Module: PuppetDockerTools::Utilities

Defined in:
lib/puppet_docker_tools/utilities.rb

Class Method Summary collapse

Class Method Details

.current_git_sha(directory = '.') ⇒ Object

Get the current git sha for the specified directory

Parameters:

  • directory (defaults to: '.')


65
66
67
68
69
# File 'lib/puppet_docker_tools/utilities.rb', line 65

def current_git_sha(directory = '.')
  Dir.chdir directory do
    `git rev-parse HEAD`.strip
  end
end

.format_timestamp(timestamp) ⇒ Object

Convert timestamps from second since epoch to ISO 8601 timestamps. If the given timestamp is entirely numeric it will be converted to an ISO 8601 timestamp, if not the parameter will be returned as passed.

Parameters:

  • timestamp

    The timestamp to convert



76
77
78
79
80
81
# File 'lib/puppet_docker_tools/utilities.rb', line 76

def format_timestamp(timestamp)
  if "#{timestamp}" =~ /^\d+$/
    timestamp = Time.at(Integer(timestamp)).utc.iso8601
  end
  timestamp
end

.get_value_from_base_image(value, namespace:, directory: '.', dockerfile: 'Dockerfile', dockerfile_contents: '') ⇒ Object

Get a value from a container’s base image

Parameters:

  • value

    The value we want to get from this image’s base image, e.g. ‘version’

  • namespace

    The namespace for the value, e.g. ‘org.label-schema’

  • directory (defaults to: '.')

    The directory containing the Dockerfile, defaults to $PWD

  • dockerfile (defaults to: 'Dockerfile')

    The file name for your dockerfile, defaults to ‘Dockerfile’

  • dockerfile_contents (defaults to: '')

    A string containing the contents of the Dockerfile [optional]



152
153
154
155
# File 'lib/puppet_docker_tools/utilities.rb', line 152

def get_value_from_base_image(value, namespace:, directory: '.', dockerfile: 'Dockerfile', dockerfile_contents: '')
  base_image = get_value_from_dockerfile('from', directory: directory, dockerfile: dockerfile, dockerfile_contents: dockerfile_contents).split(':').first.split('/').last
  get_value_from_env(value, namespace: namespace, directory: "#{directory}/../#{base_image}", dockerfile: dockerfile)
end

.get_value_from_dockerfile(key, directory: '.', dockerfile: 'Dockerfile', dockerfile_contents: '') ⇒ Object

Get a value from a Dockerfile

Parameters:

  • key

    The key to read from the Dockerfile, e.g. ‘from’

  • directory (defaults to: '.')

    The directory containing the Dockerfile, defaults to $PWD

  • dockerfile (defaults to: 'Dockerfile')

    The file name for your dockerfile, defaults to ‘Dockerfile’

  • dockerfile_contents (defaults to: '')

    A string containing the contents of the Dockerfile [optional]



135
136
137
138
139
140
141
142
# File 'lib/puppet_docker_tools/utilities.rb', line 135

def get_value_from_dockerfile(key, directory: '.', dockerfile: 'Dockerfile', dockerfile_contents: '')
  if dockerfile_contents.empty?
    file = "#{directory}/#{dockerfile}"
    fail "File #{file} doesn't exist!" unless File.exist? file
    dockerfile_contents = File.read("#{file}")
  end
  dockerfile_contents[/^#{key.upcase} (.*$)/, 1]
end

.get_value_from_env(label, namespace: '', directory: '.', dockerfile: 'Dockerfile') ⇒ Object

Get a value from a Dockerfile. Extrapolates variables and variables set in the base docker image

Parameters:

  • label

    The label containing the value you want to retrieve, e.g. ‘version’

  • namespace (defaults to: '')

    The namespace for the label, e.g. ‘org.label-schema’

  • directory (defaults to: '.')

    The directory containing the Dockerfile, defaults to $PWD

  • dockerfile (defaults to: 'Dockerfile')

    The file name for your dockerfile, defaults to ‘Dockerfile’



48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/puppet_docker_tools/utilities.rb', line 48

def get_value_from_env(label, namespace: '', directory: '.', dockerfile: 'Dockerfile')
  file = "#{directory}/#{dockerfile}"
  fail "File #{file} doesn't exist!" unless File.exist? file
  text = File.read(file)

  value = text.scan(/#{Regexp.escape(namespace)}\.(.+)=(.+) \\?/).to_h[label]
  # expand out environment variables
  value = get_value_from_variable(value, directory: directory, dockerfile: dockerfile, dockerfile_contents: text) if value.start_with?('$')
  # check in higher-level image if we didn't find it defined in this docker file
  value = get_value_from_base_image(label, namespace: namespace, directory: directory, dockerfile: dockerfile) if value.nil?
  # This gets rid of leading or trailing quotes
  value.gsub(/\A"|"\Z/, '')
end

.get_value_from_label(image, value:, namespace:) ⇒ Object

Get a value from the labels on a docker image

Parameters:

  • image

    The docker image you want to get a value from, e.g. ‘puppet/puppetserver’

  • value

    The value you want to get from the labels, e.g. ‘version’

  • namespace

    The namespace for the value, e.g. ‘org.label-schema’



34
35
36
37
38
39
# File 'lib/puppet_docker_tools/utilities.rb', line 34

def get_value_from_label(image, value: , namespace: )
  labels = Docker::Image.get(image).json["Config"]["Labels"]
  labels["#{namespace}.#{value.tr('_', '-')}"]
rescue
  nil
end

.get_value_from_variable(variable, directory: '.', dockerfile: 'Dockerfile', dockerfile_contents: '') ⇒ Object

Get a value from a variable in a Dockerfile

Parameters:

  • variable

    The variable we want to look for in the Dockerfile, e.g. $PUPPET_SERVER_VERSION

  • directory (defaults to: '.')

    The directory containing the Dockerfile, defaults to $PWD

  • dockerfile (defaults to: 'Dockerfile')

    The file name for your dockerfile, defaults to ‘Dockerfile’

  • dockerfile_contents (defaults to: '')

    A string containing the contents of the Dockerfile [optional]



164
165
166
167
168
169
170
171
172
173
# File 'lib/puppet_docker_tools/utilities.rb', line 164

def get_value_from_variable(variable, directory: '.', dockerfile: 'Dockerfile', dockerfile_contents: '')
  if dockerfile_contents.empty?
    file = "#{directory}/#{dockerfile}"
    fail "File #{file} doesn't exist!" unless File.exist? file
    dockerfile_contents = File.read("#{file}")
  end
  # get rid of the leading $ for the variable
  variable[0] = ''
  dockerfile_contents[/#{variable}=(["a-zA-Z0-9\.]+)/, 1]
end

.pull(image) ⇒ Object

Pull a docker image

Parameters:

  • image

    The image to pull. If the image does not include the tag to pull, it will pull all tags for that image



87
88
89
90
91
92
93
94
95
# File 'lib/puppet_docker_tools/utilities.rb', line 87

def pull(image)
  if image.include?(':')
    puts "Pulling #{image}"
    PuppetDockerTools::Utilities.pull_single_tag(image)
  else
    puts "Pulling all tags for #{image}"
    PuppetDockerTools::Utilities.pull_all_tags(image)
  end
end

.pull_all_tags(image) ⇒ Object

Pull all tags for a docker image

Parameters:

  • image

    The image to pull, e.g. puppet/puppetserver



100
101
102
103
104
105
106
107
108
109
# File 'lib/puppet_docker_tools/utilities.rb', line 100

def pull_all_tags(image)
  Docker::Image.create('fromImage' => image)

  # Filter through existing tags of that image so we can output what we pulled
  images = Docker::Image.all('filter' => image)
  images.each do |img|
    timestamp = PuppetDockerTools::Utilities.format_timestamp(img.info["Created"])
    puts "Pulled #{img.info["RepoTags"].join(', ')}, last updated #{timestamp}"
  end
end

.pull_single_tag(tag) ⇒ Object

Pull a single tag of a docker image

Parameters:

  • tag

    The image/tag to pull, e.g. puppet/puppetserver:latest



114
115
116
117
118
# File 'lib/puppet_docker_tools/utilities.rb', line 114

def pull_single_tag(tag)
  image = Docker::Image.create('fromImage' => tag)
  timestamp = PuppetDockerTools::Utilities.format_timestamp(image.info["Created"])
  puts "Pulled #{image.info["RepoTags"].first}, last updated #{timestamp}"
end

.push_to_dockerhub(image_name, stream_output = true) ⇒ Object

Push an image to hub.docker.com

Parameters:

  • image_name

    The image to push, including the tag e.g., puppet/puppetserver:latest

  • stream_output (defaults to: true)

    Whether or not to stream output as it comes in, defaults to true

Returns:

  • Returns an array containing the integer exitstatus of the push command and a string containing the combined stdout and stderr from the push



15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/puppet_docker_tools/utilities.rb', line 15

def push_to_dockerhub(image_name, stream_output=true)
  Open3.popen2e("docker push #{image_name}") do |stdin, output_stream, wait_thread|
    output=''
    while line = output_stream.gets
      if stream_output
        puts line
      end
      output += line
    end
    exit_status = wait_thread.value.exitstatus
    return exit_status, output
  end
end

.update_base_images(tags) ⇒ Object

Pull the specified tags

Parameters:

  • tags (Array)

    A list of tags to pull, e.g. [‘centos:7’, ‘ubuntu:16.04’]



123
124
125
126
127
# File 'lib/puppet_docker_tools/utilities.rb', line 123

def update_base_images(tags)
  tags.each do |tag|
    PuppetDockerTools::Utilities.pull(tag)
  end
end