Skip to content

Fixed docker facts to check for active swarm clusters before running docker swarm sub-commands. #817

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
May 31, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 26 additions & 4 deletions lib/facter/docker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,20 @@ def interfaces
Facter.add(:docker_worker_join_token) do
setcode do
if Facter::Core::Execution.which('docker')
val = Facter::Core::Execution.execute(
"#{docker_command} swarm join-token worker -q", timeout: 90
# only run `docker swarm` commands if this node is in active in a cluster
docker_json_str = Facter::Core::Execution.execute(
"#{docker_command} info --format '{{json .}}'", timeout: 90
)
begin
docker = JSON.parse(docker_json_str)
if docker.fetch('Swarm', {})['LocalNodeState'] == 'active'
val = Facter::Core::Execution.execute(
"#{docker_command} swarm join-token worker -q", timeout: 90
)
end
rescue JSON::ParserError
nil
end
end
val
end
Expand All @@ -91,9 +102,20 @@ def interfaces
Facter.add(:docker_manager_join_token) do
setcode do
if Facter::Core::Execution.which('docker')
val = Facter::Core::Execution.execute(
"#{docker_command} swarm join-token manager -q", timeout: 90
# only run `docker swarm` commands if this node is in active in a cluster
docker_json_str = Facter::Core::Execution.execute(
"#{docker_command} info --format '{{json .}}'", timeout: 90
)
begin
docker = JSON.parse(docker_json_str)
if docker.fetch('Swarm', {})['LocalNodeState'] == 'active'
val = Facter::Core::Execution.execute(
"#{docker_command} swarm join-token manager -q", timeout: 90
)
end
rescue JSON::ParserError
nil
end
end
val
end
Expand Down
2 changes: 1 addition & 1 deletion spec/fixtures/facts/docker_info
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@
},
"ControlAvailable": false,
"Error": "",
"LocalNodeState": "inactive",
"LocalNodeState": "active",
"Managers": 0,
"NodeAddr": "",
"NodeID": "",
Expand Down
143 changes: 143 additions & 0 deletions spec/fixtures/facts/docker_info_swarm_inactive
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
{
"Architecture": "x86_64",
"BridgeNfIp6tables": true,
"BridgeNfIptables": true,
"CPUSet": true,
"CPUShares": true,
"CgroupDriver": "cgroupfs",
"ClusterAdvertise": "",
"ClusterStore": "",
"ContainerdCommit": {
"Expected": "4ab9917febca54791c5f071a9d1f404867857fcc",
"ID": "4ab9917febca54791c5f071a9d1f404867857fcc"
},
"Containers": 46,
"ContainersPaused": 0,
"ContainersRunning": 5,
"ContainersStopped": 41,
"CpuCfsPeriod": true,
"CpuCfsQuota": true,
"Debug": false,
"DefaultRuntime": "runc",
"DockerRootDir": "/var/lib/docker",
"Driver": "aufs",
"DriverStatus": [
[
"Root Dir",
"/var/lib/docker/aufs"
],
[
"Backing Filesystem",
"extfs"
],
[
"Dirs",
"408"
],
[
"Dirperm1 Supported",
"false"
]
],
"ExperimentalBuild": false,
"HttpProxy": "",
"HttpsProxy": "",
"ID": "VYL2:ZOEC:PG3V:3UFK:EXBT:FR3X:6IY4:ELX4:EQ5B:35C7:6OPZ:EQC6",
"IPv4Forwarding": true,
"Images": 50,
"IndexServerAddress": "https://index.docker.io/v1/",
"InitBinary": "docker-init",
"InitCommit": {
"Expected": "949e6fa",
"ID": "949e6fa"
},
"Isolation": "",
"KernelMemory": true,
"KernelVersion": "3.13.0-115-generic",
"Labels": null,
"LiveRestoreEnabled": false,
"LoggingDriver": "json-file",
"MemTotal": 1977839616,
"MemoryLimit": true,
"NCPU": 2,
"NEventsListener": 0,
"NFd": 52,
"NGoroutines": 50,
"Name": "docker00",
"NoProxy": "",
"OSType": "linux",
"OomKillDisable": true,
"OperatingSystem": "Ubuntu 14.04.5 LTS",
"Plugins": {
"Authorization": null,
"Network": [
"bridge",
"host",
"macvlan",
"null",
"overlay"
],
"Volume": [
"local"
]
},
"RegistryConfig": {
"IndexConfigs": {
"docker.io": {
"Mirrors": null,
"Name": "docker.io",
"Official": true,
"Secure": true
}
},
"InsecureRegistryCIDRs": [
"127.0.0.0/8"
],
"Mirrors": []
},
"RuncCommit": {
"Expected": "54296cf40ad8143b62dbcaa1d90e520a2136ddfe",
"ID": "54296cf40ad8143b62dbcaa1d90e520a2136ddfe"
},
"Runtimes": {
"runc": {
"path": "docker-runc"
}
},
"SecurityOptions": [
"name=apparmor"
],
"ServerVersion": "17.03.1-ce",
"SwapLimit": false,
"Swarm": {
"Cluster": {
"CreatedAt": "0001-01-01T00:00:00Z",
"ID": "",
"Spec": {
"CAConfig": {},
"Dispatcher": {},
"EncryptionConfig": {
"AutoLockManagers": false
},
"Orchestration": {},
"Raft": {
"ElectionTick": 0,
"HeartbeatTick": 0
},
"TaskDefaults": {}
},
"UpdatedAt": "0001-01-01T00:00:00Z",
"Version": {}
},
"ControlAvailable": false,
"Error": "",
"LocalNodeState": "inactive",
"Managers": 0,
"NodeAddr": "",
"NodeID": "",
"Nodes": 0,
"RemoteManagers": null
},
"SystemStatus": null,
"SystemTime": "2017-04-11T01:12:52.292117616-04:00"
}
37 changes: 29 additions & 8 deletions spec/unit/lib/facter/docker_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,34 +10,34 @@
allow(Facter::Core::Execution).to receive(:execute).and_call_original

if Facter.value(:kernel) == 'windows'
docker_command = 'powershell -NoProfile -NonInteractive -NoLogo -ExecutionPolicy Bypass -c docker'
@docker_command = 'powershell -NoProfile -NonInteractive -NoLogo -ExecutionPolicy Bypass -c docker'
allow(Facter::Core::Execution).to receive(:which).with('dhcpcd').and_return('C:\Windows\dhcpd.exe')
allow(Facter::Core::Execution).to receive(:which).with('route').and_return('C:\Windows\System32\ROUTE.EXE')
allow(Facter::Core::Execution).to receive(:which).with('docker').and_return('C:\Program Files\Docker\docker.exe')
else
docker_command = 'docker'
@docker_command = 'docker'
allow(Facter::Core::Execution).to receive(:which).with('route').and_return('/usr/bin/route')
allow(Facter::Core::Execution).to receive(:which).with('dhcpcd').and_return('/usr/bin/dhcpd')
allow(Facter::Core::Execution).to receive(:which).with('docker').and_return('/usr/bin/docker')
end
docker_info = File.read(fixtures('facts', 'docker_info'))
allow(Facter::Core::Execution).to receive(:execute).with("#{docker_command} info --format '{{json .}}'", timeout: 90).and_return(docker_info)
allow(Facter::Core::Execution).to receive(:execute).with("#{@docker_command} info --format '{{json .}}'", timeout: 90).and_return(docker_info)
processors = File.read(fixtures('facts', 'processors'))
allow(Facter.fact(:processors)).to receive(:value).and_return(JSON.parse(processors))
docker_version = File.read(fixtures('facts', 'docker_version'))
allow(Facter::Core::Execution).to receive(:execute).with("#{docker_command} version --format '{{json .}}'", timeout: 90).and_return(docker_version)
allow(Facter::Core::Execution).to receive(:execute).with("#{@docker_command} version --format '{{json .}}'", timeout: 90).and_return(docker_version)
docker_network_list = File.read(fixtures('facts', 'docker_network_list'))
allow(Facter::Core::Execution).to receive(:execute).with("#{docker_command} network ls | tail -n +2", timeout: 90).and_return(docker_network_list)
allow(Facter::Core::Execution).to receive(:execute).with("#{@docker_command} network ls | tail -n +2", timeout: 90).and_return(docker_network_list)
docker_network_names = []
docker_network_list.each_line { |line| docker_network_names.push line.split[1] }
docker_network_names.each do |network|
inspect = File.read(fixtures('facts', "docker_network_inspect_#{network}"))
allow(Facter::Core::Execution).to receive(:execute).with("#{docker_command} network inspect #{network}", timeout: 90).and_return(inspect)
allow(Facter::Core::Execution).to receive(:execute).with("#{@docker_command} network inspect #{network}", timeout: 90).and_return(inspect)
end
docker_worker_token = File.read(fixtures('facts', 'docker_swarm_worker_token'))
allow(Facter::Core::Execution).to receive(:execute).with("#{docker_command} swarm join-token worker -q", timeout: 90).and_return(docker_worker_token.chomp)
allow(Facter::Core::Execution).to receive(:execute).with("#{@docker_command} swarm join-token worker -q", timeout: 90).and_return(docker_worker_token.chomp)
docker_manager_token = File.read(fixtures('facts', 'docker_swarm_manager_token'))
allow(Facter::Core::Execution).to receive(:execute).with("#{docker_command} swarm join-token manager -q", timeout: 90).and_return(docker_manager_token.chomp)
allow(Facter::Core::Execution).to receive(:execute).with("#{@docker_command} swarm join-token manager -q", timeout: 90).and_return(docker_manager_token.chomp)
end
after(:each) { Facter.clear }

Expand Down Expand Up @@ -129,4 +129,25 @@
)
end
end

describe 'docker swarm worker join-token with inactive swarm cluster' do
before :each do
docker_info = File.read(fixtures('facts', 'docker_info_swarm_inactive'))
allow(Facter::Core::Execution).to receive(:execute).with("#{@docker_command} info --format '{{json .}}'", timeout: 90).and_return(docker_info)
end
it do
expect(Facter.fact(:docker_worker_join_token).value).to be_nil
end
end

describe 'docker swarm manager join-token with inactive swarm cluster' do
before :each do
docker_info = File.read(fixtures('facts', 'docker_info_swarm_inactive'))
allow(Facter::Core::Execution).to receive(:execute).with("#{@docker_command} info --format '{{json .}}'", timeout: 90).and_return(docker_info)
end

it do
expect(Facter.fact(:docker_manager_join_token).value).to be_nil
end
end
end