class ChefCLI::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-cli/policyfile_services/push_archive.rb, line 40
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-cli/policyfile_services/push_archive.rb, line 50
def archive_file_path
  File.expand_path(archive_file, root_dir)
end
http_client() click to toggle source

@api private

# File lib/chef-cli/policyfile_services/push_archive.rb, line 78
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-cli/policyfile_services/push_archive.rb, line 54
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-cli/policyfile_services/push_archive.rb, line 70
def uploader
  ChefCLI::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-cli/policyfile_services/push_archive.rb, line 122
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-cli/policyfile_services/push_archive.rb, line 141
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-cli/policyfile_services/push_archive.rb, line 86
      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 ChefCLI. This version of
            ChefCLI does not support archives in the older format. Please Re-create the
            archive with a newer version of ChefCLI or Workstation.
          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 = ChefCLI::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-cli/policyfile_services/push_archive.rb, line 126
def stage_unpacked_archive
  p = Process.pid
  t = Time.new.utc.strftime("%Y%m%d%H%M%S")
  Dir.mktmpdir("chefcli-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-cli/policyfile_services/push_archive.rb, line 135
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