puppet_docker_tools 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|