class ChefDK::PolicyfileServices::PushArchive

Constants

USTAR_INDICATOR

Attributes

archive_file[R]
config[R]
policy_group[R]
policyfile_lock[R]
root_dir[R]
ui[R]

Public Class Methods

new(archive_file: nil, policy_group: nil, root_dir: nil, ui: nil, config: nil) click to toggle source
# File lib/chef-dk/policyfile_services/push_archive.rb, line 41
def initialize(archive_file: nil, policy_group: nil, root_dir: nil, ui: nil, config: nil)
  @archive_file = archive_file
  @policy_group = policy_group
  @root_dir = root_dir || Dir.pwd
  @ui = ui
  @config = config

  @policyfile_lock = nil
end

Public Instance Methods

archive_file_path() click to toggle source
# File lib/chef-dk/policyfile_services/push_archive.rb, line 51
def archive_file_path
  File.expand_path(archive_file, root_dir)
end
http_client() click to toggle source

@api private

# File lib/chef-dk/policyfile_services/push_archive.rb, line 79
def http_client
  @http_client ||= Chef::ServerAPI.new(config.chef_server_url,
    signing_key_filename: config.client_key,
    client_name: config.node_name)
end
run() click to toggle source
# File lib/chef-dk/policyfile_services/push_archive.rb, line 55
def run
  unless File.exist?(archive_file_path)
    raise InvalidPolicyArchive, "Archive file #{archive_file_path} not found"
  end

  stage_unpacked_archive do |staging_dir|
    read_policyfile_lock(staging_dir)

    uploader.upload
  end

rescue => e
  raise PolicyfilePushArchiveError.new("Failed to publish archived policy", e)
end
uploader() click to toggle source

@api private

# File lib/chef-dk/policyfile_services/push_archive.rb, line 71
def uploader
  ChefDK::Policyfile::Uploader.new(policyfile_lock, policy_group,
    ui: ui,
    http_client: http_client,
    policy_document_native_api: config.policy_document_native_api)
end

Private Instance Methods

load_policy_data(policyfile_lock_path) click to toggle source
# File lib/chef-dk/policyfile_services/push_archive.rb, line 123
def load_policy_data(policyfile_lock_path)
  FFI_Yajl::Parser.parse(IO.read(policyfile_lock_path))
end
looks_like_old_format_archive?(staging_dir) click to toggle source
# File lib/chef-dk/policyfile_services/push_archive.rb, line 142
def looks_like_old_format_archive?(staging_dir)
  cookbooks_dir = File.join(staging_dir, "cookbooks")
  data_bags_dir = File.join(staging_dir, "data_bags")

  cookbook_artifacts_dir = File.join(staging_dir, "cookbook_artifacts")
  policies_dir = File.join(staging_dir, "policies")
  policy_groups_dir = File.join(staging_dir, "policy_groups")

  # Old archives just had these two dirs
  have_old_dirs = File.exist?(cookbooks_dir) && File.exist?(data_bags_dir)

  # New archives created by `chef export` will have all of these; it's
  # also possible we'll encounter an "artisanal" archive, which might
  # only be missing one of these by accident. In that case we want to
  # trigger a different error than we're detecting here.
  have_any_new_dirs = File.exist?(cookbook_artifacts_dir) ||
    File.exist?(policies_dir) ||
    File.exist?(policy_groups_dir)

  have_old_dirs && !have_any_new_dirs
end
read_policyfile_lock(staging_dir) click to toggle source
# File lib/chef-dk/policyfile_services/push_archive.rb, line 87
      def read_policyfile_lock(staging_dir)
        policyfile_lock_path = File.join(staging_dir, "Policyfile.lock.json")

        if looks_like_old_format_archive?(staging_dir)
          raise InvalidPolicyArchive, <<~MESSAGE
            This archive is in an unsupported format.

            This archive was created with an older version of #{ChefDK::Dist::PRODUCT}. This version of
            #{ChefDK::Dist::PRODUCT} does not support archives in the older format. Please Re-create the
            archive with a newer version of #{ChefDK::Dist::PRODUCT}.
          MESSAGE
        end

        unless File.exist?(policyfile_lock_path)
          raise InvalidPolicyArchive, "Archive does not contain a Policyfile.lock.json"
        end

        unless File.directory?(File.join(staging_dir, "cookbook_artifacts"))
          raise InvalidPolicyArchive, "Archive does not contain a cookbook_artifacts directory"
        end

        policy_data = load_policy_data(policyfile_lock_path)
        storage_config = Policyfile::StorageConfig.new.use_policyfile_lock(policyfile_lock_path)
        @policyfile_lock = ChefDK::PolicyfileLock.new(storage_config).build_from_archive(policy_data)

        missing_cookbooks = policyfile_lock.cookbook_locks.select do |name, lock|
          !lock.installed?
        end

        unless missing_cookbooks.empty?
          message = "Archive does not have all cookbooks required by the Policyfile.lock. " +
            "Missing cookbooks: '#{missing_cookbooks.keys.join('", "')}'."
          raise InvalidPolicyArchive, message
        end
      end
stage_unpacked_archive() { |staging_dir| ... } click to toggle source
# File lib/chef-dk/policyfile_services/push_archive.rb, line 127
def stage_unpacked_archive
  p = Process.pid
  t = Time.new.utc.strftime("%Y%m%d%H%M%S")
  Dir.mktmpdir("chefdk-push-archive-#{p}-#{t}") do |staging_dir|
    unpack_to(staging_dir)
    yield staging_dir
  end
end
unpack_to(staging_dir) click to toggle source
# File lib/chef-dk/policyfile_services/push_archive.rb, line 136
def unpack_to(staging_dir)
  Mixlib::Archive.new(archive_file_path).extract(staging_dir)
rescue => e
  raise InvalidPolicyArchive, "Archive file #{archive_file_path} could not be unpacked. #{e}"
end