puppet_docker_tools 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +14 -0
- data/bin/puppet-docker +3 -0
- data/lib/puppet_docker_tools/runner.rb +20 -14
- data/lib/puppet_docker_tools/utilities.rb +17 -0
- data/spec/lib/puppet_docker_tools/runner_spec.rb +15 -5
- data/spec/lib/puppet_docker_tools/utilities_spec.rb +9 -0
- data/spec/support/examples/running_container.rb +11 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2af7f0af2ac0fb8371c5358179ff8b3d26f10157
|
4
|
+
data.tar.gz: 5c82a30a82d4dbaafbf3e8217a9c8f4b96cb4d5d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e3f350e40c4f26824845e9e06d820b3fb47d69e165602feb6a9049a3cf7a18f78514670a0f9a53dcae5d07bafc22e644173b93f2d5ec3e815c04ba7daff79c76
|
7
|
+
data.tar.gz: f8092567055f4a50bcecd27682209ff6f3374d46a39806bc6a5a86143d3c3155b9ab5c06b9db87269a109f7e7ab25a1988f7e7e5019fa56f6e0c4c269afec1bd
|
data/README.md
CHANGED
@@ -15,6 +15,7 @@ $ puppet-docker help
|
|
15
15
|
Usage:
|
16
16
|
puppet-docker build [DIRECTORY] [--dockerfile=<dockerfile>] [--repository=<repo>] [--namespace=<namespace>] [--no-cache]
|
17
17
|
puppet-docker lint [DIRECTORY] [--dockerfile=<dockerfile>]
|
18
|
+
puppet-docker local-lint [DIRECTORY] [--dockerfile=<dockerfile>]
|
18
19
|
puppet-docker pull [IMAGE] [--repository=<repo>]
|
19
20
|
puppet-docker push [DIRECTORY] [--dockerfile=<dockerfile>] [--repository=<repo>] [--namespace=<namespace>]
|
20
21
|
puppet-docker rev-labels [DIRECTORY] [--dockerfile=<dockerfile>] [--namespace=<namespace>]
|
@@ -48,6 +49,10 @@ Run [hadolint](https://github.com/hadolint/hadolint) on the dockerfile in DIRECT
|
|
48
49
|
* [DL4000](https://github.com/hadolint/hadolint/wiki/DL4000) - MAINTAINER is deprecated
|
49
50
|
* [DL4001](https://github.com/hadolint/hadolint/wiki/DL4001) - Don't use both wget and curl
|
50
51
|
|
52
|
+
### `puppet-docker local-lint`
|
53
|
+
|
54
|
+
Run [hadolint](https://github.com/hadolint/hadolint) on the dockerfile in DIRECTORY. The lint task runs using a locally installed `hadolint` executable with the same rule exclusions as `puppet-docker lint`.
|
55
|
+
|
51
56
|
### `puppet-docker pull`
|
52
57
|
|
53
58
|
Pull the specified image, i.e. 'puppet/puppetserver'. *NOTE*: If you don't include the tag you want to pull, `puppet-docker pull` will pull all tags for that image.
|
@@ -76,6 +81,15 @@ Output the `version` label for the dockerfile contained in DIRECTORY.
|
|
76
81
|
|
77
82
|
Update the base images. Any number of tags to update can be passed, or by default it will pull the latest version of: ['ubuntu:16.04', 'centos:7', 'alpine:3.4', 'debian:9', 'postgres:9.6.8']
|
78
83
|
|
84
|
+
## Items available to Dockerfiles
|
85
|
+
|
86
|
+
There are some common variables passed to builds that you can take advantage of in your Dockerfiles.
|
87
|
+
|
88
|
+
### `ARG`s
|
89
|
+
|
90
|
+
* `vcs_ref`: set to `git rev-parse HEAD`
|
91
|
+
* `build_date`: set to ruby's `Time.now.utc.iso8601`
|
92
|
+
|
79
93
|
## Issues
|
80
94
|
|
81
95
|
File issues in the [Community Package Repository (CPR) project](https://tickets.puppet.com/browse/CPR) with the 'Container' component.
|
data/bin/puppet-docker
CHANGED
@@ -9,6 +9,7 @@ Utilities for building and releasing Puppet docker images.
|
|
9
9
|
Usage:
|
10
10
|
puppet-docker build [DIRECTORY] [--dockerfile=<dockerfile>] [--repository=<repo>] [--namespace=<namespace>] [--no-cache]
|
11
11
|
puppet-docker lint [DIRECTORY] [--dockerfile=<dockerfile>]
|
12
|
+
puppet-docker local-lint [DIRECTORY] [--dockerfile=<dockerfile>]
|
12
13
|
puppet-docker pull [IMAGE] [--repository=<repo>]
|
13
14
|
puppet-docker push [DIRECTORY] [--dockerfile=<dockerfile>] [--repository=<repo>] [--namespace=<namespace>]
|
14
15
|
puppet-docker rev-labels [DIRECTORY] [--dockerfile=<dockerfile>] [--namespace=<namespace>]
|
@@ -71,6 +72,8 @@ begin
|
|
71
72
|
command_runner.build(no_cache: options['--no-cache'])
|
72
73
|
elsif options['lint']
|
73
74
|
command_runner.lint
|
75
|
+
elsif options['local-lint']
|
76
|
+
command_runner.local_lint
|
74
77
|
elsif options['push']
|
75
78
|
command_runner.push
|
76
79
|
elsif options['rev-labels']
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'date'
|
2
2
|
require 'docker'
|
3
|
+
require 'json'
|
3
4
|
require 'rspec/core'
|
4
5
|
require 'time'
|
5
6
|
require 'puppet_docker_tools/utilities'
|
@@ -29,8 +30,14 @@ class PuppetDockerTools
|
|
29
30
|
path = "#{repository}/#{image_name}"
|
30
31
|
puts "Building #{path}:latest"
|
31
32
|
|
33
|
+
build_args = {
|
34
|
+
'vcs_ref' => PuppetDockerTools::Utilities.current_git_sha(directory),
|
35
|
+
'build_date' => Time.now.utc.iso8601
|
36
|
+
}
|
37
|
+
|
32
38
|
# 't' in the build_options sets the tag for the image we're building
|
33
|
-
build_options = { 't' => "#{path}:latest", 'dockerfile' => dockerfile }
|
39
|
+
build_options = { 't' => "#{path}:latest", 'dockerfile' => dockerfile, 'buildargs' => "#{build_args.to_json}"}
|
40
|
+
|
34
41
|
if no_cache
|
35
42
|
puts "Ignoring cache for #{path}"
|
36
43
|
build_options['nocache'] = true
|
@@ -40,29 +47,21 @@ class PuppetDockerTools
|
|
40
47
|
if version
|
41
48
|
puts "Building #{path}:#{version}"
|
42
49
|
|
43
|
-
|
44
|
-
build_options = { 't' => "#{path}:#{version}", 'dockerfile' => dockerfile }
|
50
|
+
build_options['t'] = "#{path}:#{version}"
|
45
51
|
Docker::Image.build_from_dir(directory, build_options)
|
46
52
|
end
|
47
53
|
end
|
48
54
|
|
49
|
-
# Run hadolint on the Dockerfile in the specified directory.
|
50
|
-
#
|
51
|
-
#
|
55
|
+
# Run hadolint on the Dockerfile in the specified directory. This will run
|
56
|
+
# hadolint inside of a container. To run a locally-installed hadolint binary
|
57
|
+
# see local_lint.
|
52
58
|
#
|
53
59
|
def lint
|
54
60
|
hadolint_container = 'hadolint/hadolint'
|
55
|
-
ignore_rules = [
|
56
|
-
'DL3008',
|
57
|
-
'DL3018',
|
58
|
-
'DL4000',
|
59
|
-
'DL4001',
|
60
|
-
]
|
61
|
-
ignore_string = ignore_rules.map { |x| "--ignore #{x}" }.join(' ')
|
62
61
|
|
63
62
|
# make sure we have the container locally
|
64
63
|
PuppetDockerTools::Utilities.pull("#{hadolint_container}:latest")
|
65
|
-
container = Docker::Container.create('Cmd' => ['/bin/sh', '-c', "
|
64
|
+
container = Docker::Container.create('Cmd' => ['/bin/sh', '-c', "#{PuppetDockerTools::Utilities.get_hadolint_command}"], 'Image' => hadolint_container, 'OpenStdin' => true, 'StdinOnce' => true)
|
66
65
|
# This container.tap startes the container created above, and passes directory/Dockerfile to the container
|
67
66
|
container.tap(&:start).attach(stdin: "#{directory}/#{dockerfile}")
|
68
67
|
# Wait for the run to finish
|
@@ -73,6 +72,13 @@ class PuppetDockerTools
|
|
73
72
|
end
|
74
73
|
end
|
75
74
|
|
75
|
+
# Run hadolint Dockerfile linting using a local hadolint executable. Executable
|
76
|
+
# found based on your path.
|
77
|
+
def local_lint
|
78
|
+
output, status = Open3.capture2e(PuppetDockerTools::Utilities.get_hadolint_command("#{directory}/#{dockerfile}"))
|
79
|
+
fail output unless status == 0
|
80
|
+
end
|
81
|
+
|
76
82
|
# Push an image to hub.docker.com
|
77
83
|
#
|
78
84
|
def push
|
@@ -126,6 +126,23 @@ class PuppetDockerTools
|
|
126
126
|
end
|
127
127
|
end
|
128
128
|
|
129
|
+
# Generate the hadolint command that should be run. Hadolint is a
|
130
|
+
# linter for dockerfiles that also validates inline bash with shellcheck.
|
131
|
+
# For more info, see the github repo (https://github.com/hadolint/hadolint)
|
132
|
+
#
|
133
|
+
# @param file Dockerfile to lint, defaults to stdin
|
134
|
+
def get_hadolint_command(file = '-')
|
135
|
+
ignore_rules = [
|
136
|
+
'DL3008',
|
137
|
+
'DL3018',
|
138
|
+
'DL4000',
|
139
|
+
'DL4001',
|
140
|
+
]
|
141
|
+
ignore_string = ignore_rules.map { |x| "--ignore #{x}" }.join(' ')
|
142
|
+
|
143
|
+
"hadolint #{ignore_string} #{file}"
|
144
|
+
end
|
145
|
+
|
129
146
|
# Get a value from a Dockerfile
|
130
147
|
#
|
131
148
|
# @param key The key to read from the Dockerfile, e.g. 'from'
|
@@ -5,10 +5,13 @@ require 'docker'
|
|
5
5
|
describe PuppetDockerTools::Runner do
|
6
6
|
def create_runner(directory:, repository:, namespace:, dockerfile:)
|
7
7
|
allow(File).to receive(:exist?).with("#{directory}/#{dockerfile}").and_return(true)
|
8
|
+
allow(Dir).to receive(:chdir).with(directory).and_return('b0c5ead01b6cabdb3f01871bce699be165c3288f')
|
9
|
+
allow(Time).to receive(:now).and_return(Time.at(1528478293))
|
8
10
|
PuppetDockerTools::Runner.new(directory: directory, repository: repository, namespace: namespace, dockerfile: dockerfile)
|
9
11
|
end
|
10
12
|
|
11
13
|
let(:runner) { create_runner(directory: '/tmp/test-image', repository: 'test', namespace: 'org.label-schema', dockerfile: 'Dockerfile') }
|
14
|
+
let(:buildargs) {{ 'vcs_ref' => 'b0c5ead01b6cabdb3f01871bce699be165c3288f', 'build_date' => '2018-06-08T17:18:13Z' }.to_json}
|
12
15
|
|
13
16
|
describe '#initialize' do
|
14
17
|
it "should fail if the dockerfile doesn't exist" do
|
@@ -22,27 +25,27 @@ describe PuppetDockerTools::Runner do
|
|
22
25
|
|
23
26
|
it 'builds a latest and version tag if version is found' do
|
24
27
|
expect(PuppetDockerTools::Utilities).to receive(:get_value_from_env).with('version', namespace: runner.namespace, directory: runner.directory, dockerfile: runner.dockerfile).and_return('1.2.3')
|
25
|
-
expect(Docker::Image).to receive(:build_from_dir).with(runner.directory, { 't' => 'test/test-image:1.2.3', 'dockerfile' => runner.dockerfile }).and_return(image)
|
26
|
-
expect(Docker::Image).to receive(:build_from_dir).with(runner.directory, { 't' => 'test/test-image:latest', 'dockerfile' => runner.dockerfile }).and_return(image)
|
28
|
+
expect(Docker::Image).to receive(:build_from_dir).with(runner.directory, { 't' => 'test/test-image:1.2.3', 'dockerfile' => runner.dockerfile, 'buildargs' => buildargs }).and_return(image)
|
29
|
+
expect(Docker::Image).to receive(:build_from_dir).with(runner.directory, { 't' => 'test/test-image:latest', 'dockerfile' => runner.dockerfile, 'buildargs' => buildargs }).and_return(image)
|
27
30
|
runner.build
|
28
31
|
end
|
29
32
|
|
30
33
|
it 'builds just a latest tag if no version is found' do
|
31
34
|
expect(PuppetDockerTools::Utilities).to receive(:get_value_from_env).with('version', namespace: runner.namespace, directory: runner.directory, dockerfile: runner.dockerfile).and_return(nil)
|
32
|
-
expect(Docker::Image).to receive(:build_from_dir).with(runner.directory, { 't' => 'test/test-image:latest', 'dockerfile' => runner.dockerfile }).and_return(image)
|
35
|
+
expect(Docker::Image).to receive(:build_from_dir).with(runner.directory, { 't' => 'test/test-image:latest', 'dockerfile' => runner.dockerfile, 'buildargs' => buildargs }).and_return(image)
|
33
36
|
runner.build
|
34
37
|
end
|
35
38
|
|
36
39
|
it 'ignores the cache when that parameter is set' do
|
37
40
|
expect(PuppetDockerTools::Utilities).to receive(:get_value_from_env).with('version', namespace: runner.namespace, directory: runner.directory, dockerfile: runner.dockerfile).and_return(nil)
|
38
|
-
expect(Docker::Image).to receive(:build_from_dir).with(runner.directory, { 't' => 'test/test-image:latest', 'nocache' => true, 'dockerfile' => runner.dockerfile }).and_return(image)
|
41
|
+
expect(Docker::Image).to receive(:build_from_dir).with(runner.directory, { 't' => 'test/test-image:latest', 'nocache' => true, 'dockerfile' => runner.dockerfile, 'buildargs' => buildargs }).and_return(image)
|
39
42
|
runner.build(no_cache: true)
|
40
43
|
end
|
41
44
|
|
42
45
|
it 'uses a custom dockerfile if passed' do
|
43
46
|
allow(File).to receive(:exist?).with('/tmp/test-image/Dockerfile.test').and_return(true)
|
44
47
|
expect(PuppetDockerTools::Utilities).to receive(:get_value_from_env).with('version', namespace: 'org.label-schema', directory: '/tmp/test-image', dockerfile: 'Dockerfile.test').and_return(nil)
|
45
|
-
expect(Docker::Image).to receive(:build_from_dir).with('/tmp/test-image', { 't' => 'test/test-image:latest', 'dockerfile' => 'Dockerfile.test' }).and_return(image)
|
48
|
+
expect(Docker::Image).to receive(:build_from_dir).with('/tmp/test-image', { 't' => 'test/test-image:latest', 'dockerfile' => 'Dockerfile.test', 'buildargs' => buildargs }).and_return(image)
|
46
49
|
local_runner = create_runner(directory: '/tmp/test-image', repository: 'test', namespace: 'org.label-schema', dockerfile: 'Dockerfile.test')
|
47
50
|
local_runner.build
|
48
51
|
end
|
@@ -86,6 +89,13 @@ describe PuppetDockerTools::Runner do
|
|
86
89
|
end
|
87
90
|
end
|
88
91
|
|
92
|
+
describe '#local_lint' do
|
93
|
+
it "should fail with logs if linting fails" do
|
94
|
+
allow(Open3).to receive(:capture2e).with(PuppetDockerTools::Utilities.get_hadolint_command('/tmp/test-image/Dockerfile')).and_return('container logs', 1)
|
95
|
+
expect { runner.local_lint }.to raise_error(RuntimeError, /container logs/)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
89
99
|
describe '#push' do
|
90
100
|
it 'should fail if no version is set' do
|
91
101
|
expect(PuppetDockerTools::Utilities).to receive(:get_value_from_label).and_return(nil)
|
@@ -195,4 +195,13 @@ HERE
|
|
195
195
|
end
|
196
196
|
end
|
197
197
|
|
198
|
+
describe '#get_hadolint_command' do
|
199
|
+
it 'generates a commmand with a dockerfile' do
|
200
|
+
expect(PuppetDockerTools::Utilities.get_hadolint_command('test/Dockerfile')).to eq('hadolint --ignore DL3008 --ignore DL3018 --ignore DL4000 --ignore DL4001 test/Dockerfile')
|
201
|
+
end
|
202
|
+
|
203
|
+
it 'defaults to generating a command that reads from stdin' do
|
204
|
+
expect(PuppetDockerTools::Utilities.get_hadolint_command).to eq('hadolint --ignore DL3008 --ignore DL3018 --ignore DL4000 --ignore DL4001 -')
|
205
|
+
end
|
206
|
+
end
|
198
207
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
shared_examples "a running container" do |command, exit_status|
|
2
|
+
it "should run #{command} with exit status #{exit_status}" do
|
3
|
+
container = Docker::Container.create('Image' => @image.id, 'Cmd' => command)
|
4
|
+
container.start
|
5
|
+
container.wait
|
6
|
+
exit_status = container.json['State']['ExitCode']
|
7
|
+
expect(exit_status).to eq(exit_status)
|
8
|
+
container.kill
|
9
|
+
container.delete(force: true)
|
10
|
+
end
|
11
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: puppet_docker_tools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Puppet, Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-06-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: docker-api
|
@@ -87,6 +87,7 @@ files:
|
|
87
87
|
- spec/support/context/with_docker_container.rb
|
88
88
|
- spec/support/context/with_docker_container_dummy_cmd.rb
|
89
89
|
- spec/support/context/with_docker_image.rb
|
90
|
+
- spec/support/examples/running_container.rb
|
90
91
|
homepage: https://github.com/puppetlabs/puppet_docker_tools
|
91
92
|
licenses:
|
92
93
|
- Apache-2.0
|