Class: PuppetDockerTools::Runner

Inherits:
Object
  • Object
show all
Defined in:
lib/puppet_docker_tools/runner.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(directory:, repository:, namespace:, dockerfile:) ⇒ Runner

Returns a new instance of Runner.



12
13
14
15
16
17
18
19
20
# File 'lib/puppet_docker_tools/runner.rb', line 12

def initialize(directory: , repository: , namespace: , dockerfile: )
  @directory = directory
  @repository = repository
  @namespace = namespace
  @dockerfile = dockerfile

  file = "#{directory}/#{dockerfile}"
  fail "File #{file} doesn't exist!" unless File.exist? file
end

Instance Attribute Details

#directoryObject

Returns the value of attribute directory.



10
11
12
# File 'lib/puppet_docker_tools/runner.rb', line 10

def directory
  @directory
end

#dockerfileObject

Returns the value of attribute dockerfile.



10
11
12
# File 'lib/puppet_docker_tools/runner.rb', line 10

def dockerfile
  @dockerfile
end

#namespaceObject

Returns the value of attribute namespace.



10
11
12
# File 'lib/puppet_docker_tools/runner.rb', line 10

def namespace
  @namespace
end

#repositoryObject

Returns the value of attribute repository.



10
11
12
# File 'lib/puppet_docker_tools/runner.rb', line 10

def repository
  @repository
end

Instance Method Details

#build(no_cache: false) ⇒ Object

Build a docker image from a directory

Parameters:

  • no_cache (defaults to: false)

    Whether or not to use existing layer caches when building this image. Defaults to using the cache (no_cache = false).



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/puppet_docker_tools/runner.rb', line 26

def build(no_cache: false)
  image_name = File.basename(directory)
  version = PuppetDockerTools::Utilities.get_value_from_env('version', namespace: namespace, directory: directory, dockerfile: dockerfile)
  path = "#{repository}/#{image_name}"
  puts "Building #{path}:latest"

  # 't' in the build_options sets the tag for the image we're building
  build_options = { 't' => "#{path}:latest", 'dockerfile' => dockerfile }
  if no_cache
    puts "Ignoring cache for #{path}"
    build_options['nocache'] = true
  end
  Docker::Image.build_from_dir(directory, build_options)

  if version
    puts "Building #{path}:#{version}"

    # 't' in the build_options sets the tag for the image we're building
    build_options = { 't' => "#{path}:#{version}", 'dockerfile' => dockerfile }
    Docker::Image.build_from_dir(directory, build_options)
  end
end

#lintObject

Run hadolint on the Dockerfile in the specified directory. Hadolint is a linter for dockerfiles that also validates inline bash with shellcheck. For more info, see the github repo (github.com/hadolint/hadolint)



53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/puppet_docker_tools/runner.rb', line 53

def lint
  hadolint_container = 'hadolint/hadolint'
  # make sure we have the container locally
  PuppetDockerTools::Utilities.pull("#{hadolint_container}:latest")
  container = Docker::Container.create('Cmd' => ['/bin/sh', '-c', "hadolint --ignore DL3008 --ignore DL4000 --ignore DL4001 - "], 'Image' => hadolint_container, 'OpenStdin' => true, 'StdinOnce' => true)
  # This container.tap startes the container created above, and passes directory/Dockerfile to the container
  container.tap(&:start).attach(stdin: "#{directory}/#{dockerfile}")
  # Wait for the run to finish
  container.wait
  exit_status = container.json['State']['ExitCode']
  unless exit_status == 0
    fail container.logs(stdout: true, stderr: true)
  end
end

#pushObject

Push an image to hub.docker.com



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/puppet_docker_tools/runner.rb', line 70

def push
  image_name = File.basename(directory)
  path = "#{repository}/#{image_name}"
  version = PuppetDockerTools::Utilities.get_value_from_label(path, value: 'version', namespace: namespace)

  # We always want to push a versioned label in addition to the latest label
  unless version
    fail "No version specified in #{dockerfile} for #{path}"
  end

  puts "Pushing #{path}:#{version} to Docker Hub"
  exitstatus, _ = PuppetDockerTools::Utilities.push_to_dockerhub("#{path}:#{version}")
  unless exitstatus == 0
    fail "Pushing #{path}:#{version} to dockerhub failed!"
  end

  puts "Pushing #{path}:latest to Docker Hub"
  exitstatus, _ = PuppetDockerTools::Utilities.push_to_dockerhub("#{path}:latest")
  unless exitstatus == 0
    fail "Pushing #{path}:latest to dockerhub failed!"
  end
end

#rev_labelsObject

Update vcs-ref and build-date labels in the Dockerfile



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/puppet_docker_tools/runner.rb', line 95

def rev_labels
  file = File.join(directory, dockerfile)

  values_to_update = {
    "#{namespace}.vcs-ref" => PuppetDockerTools::Utilities.current_git_sha(directory),
    "#{namespace}.build-date" => Time.now.utc.iso8601
  }

  text = File.read(file)
  values_to_update.each do |key, value|
    original = text.clone
    text = text.gsub(/#{key}=\"[a-z0-9A-Z\-:]*\"/, "#{key}=\"#{value}\"")
    puts "Updating #{key} in #{file}" unless original == text
  end

  File.open(file, 'w') { |f| f.puts text }
end

#specObject

Run spec tests



115
116
117
118
119
120
121
# File 'lib/puppet_docker_tools/runner.rb', line 115

def spec
  tests = Dir.glob("#{directory}/spec/*_spec.rb")
  test_files = tests.map { |test| File.basename(test, '.rb') }

  puts "Running RSpec tests from #{File.expand_path("#{directory}/spec")} (#{test_files.join ","}), this may take some time"
  RSpec::Core::Runner.run(tests, $stderr, $stdout)
end

#versionObject

Get the version set in the Dockerfile in the specified directory



125
126
127
# File 'lib/puppet_docker_tools/runner.rb', line 125

def version
  puts PuppetDockerTools::Utilities.get_value_from_env('version', namespace: namespace, directory: directory, dockerfile: dockerfile)
end