From a170709aa7b62ddd48964c205f70099880230d70 Mon Sep 17 00:00:00 2001 From: Jaroslav Prokop Date: Fri, 31 Jan 2020 13:41:37 +0100 Subject: [PATCH] Docker provider: catch container name when using podman. When user is using podman's docker CLI emulation the containers would fail to enter running state because the docker driver could not catch the container name. This commit fixes that by adding a check if podman docker emulation is used and pick the container hash correctly from the output. --- plugins/providers/docker/driver.rb | 30 +++++++++++++++---- .../plugins/providers/docker/driver_test.rb | 27 +++++++++++++++++ 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/plugins/providers/docker/driver.rb b/plugins/providers/docker/driver.rb index 8932c74a2f8..0f111a14424 100644 --- a/plugins/providers/docker/driver.rb +++ b/plugins/providers/docker/driver.rb @@ -26,11 +26,21 @@ def build(dir, **opts, &block) result = execute('docker', 'build', *args, opts, &block) matches = result.match(/Successfully built (?.+)$/i) if !matches - # Check for the new output format 'writing image sha256...' - # In this case, docker builtkit is enabled. Its format is different - # from standard docker - @logger.warn("Could not determine docker container ID. Scanning for buildkit output instead") - matches = result.match(/writing image .+:(?[0-9a-z]+) done/i) + if podman? + # Check for podman format when it is emulating docker CLI. + # Podman outputs the full hash of the container on + # the last line after a successful build. + @logger.warn("Could not find docker container ID. Scanning for podman output instead") + match = result.split.select { |str| str.match?(/[0-9a-z]{64}/) }.last + return match[0..7] unless match.nil? + else + # Check for the new output format 'writing image sha256...' + # In this case, docker builtkit is enabled. Its format is different + # from standard docker + @logger.warn("Could not determine docker container ID. Scanning for buildkit output instead") + matches = result.match(/writing image .+:(?[0-9a-z]+) done/i) + end + if !matches # This will cause a stack trace in Vagrant, but it is a bug # if this happens anyways. @@ -42,6 +52,16 @@ def build(dir, **opts, &block) matches[:id] end + # Check if podman emulating docker CLI is enabled. + # + # @return [Bool] + def podman? + execute('docker', '-v') + .scan(/podman/) + .any? + end + + def create(params, **opts, &block) image = params.fetch(:image) links = params.fetch(:links) diff --git a/test/unit/plugins/providers/docker/driver_test.rb b/test/unit/plugins/providers/docker/driver_test.rb index 7ae6524ef0c..59c8a3b92ab 100644 --- a/test/unit/plugins/providers/docker/driver_test.rb +++ b/test/unit/plugins/providers/docker/driver_test.rb @@ -155,6 +155,7 @@ describe '#build' do let(:result) { "Successfully built 1a2b3c4d" } let(:buildkit_result) { "writing image sha256:1a2b3c4d done" } + let(:podman_result) { "1a2b3c4d5e6f7g8h9i10j11k12l13m14n16o17p18q19r20s21t22u23v24w25x2" } let(:cid) { "1a2b3c4d" } it "builds a container with standard docker" do @@ -172,6 +173,32 @@ expect(container_id).to eq(cid) end + + it "builds a container with podman emulating docker CLI" do + allow(subject).to receive(:execute).and_return(podman_result) + allow(subject).to receive(:podman?).and_return(true) + + container_id = subject.build("/tmp/fakedir") + + expect(container_id).to eq(cid) + end + end + + describe '#podman?' do + let(:emulating_docker_output) { "podman version 1.7.1-dev" } + let(:real_docker_output) { "Docker version 1.8.1, build d12ea79" } + + it 'returns false when docker is used' do + allow(subject).to receive(:execute).and_return(real_docker_output) + + expect(subject.podman?).to be false + end + + it 'returns true when podman is used' do + allow(subject).to receive(:execute).and_return(emulating_docker_output) + + expect(subject.podman?).to be true + end end describe '#create' do