class SIB::Image
SIB::Image
represents a docker image
Attributes
image[RW]
repo[RW]
Public Class Methods
build(repo:, build_dir:, dockerfile: 'Dockerfile', labels: {}, squash: false)
click to toggle source
TODO: Fix rubocop:disable Metrics/MethodLength
# File lib/service_image_builder/image.rb, line 14 def self.build(repo:, build_dir:, dockerfile: 'Dockerfile', labels: {}, squash: false) build_dir ||= Dir.pwd build_args = { 'dockerfile' => dockerfile, 'labels' => labels_to_json(labels), 'squash' => squash } SIB.log.info("Building #{repo} from #{Pathname.new(build_dir).join(dockerfile)}") # TODO: maybe have parse_api_response do the logging & just raise an error # when one gets detected image = Docker::Image.build_from_dir(build_dir, build_args) do |resp| parse_api_response(resp).each do |r| SIB.log.info(r['stream'].rstrip) if r.key?('stream') end end new(repo: repo, image: image) end
import(repo:, tag:)
click to toggle source
rubocop:enable Metrics/MethodLength
# File lib/service_image_builder/image.rb, line 35 def self.import(repo:, tag:) new(repo: repo, image: Docker::Image.create('fromImage' => "#{repo}:#{tag}")) rescue Docker::Error::NotFoundError nil end
labels_to_json(labels)
click to toggle source
# File lib/service_image_builder/image.rb, line 106 def labels_to_json(labels) Oj.dump(labels || {}) rescue Oj::Error => e raise ImageError, "Couldn't convert labels to json: #{e.message}" end
new(repo:, image:)
click to toggle source
# File lib/service_image_builder/image.rb, line 41 def initialize(repo:, image:) @image = image @repo = repo end
parse_api_response(response)
click to toggle source
# File lib/service_image_builder/image.rb, line 112 def parse_api_response(response) response.split("\r\n").map { |r| Oj.load(r) } rescue Oj::Error => e SIB.log.error("Couldn't JSON parse api response: #{e.message}") SIB.log.info("Unparseable message: #{response}") end
Public Instance Methods
<=>(other)
click to toggle source
Image#<=> is a comparison operator implementation for SIB::Image
. If the factor_hash
are the same, they're equal. Otherwise, the latest timestamp wins.
@param other; the SIB::Image
to compare against
# File lib/service_image_builder/image.rb, line 51 def <=>(other) return 0 if factor_hash == other.factor_hash timestamp.compare_with_coercion(other.timestamp) # <=> with coercion end
commit_id()
click to toggle source
# File lib/service_image_builder/image.rb, line 57 def commit_id @commit_id ||= labels.fetch('systems.slush.commit-id', nil) end
factor_hash()
click to toggle source
# File lib/service_image_builder/image.rb, line 61 def factor_hash @factor_hash ||= Digest::SHA2.new(256).tap do |hash| hash << commit_id hash << package_manifest end.hexdigest[0..15] end
labels()
click to toggle source
# File lib/service_image_builder/image.rb, line 68 def labels @labels ||= image.json['Config']['Labels'] end
package_manifest()
click to toggle source
Image#package_manifest
creates a container from @image and generates the package-manifest from it TODO extract the entire factor system out into its own object After that, remove the `Metrics/MethodLength` cop override
# File lib/service_image_builder/image.rb, line 76 def package_manifest @package_manifest ||= String.new.tap do |manifest| container = Docker::Container.create( 'Cmd' => ['/bin/bash', '-c', 'dnf list installed | sha256sum | colrm 65 > /package-manifest'], 'Image' => image.id, 'User' => 'root' ) container.tap(&:start).tap(&:wait) manifest << container.read_file('/package-manifest').chomp container.remove end end
push_tag(tag:)
click to toggle source
# File lib/service_image_builder/image.rb, line 90 def push_tag(tag:) image.tag(repo: repo, tag: tag) image.push(nil, tag: tag) do |msg| SIB::Image.parse_api_response(msg).each do |r| raise SIB::ImageError, r if r.key?('error') SIB.log.info(r) end end end
timestamp()
click to toggle source
# File lib/service_image_builder/image.rb, line 101 def timestamp @timestamp ||= Time.parse(labels.fetch('systems.slush.timestamp', nil)) end