class Drydock::Instructions::Copy
The concrete implementation of the COPY instruction. **Do not use this class directly.**
@see Project#copy
Attributes
chain[R]
chmod[RW]
ignorefile[RW]
no_cache[RW]
recursive[RW]
source_path[R]
target_path[R]
Public Instance Methods
run!()
click to toggle source
@raise [InvalidInstructionError] when the ‘source_path` does not exist @raise [InvalidInstructionError] when the `source_path` is an empty directory
with nothing to copy
@raise [InvalidInstructionError] when the ‘target_path` does not exist in the
container
@raise [InvalidInstructionError] when the ‘target_path` exists in the container,
but is not actually a directory
# File lib/drydock/instructions/copy.rb, line 29 def run! if source_path.start_with?('/') Drydock.logger.warn("#{source_path.inspect} is an absolute path; we recommend relative paths") end fail InvalidInstructionError, "#{source_path} does not exist" unless File.exist?(source_path) buffer = build_tar_from_source! digest = calculate_digest(buffer) write_to_container(buffer, digest) end
Private Instance Methods
build_tar_from_source!()
click to toggle source
# File lib/drydock/instructions/copy.rb, line 43 def build_tar_from_source! buffer = StringIO.new log_info("Processing #{source_files.size} files in tree") TarWriter.new(buffer) do |tar| source_files.each do |source_file| File.open(source_file, 'r') do |input| stat = input.stat mode = chmod || stat.mode tar.add_entry(source_file, mode: mode, mtime: stat.mtime) do |tar_file| tar_file.write(input.read) end end end end buffer.rewind buffer end
calculate_digest(buffer)
click to toggle source
# File lib/drydock/instructions/copy.rb, line 63 def calculate_digest(buffer) Digest::MD5.hexdigest(buffer.read).tap do |digest| log_info("Tree digest is md5:#{digest}") buffer.rewind end end
log_info(msg, indent: 0)
click to toggle source
# File lib/drydock/instructions/copy.rb, line 70 def log_info(msg, indent: 0) Drydock.logger.info(indent: indent, message: msg) end
source_files()
click to toggle source
Retrieve all files inside {#source_path} not matching the {#ignorefile} rules.
# File lib/drydock/instructions/copy.rb, line 75 def source_files files = if File.directory?(source_path) FileManager.find(source_path, ignorefile, prepend_path: true, recursive: recursive).sort else [source_path] end fail InvalidInstructionError, "#{source_path} is empty or does not match a path" if files.empty? files end
write_to_container(buffer, digest)
click to toggle source
Create a new container on the ‘chain`, and then write the contents of `buffer`, whose digest is `digest`.
# File lib/drydock/instructions/copy.rb, line 91 def write_to_container(buffer, digest) label = "# COPY #{recursive ? 'dir' : 'file'}:md5:#{digest} TO #{target_path}" chain.run(label, no_cache: no_cache) do |container| target_stat = container.archive_head(target_path) # TODO(rpasay): cannot autocreate the target, because `container` here is already dead unless target_stat fail InvalidInstructionError, "Target path #{target_path.inspect} does not exist" end unless target_stat.directory? Drydock.logger.debug(target_stat) fail InvalidInstructionError, "Target path #{target_path.inspect} exists, " + "but is not a directory in the container" end container.archive_put(target_path) do |output| output.write(buffer.read) end end end