Don't rely on `/sbin/ip` to fetch the docker bridge ip address, instead first attempt to use the docker command to fetch it. If it fails, fall back to previous behavior.
754 lines
23 KiB
Ruby
754 lines
23 KiB
Ruby
require_relative "../../../base"
|
|
|
|
require Vagrant.source_root.join("plugins/providers/docker/driver")
|
|
|
|
describe VagrantPlugins::DockerProvider::Driver do
|
|
let(:cmd_executed) { @cmd }
|
|
let(:cid) { 'side-1-song-10' }
|
|
let(:execute_result) {
|
|
double("execute_result",
|
|
exit_code: exit_code,
|
|
stderr: stderr,
|
|
stdout: stdout
|
|
)
|
|
}
|
|
let(:exit_code) { 0 }
|
|
let(:stderr) { "" }
|
|
let(:stdout) { "" }
|
|
|
|
before do
|
|
allow(Vagrant::Util::Subprocess).to receive(:execute) { |*args|
|
|
if args.last.is_a?(Hash)
|
|
args = args[0, args.size - 1]
|
|
end
|
|
invalid = args.detect { |a| !a.is_a?(String) }
|
|
if invalid
|
|
raise TypeError,
|
|
"Vagrant::Util::Subprocess#execute only accepts signle option Hash and String arguments, received `#{invalid.class}'"
|
|
end
|
|
@cmd = args.join(" ")
|
|
}.and_return(execute_result)
|
|
allow_any_instance_of(Vagrant::Errors::VagrantError).
|
|
to receive(:translate_error) { |*args| args.join(" ") }
|
|
end
|
|
|
|
let(:docker_network_struct) {
|
|
[
|
|
{
|
|
"Name": "bridge",
|
|
"Id": "ae74f6cc18bbcde86326937797070b814cc71bfc4a6d8e3e8cf3b2cc5c7f4a7d",
|
|
"Created": "2019-03-20T14:10:06.313314662-07:00",
|
|
"Scope": "local",
|
|
"Driver": "bridge",
|
|
"EnableIPv6": false,
|
|
"IPAM": {
|
|
"Driver": "default",
|
|
"Options": nil,
|
|
"Config": [
|
|
{
|
|
"Subnet": "172.17.0.0/16",
|
|
"Gateway": "172.17.0.1"
|
|
}
|
|
]
|
|
},
|
|
"Internal": false,
|
|
"Attachable": false,
|
|
"Ingress": false,
|
|
"ConfigFrom": {
|
|
"Network": ""
|
|
},
|
|
"ConfigOnly": false,
|
|
"Containers": {
|
|
"a1ee9b12bcea8268495b1f43e8d1285df1925b7174a695075f6140adb9415d87": {
|
|
"Name": "vagrant-sandbox_docker-1_1553116237",
|
|
"EndpointID": "fc1b0ed6e4f700cf88bb26a98a0722655191542e90df3e3492461f4d1f3c0cae",
|
|
"MacAddress": "02:42:ac:11:00:02",
|
|
"IPv4Address": "172.17.0.2/16",
|
|
"IPv6Address": ""
|
|
}
|
|
},
|
|
"Options": {
|
|
"com.docker.network.bridge.default_bridge": "true",
|
|
"com.docker.network.bridge.enable_icc": "true",
|
|
"com.docker.network.bridge.enable_ip_masquerade": "true",
|
|
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
|
|
"com.docker.network.bridge.name": "docker0",
|
|
"com.docker.network.driver.mtu": "1500"
|
|
},
|
|
"Labels": {}
|
|
},
|
|
{
|
|
"Name": "host",
|
|
"Id": "2a2845e77550e33bf3e97bda8b71477ac7d3ccf78bc9102585fdb6056fb84cbf",
|
|
"Created": "2018-09-28T10:54:08.633543196-07:00",
|
|
"Scope": "local",
|
|
"Driver": "host",
|
|
"EnableIPv6": false,
|
|
"IPAM": {
|
|
"Driver": "default",
|
|
"Options": nil,
|
|
"Config": []
|
|
},
|
|
"Internal": false,
|
|
"Attachable": false,
|
|
"Ingress": false,
|
|
"ConfigFrom": {
|
|
"Network": ""
|
|
},
|
|
"ConfigOnly": false,
|
|
"Containers": {},
|
|
"Options": {},
|
|
"Labels": {}
|
|
},
|
|
{
|
|
"Name": "vagrant_network",
|
|
"Id": "93385d4fd3cf7083a36e62fa72a0ad0a21203d0ddf48409c32b550cd8462b3ba",
|
|
"Created": "2019-03-20T14:10:36.828235585-07:00",
|
|
"Scope": "local",
|
|
"Driver": "bridge",
|
|
"EnableIPv6": false,
|
|
"IPAM": {
|
|
"Driver": "default",
|
|
"Options": {},
|
|
"Config": [
|
|
{
|
|
"Subnet": "172.18.0.0/16",
|
|
"Gateway": "172.18.0.1"
|
|
}
|
|
]
|
|
},
|
|
"Internal": false,
|
|
"Attachable": false,
|
|
"Ingress": false,
|
|
"ConfigFrom": {
|
|
"Network": ""
|
|
},
|
|
"ConfigOnly": false,
|
|
"Containers": {
|
|
"a1ee9b12bcea8268495b1f43e8d1285df1925b7174a695075f6140adb9415d87": {
|
|
"Name": "vagrant-sandbox_docker-1_1553116237",
|
|
"EndpointID": "9502cd9d37ae6815e3ffeb0bc2de9b84f79e7223e8a1f8f4ccc79459e96c7914",
|
|
"MacAddress": "02:42:ac:12:00:02",
|
|
"IPv4Address": "172.18.0.2/16",
|
|
"IPv6Address": ""
|
|
}
|
|
},
|
|
"Options": {},
|
|
"Labels": {}
|
|
},
|
|
{
|
|
"Name": "vagrant_network_172.20.0.0/16",
|
|
"Id": "649f0ab3ef0eef6f2a025c0d0398bd7b9b4d05ec88b0d7bd573b44153d903cfb",
|
|
"Created": "2019-03-20T14:10:37.088885647-07:00",
|
|
"Scope": "local",
|
|
"Driver": "bridge",
|
|
"EnableIPv6": false,
|
|
"IPAM": {
|
|
"Driver": "default",
|
|
"Options": {},
|
|
"Config": [
|
|
{
|
|
"Subnet": "172.20.0.0/16"
|
|
}
|
|
]
|
|
},
|
|
"Internal": false,
|
|
"Attachable": false,
|
|
"Ingress": false,
|
|
"ConfigFrom": {
|
|
"Network": ""
|
|
},
|
|
"ConfigOnly": false,
|
|
"Containers": {
|
|
"a1ee9b12bcea8268495b1f43e8d1285df1925b7174a695075f6140adb9415d87": {
|
|
"Name": "vagrant-sandbox_docker-1_1553116237",
|
|
"EndpointID": "e19156f8018f283468227fa97c145f4ea0eaba652fb7e977a0c759b1c3ec168a",
|
|
"MacAddress": "02:42:ac:14:80:02",
|
|
"IPv4Address": "172.20.0.2/16",
|
|
"IPv6Address": ""
|
|
}
|
|
},
|
|
"Options": {},
|
|
"Labels": {}
|
|
}
|
|
].to_json }
|
|
|
|
|
|
describe '#build' do
|
|
let(:stdout) { "Successfully built other_package\nSuccessfully built 1a2b3c4d" }
|
|
let(:cid) { "1a2b3c4d" }
|
|
|
|
it "builds a container with standard docker" do
|
|
container_id = subject.build("/tmp/fakedir")
|
|
|
|
expect(container_id).to eq(cid)
|
|
end
|
|
|
|
context "using buildkit" do
|
|
let(:stdout) { "writing image sha256:1a2b3c4d 0.0s done" }
|
|
|
|
it "builds a container with buildkit docker" do
|
|
container_id = subject.build("/tmp/fakedir")
|
|
|
|
expect(container_id).to eq(cid)
|
|
end
|
|
end
|
|
|
|
context "using buildkit with old output" do
|
|
let(:stdout) { "writing image sha256:1a2b3c4d done" }
|
|
|
|
it "builds a container with buildkit docker (old output)" do
|
|
container_id = subject.build("/tmp/fakedir")
|
|
|
|
expect(container_id).to eq(cid)
|
|
end
|
|
end
|
|
|
|
context "using podman emulating docker CLI" do
|
|
let(:stdout) { "1a2b3c4d5e6f7g8h9i10j11k12l13m14n16o17p18q19r20s21t22u23v24w25x2" }
|
|
|
|
it "builds a container with podman emulating docker CLI" do
|
|
allow(subject).to receive(:podman?).and_return(true)
|
|
|
|
container_id = subject.build("/tmp/fakedir")
|
|
|
|
expect(container_id).to eq(cid)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '#podman?' do
|
|
context "when docker is used" do
|
|
let(:stdout) { "Docker version 1.8.1, build d12ea79" }
|
|
|
|
it 'returns false' do
|
|
expect(subject.podman?).to be false
|
|
end
|
|
end
|
|
context "when podman is used" do
|
|
let(:stdout) { "podman version 1.7.1-dev" }
|
|
|
|
it 'returns true' do
|
|
expect(subject.podman?).to be true
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '#create' do
|
|
let(:params) { {
|
|
image: 'jimi/hendrix:electric-ladyland',
|
|
cmd: ['play', 'voodoo-chile'],
|
|
ports: '8080:80',
|
|
volumes: '/host/path:guest/path',
|
|
detach: true,
|
|
links: [[:janis, 'joplin'], [:janis, 'janis']],
|
|
env: {key: 'value'},
|
|
name: cid,
|
|
hostname: 'jimi-hendrix',
|
|
privileged: true
|
|
} }
|
|
|
|
before { subject.create(params) }
|
|
|
|
it 'runs a detached docker image' do
|
|
expect(cmd_executed).to match(/^docker run .+ -d .+ #{Regexp.escape params[:image]}/)
|
|
end
|
|
|
|
it 'sets container name' do
|
|
expect(cmd_executed).to match(/--name #{Regexp.escape params[:name]}/)
|
|
end
|
|
|
|
it 'forwards ports' do
|
|
expect(cmd_executed).to match(/-p #{params[:ports]} .+ #{Regexp.escape params[:image]}/)
|
|
end
|
|
|
|
it 'shares folders' do
|
|
expect(cmd_executed).to match(/-v #{params[:volumes]} .+ #{Regexp.escape params[:image]}/)
|
|
end
|
|
|
|
it 'links containers' do
|
|
params[:links].each do |link|
|
|
expect(cmd_executed).to match(/--link #{link.join(':')} .+ #{Regexp.escape params[:image]}/)
|
|
end
|
|
end
|
|
|
|
it 'sets environmental variables' do
|
|
expect(cmd_executed).to match(/-e key=value .+ #{Regexp.escape params[:image]}/)
|
|
end
|
|
|
|
it 'is able to run a privileged container' do
|
|
expect(cmd_executed).to match(/--privileged .+ #{Regexp.escape params[:image]}/)
|
|
end
|
|
|
|
it 'sets the hostname if specified' do
|
|
expect(cmd_executed).to match(/-h #{params[:hostname]} #{Regexp.escape params[:image]}/)
|
|
end
|
|
|
|
it 'executes the provided command' do
|
|
expect(cmd_executed).to match(/#{Regexp.escape params[:image]} #{Regexp.escape params[:cmd].join(' ')}/)
|
|
end
|
|
end
|
|
|
|
describe '#create windows' do
|
|
let(:params) { {
|
|
image: 'jimi/hendrix:eletric-ladyland',
|
|
cmd: ['play', 'voodoo-chile'],
|
|
ports: '8080:80',
|
|
volumes: 'C:/Users/BobDylan/AllAlong:/The/Watchtower',
|
|
detach: true,
|
|
links: [[:janis, 'joplin'], [:janis, 'janis']],
|
|
env: {key: 'value'},
|
|
name: cid,
|
|
hostname: 'jimi-hendrix',
|
|
privileged: true
|
|
} }
|
|
|
|
let(:translated_path) { "//c/Users/BobDylan/AllAlong:/The/Watchtower" }
|
|
|
|
before do
|
|
allow(Vagrant::Util::Platform).to receive(:windows?).and_return(true)
|
|
subject.create(params)
|
|
end
|
|
|
|
it 'shares folders' do
|
|
expect(cmd_executed).to match(/-v #{translated_path} .+ #{Regexp.escape params[:image]}/)
|
|
end
|
|
end
|
|
|
|
|
|
describe '#created?' do
|
|
let(:result) { subject.created?(cid) }
|
|
|
|
it 'performs the check on all containers list' do
|
|
subject.created?(cid)
|
|
expect(cmd_executed).to match(/docker ps \-a \-q/)
|
|
end
|
|
|
|
context 'when container exists' do
|
|
let(:stdout) { "foo\n#{cid}\nbar" }
|
|
|
|
it { expect(result).to be_truthy }
|
|
end
|
|
|
|
context 'when container does not exist' do
|
|
let(:stdout) { "foo\n#{cid}extra\nbar" }
|
|
|
|
it { expect(result).to be_falsey }
|
|
end
|
|
end
|
|
|
|
describe '#pull' do
|
|
it 'should pull images' do
|
|
subject.pull('foo')
|
|
expect(cmd_executed).to match(/docker pull foo/)
|
|
end
|
|
end
|
|
|
|
describe '#read_used_ports' do
|
|
let(:all_containers) { ["container1\ncontainer2"] }
|
|
let(:container_info) { {"Name"=>"/container", "State"=>{"Running"=>true}, "HostConfig"=>{"PortBindings"=>{}}} }
|
|
let(:empty_used_ports) { {} }
|
|
|
|
context "with existing port forwards" do
|
|
let(:container_info) { {"Name"=>"/container","State"=>{"Running"=>true}, "HostConfig"=>{"PortBindings"=>{"22/tcp"=>[{"HostIp"=>"127.0.0.1","HostPort"=>"2222"}] }}} }
|
|
let(:used_ports_set) { {"2222"=>Set["127.0.0.1"]} }
|
|
|
|
context "with active containers" do
|
|
it 'should read all port bindings and return a hash of sets' do
|
|
allow(subject).to receive(:all_containers).and_return(all_containers)
|
|
allow(subject).to receive(:inspect_container).and_return(container_info)
|
|
|
|
used_ports = subject.read_used_ports
|
|
expect(used_ports).to eq(used_ports_set)
|
|
end
|
|
end
|
|
|
|
context "with inactive containers" do
|
|
let(:container_info) { {"Name"=>"/container", "State"=>{"Running"=>false}, "HostConfig"=>{"PortBindings"=>{"22/tcp"=>[{"HostIp"=>"127.0.0.1","HostPort"=>"2222"}] }}} }
|
|
|
|
it 'returns empty' do
|
|
allow(subject).to receive(:all_containers).and_return(all_containers)
|
|
allow(subject).to receive(:inspect_container).and_return(container_info)
|
|
|
|
used_ports = subject.read_used_ports
|
|
expect(used_ports).to eq(empty_used_ports)
|
|
end
|
|
end
|
|
end
|
|
|
|
it 'returns empty if no ports are already bound' do
|
|
allow(subject).to receive(:all_containers).and_return(all_containers)
|
|
allow(subject).to receive(:inspect_container).and_return(container_info)
|
|
|
|
used_ports = subject.read_used_ports
|
|
expect(used_ports).to eq(empty_used_ports)
|
|
end
|
|
end
|
|
|
|
describe '#running?' do
|
|
let(:result) { subject.running?(cid) }
|
|
|
|
it 'performs the check on the running containers list' do
|
|
subject.running?(cid)
|
|
expect(cmd_executed).to match(/docker ps \-q/)
|
|
expect(cmd_executed).to_not include('-a')
|
|
end
|
|
|
|
context 'when container exists' do
|
|
let(:stdout) { "foo\n#{cid}\nbar" }
|
|
it { expect(result).to be_truthy }
|
|
end
|
|
|
|
context 'when container does not exist' do
|
|
let(:stdout) { "foo\n#{cid}extra\nbar" }
|
|
it { expect(result).to be_falsey }
|
|
end
|
|
end
|
|
|
|
describe '#privileged?' do
|
|
it 'identifies privileged containers' do
|
|
allow(subject).to receive(:inspect_container).and_return({'HostConfig' => {"Privileged" => true}})
|
|
expect(subject).to be_privileged(cid)
|
|
end
|
|
|
|
it 'identifies unprivileged containers' do
|
|
allow(subject).to receive(:inspect_container).and_return({'HostConfig' => {"Privileged" => false}})
|
|
expect(subject).to_not be_privileged(cid)
|
|
end
|
|
end
|
|
|
|
describe '#start' do
|
|
context 'when container is running' do
|
|
before { allow(subject).to receive(:running?).and_return(true) }
|
|
|
|
it 'does not start the container' do
|
|
subject.start(cid)
|
|
expect(cmd_executed).to be_nil
|
|
end
|
|
end
|
|
|
|
context 'when container is not running' do
|
|
before { allow(subject).to receive(:running?).and_return(false) }
|
|
|
|
it 'starts the container' do
|
|
subject.start(cid)
|
|
expect(cmd_executed).to eq("docker start #{cid}")
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '#stop' do
|
|
context 'when container is running' do
|
|
before { allow(subject).to receive(:running?).and_return(true) }
|
|
|
|
it 'stops the container' do
|
|
subject.stop(cid, 1)
|
|
expect(cmd_executed).to eq("docker stop -t 1 #{cid}")
|
|
end
|
|
|
|
it "stops the container with the set timeout" do
|
|
subject.stop(cid, 5)
|
|
expect(cmd_executed).to eq("docker stop -t 5 #{cid}")
|
|
end
|
|
end
|
|
|
|
context 'when container is not running' do
|
|
before { allow(subject).to receive(:running?).and_return(false) }
|
|
|
|
it 'does not stop container' do
|
|
subject.stop(cid, 1)
|
|
expect(cmd_executed).to be_nil
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '#rm' do
|
|
context 'when container has been created' do
|
|
before { allow(subject).to receive(:created?).and_return(true) }
|
|
|
|
it 'removes the container' do
|
|
subject.rm(cid)
|
|
expect(cmd_executed).to eq("docker rm -f -v #{cid}")
|
|
end
|
|
end
|
|
|
|
context 'when container has not been created' do
|
|
before { allow(subject).to receive(:created?).and_return(false) }
|
|
|
|
it 'does not attempt to remove the container' do
|
|
subject.rm(cid)
|
|
expect(cmd_executed).to be_nil
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '#rmi' do
|
|
let(:id) { 'asdg21ew' }
|
|
|
|
context 'image exists' do
|
|
it "removes the image" do
|
|
subject.rmi(id)
|
|
expect(cmd_executed).to eq("docker rmi #{id}")
|
|
end
|
|
end
|
|
|
|
context 'image is being used by running container' do
|
|
before { allow(subject).to receive(:execute).and_raise("image is being used by running container") }
|
|
|
|
it 'does not remove the image' do
|
|
expect(subject.rmi(id)).to eq(false)
|
|
subject.rmi(id)
|
|
end
|
|
end
|
|
|
|
context 'image is being used by stopped container' do
|
|
before { allow(subject).to receive(:execute).and_raise("image is being used by stopped container") }
|
|
|
|
it 'does not remove the image' do
|
|
expect(subject.rmi(id)).to eq(false)
|
|
subject.rmi(id)
|
|
end
|
|
end
|
|
|
|
context 'container is using it' do
|
|
before { allow(subject).to receive(:execute).and_raise("container is using it") }
|
|
|
|
it 'does not remove the image' do
|
|
expect(subject.rmi(id)).to eq(false)
|
|
subject.rmi(id)
|
|
end
|
|
end
|
|
|
|
context 'image does not exist' do
|
|
before { allow(subject).to receive(:execute).and_raise("No such image") }
|
|
|
|
it 'raises an error' do
|
|
expect(subject.rmi(id)).to eq(nil)
|
|
subject.rmi(id)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '#inspect_container' do
|
|
let(:stdout) { '[{"json": "value"}]' }
|
|
|
|
it 'inspects the container' do
|
|
subject.inspect_container(cid)
|
|
expect(cmd_executed).to eq("docker inspect #{cid}")
|
|
end
|
|
|
|
it 'parses the json output' do
|
|
expect(subject.inspect_container(cid)).to eq('json' => 'value')
|
|
end
|
|
end
|
|
|
|
describe '#all_containers' do
|
|
let(:stdout) { "container1\ncontainer2" }
|
|
|
|
it 'returns an array of all known containers' do
|
|
expect(subject.all_containers).to eq(['container1', 'container2'])
|
|
expect(cmd_executed).to eq("docker ps -a -q --no-trunc")
|
|
end
|
|
end
|
|
|
|
describe '#docker_bridge_ip' do
|
|
context 'from docker network command' do
|
|
let(:network_struct) {
|
|
[{
|
|
"Name": "bridge",
|
|
"Id": "ae74f6cc18bbcde86326937797070b814cc71bfc4a6d8e3e8cf3b2cc5c7f4a7d",
|
|
"Created": "2019-03-20T14:10:06.313314662-07:00",
|
|
"Scope": "local",
|
|
"Driver": "bridge",
|
|
"EnableIPv6": false,
|
|
"IPAM": {
|
|
"Driver": "default",
|
|
"Options": nil,
|
|
"Config": [
|
|
{
|
|
"Subnet": "172.17.0.0/16",
|
|
"Gateway": "172.17.0.1"
|
|
}
|
|
]
|
|
},
|
|
"Internal": false,
|
|
"Attachable": false,
|
|
"Ingress": false,
|
|
"ConfigFrom": {
|
|
"Network": ""
|
|
},
|
|
"ConfigOnly": false,
|
|
"Containers": {
|
|
"a1ee9b12bcea8268495b1f43e8d1285df1925b7174a695075f6140adb9415d87": {
|
|
"Name": "vagrant-sandbox_docker-1_1553116237",
|
|
"EndpointID": "fc1b0ed6e4f700cf88bb26a98a0722655191542e90df3e3492461f4d1f3c0cae",
|
|
"MacAddress": "02:42:ac:11:00:02",
|
|
"IPv4Address": "172.17.0.2/16",
|
|
"IPv6Address": ""
|
|
}
|
|
},
|
|
"Options": {
|
|
"com.docker.network.bridge.default_bridge": "true",
|
|
"com.docker.network.bridge.enable_icc": "true",
|
|
"com.docker.network.bridge.enable_ip_masquerade": "true",
|
|
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
|
|
"com.docker.network.bridge.name": "docker0",
|
|
"com.docker.network.driver.mtu": "1500"
|
|
},
|
|
"Labels": {}
|
|
}].to_json
|
|
}
|
|
it "returns the bridge gateway ip" do
|
|
allow(subject).to receive(:inspect_network).and_return(JSON.load(network_struct))
|
|
expect(subject.docker_bridge_ip).to eq('172.17.0.1')
|
|
end
|
|
end
|
|
|
|
context 'when falling back to ip' do
|
|
let(:stdout) { " inet 123.456.789.012/16 " }
|
|
|
|
it 'returns the bridge ip' do
|
|
expect(subject.docker_bridge_ip).to eq('123.456.789.012')
|
|
expect(cmd_executed).to eq("ip -4 addr show scope global docker0")
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '#docker_connect_network' do
|
|
let(:opts) { ["--ip", "172.20.128.2"] }
|
|
|
|
it 'connects a network to a container' do
|
|
subject.connect_network("vagrant_network", cid, opts)
|
|
expect(cmd_executed).to eq("docker network connect vagrant_network #{cid} --ip 172.20.128.2")
|
|
end
|
|
end
|
|
|
|
describe '#docker_create_network' do
|
|
let(:opts) { ["--subnet", "172.20.0.0/16"] }
|
|
|
|
it 'creates a network' do
|
|
subject.create_network("vagrant_network", opts)
|
|
expect(cmd_executed).to eq("docker network create vagrant_network --subnet 172.20.0.0/16")
|
|
end
|
|
end
|
|
|
|
describe '#docker_disconnet_network' do
|
|
it 'disconnects a network from a container' do
|
|
subject.disconnect_network("vagrant_network", cid)
|
|
expect(cmd_executed).to eq("docker network disconnect vagrant_network #{cid} --force")
|
|
end
|
|
end
|
|
|
|
describe '#docker_inspect_network' do
|
|
it 'gets info about a network' do
|
|
subject.inspect_network("vagrant_network")
|
|
expect(cmd_executed).to eq("docker network inspect vagrant_network")
|
|
end
|
|
end
|
|
|
|
describe '#docker_list_network' do
|
|
it 'lists docker networks' do
|
|
subject.list_network()
|
|
expect(cmd_executed).to eq("docker network ls")
|
|
end
|
|
end
|
|
|
|
describe '#docker_rm_network' do
|
|
it 'deletes a docker network' do
|
|
subject.rm_network("vagrant_network")
|
|
expect(cmd_executed).to eq("docker network rm vagrant_network")
|
|
end
|
|
end
|
|
|
|
describe '#network_defined?' do
|
|
let(:subnet_string) { "172.20.0.0/16" }
|
|
let(:network_names) { ["vagrant_network_172.20.0.0/16", "bridge", "null" ] }
|
|
|
|
it "returns network name if defined" do
|
|
allow(subject).to receive(:list_network_names).and_return(network_names)
|
|
allow(subject).to receive(:inspect_network).and_return(JSON.load(docker_network_struct))
|
|
|
|
network_name = subject.network_defined?(subnet_string)
|
|
expect(network_name).to eq("vagrant_network_172.20.0.0/16")
|
|
end
|
|
|
|
it "returns nil name if not defined" do
|
|
allow(subject).to receive(:list_network_names).and_return(network_names)
|
|
allow(subject).to receive(:inspect_network).and_return(JSON.load(docker_network_struct))
|
|
|
|
network_name = subject.network_defined?("120.20.0.0/24")
|
|
expect(network_name).to eq(nil)
|
|
end
|
|
end
|
|
|
|
describe '#network_containing_address' do
|
|
let(:address) { "172.20.128.2" }
|
|
let(:network_names) { ["vagrant_network_172.20.0.0/16", "bridge", "null" ] }
|
|
|
|
it "returns the network name if it contains the requested address" do
|
|
allow(subject).to receive(:list_network_names).and_return(network_names)
|
|
allow(subject).to receive(:inspect_network).and_return(JSON.load(docker_network_struct))
|
|
|
|
network_name = subject.network_containing_address(address)
|
|
expect(network_name).to eq("vagrant_network_172.20.0.0/16")
|
|
end
|
|
|
|
it "returns nil if no networks contain the requested address" do
|
|
allow(subject).to receive(:list_network_names).and_return(network_names)
|
|
allow(subject).to receive(:inspect_network).and_return(JSON.load(docker_network_struct))
|
|
|
|
network_name = subject.network_containing_address("127.0.0.1")
|
|
expect(network_name).to eq(nil)
|
|
end
|
|
end
|
|
|
|
describe '#existing_named_network?' do
|
|
let(:network_names) { ["vagrant_network_172.20.0.0/16", "bridge", "null" ] }
|
|
|
|
it "returns true if the network exists" do
|
|
allow(subject).to receive(:list_network_names).and_return(network_names)
|
|
|
|
expect(subject.existing_named_network?("vagrant_network_172.20.0.0/16")).to be_truthy
|
|
end
|
|
|
|
it "returns false if the network does not exist" do
|
|
allow(subject).to receive(:list_network_names).and_return(network_names)
|
|
|
|
expect(subject.existing_named_network?("vagrant_network_17.0.0/16")).to be_falsey
|
|
end
|
|
end
|
|
|
|
describe '#list_network_names' do
|
|
let(:unparsed_network_names) { "vagrant_network_172.20.0.0/16\nbridge\nnull" }
|
|
let(:network_names) { ["vagrant_network_172.20.0.0/16", "bridge", "null" ] }
|
|
|
|
it "lists the network names" do
|
|
allow(subject).to receive(:list_network).with("--format={{.Name}}").
|
|
and_return(unparsed_network_names)
|
|
|
|
expect(subject.list_network_names).to eq(network_names)
|
|
end
|
|
end
|
|
|
|
describe '#network_used?' do
|
|
let(:network_name) { "vagrant_network_172.20.0.0/16" }
|
|
it "returns nil if no networks" do
|
|
allow(subject).to receive(:inspect_network).with(network_name).and_return(nil)
|
|
|
|
expect(subject.network_used?(network_name)).to eq(nil)
|
|
end
|
|
|
|
it "returns true if network has containers in use" do
|
|
allow(subject).to receive(:inspect_network).with(network_name).and_return([JSON.load(docker_network_struct).last])
|
|
|
|
expect(subject.network_used?(network_name)).to be_truthy
|
|
end
|
|
|
|
it "returns false if network has containers in use" do
|
|
allow(subject).to receive(:inspect_network).with("host").and_return([JSON.load(docker_network_struct)[1]])
|
|
|
|
expect(subject.network_used?("host")).to be_falsey
|
|
end
|
|
end
|
|
end
|