Skip to content

Commit

Permalink
Docker provider: catch container name when using podman.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
jackorp committed Feb 12, 2020
1 parent 5cc06bd commit a170709
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 5 deletions.
30 changes: 25 additions & 5 deletions plugins/providers/docker/driver.rb
Expand Up @@ -26,11 +26,21 @@ def build(dir, **opts, &block)
result = execute('docker', 'build', *args, opts, &block)
matches = result.match(/Successfully built (?<id>.+)$/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 .+:(?<id>[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 .+:(?<id>[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.
Expand All @@ -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)
Expand Down
27 changes: 27 additions & 0 deletions test/unit/plugins/providers/docker/driver_test.rb
Expand Up @@ -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
Expand All @@ -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
Expand Down

0 comments on commit a170709

Please sign in to comment.