Class: Kitchen::Provisioner::Dokken

Inherits:
ChefInfra
  • Object
show all
Defined in:
lib/kitchen/provisioner/dokken.rb

Overview

Provisioner for the dokken driver.

Unlike its ChefInfra parent this provisioner never installs chef: the driver mounts /opt/chef into the runner from a volume container built from the requested image, so all that is left to do here is stage the sandbox and run the client.

Author:

Instance Method Summary collapse

Instance Method Details

#call(state) ⇒ void

This method returns an undefined value.

Parameters:

  • state (Hash)

    mutable instance state

Raises:

  • (Kitchen::ActionFailed)

    if the transport fails



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/kitchen/provisioner/dokken.rb', line 82

def call(state)
  create_sandbox
  write_run_command(run_command)
  instance.transport.connection(state) do |conn|
    # Gate on what the driver recorded, not on a fresh probe. The driver
    # already answered this at create time -- it built a data container
    # or it did not -- and re-deriving the answer here means the two can
    # disagree. Point DOCKER_HOST somewhere else between `kitchen
    # create` and `kitchen converge` and they do: this side decides to
    # upload, the container it would upload through was never created,
    # and the transport dies on nil several frames down.
    #
    # Kitchen::Verifier::Base#call has always gated on the recorded
    # state; this is the provisioner agreeing with it.
    unless state[:data_container].nil?
      info("Transferring files to #{instance.to_str}")
      conn.upload(sandbox_dirs, config[:root_path])
    end

    conn.execute(prepare_command)
    conn.execute_with_retry(
      "sh #{config[:root_path]}/run_command",
      config[:retry_on_exit_code],
      config[:max_retries],
      config[:wait_for_retry]
    )
  end
rescue Kitchen::Transport::TransportFailed => ex
  raise ActionFailed, ex.message
ensure
  cleanup_dokken_sandbox if config[:clean_dokken_sandbox] # rubocop: disable Lint/EnsureReturn
end

#check_licensevoid

This method returns an undefined value.

Override the parent's check_license to skip the kitchen-omnibus-chef deprecation warning. That warning concerns the omnibus download mechanism, which dokken does not use — the chef/cinc binary is mounted from a volume container, not downloaded via omnitruck.

When the resolved parent is kitchen-cinc's CincInfra (which rebinds Kitchen::Provisioner::ChefInfra in Cinc Workstation 26+), there is no omnibus warning to suppress, license_acceptance_id is not defined, and the LicenseAcceptance constant is not autoloaded — delegate to super in that case so the parent's own check_license runs. We test for both because a partial drop-in shim may define license_acceptance_id without pulling in license-acceptance.

Raises:

  • (LicenseAcceptance::LicenseNotAcceptedError)

    if declined



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/kitchen/provisioner/dokken.rb', line 130

def check_license
  return super unless respond_to?(:license_acceptance_id, true) && defined?(LicenseAcceptance)

  name = license_acceptance_id
  version = product_version
  debug("Checking if we need to prompt for license acceptance on product: #{name} version: #{version}.")

  acceptor = LicenseAcceptance::Acceptor.new(logger: Kitchen.logger, provided: config[:chef_license])
  return unless acceptor.license_required?(name, version)

  debug("License acceptance required for #{name} version: #{version}. Prompting")
  license_id = acceptor.id_from_mixlib(name)
  begin
    acceptor.check_and_persist(license_id, version.to_s)
  rescue LicenseAcceptance::LicenseNotAcceptedError => e
    error("Cannot converge without accepting the #{e.product.pretty_name} License. Set it in your kitchen.yml or using the CHEF_LICENSE environment variable")
    raise
  end
  config[:chef_license] ||= acceptor.acceptance_value
end

#validate_configvoid

This method returns an undefined value.

Normalise the chef command-line settings before they are assembled.



154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/kitchen/provisioner/dokken.rb', line 154

def validate_config
  # check if we have an space for the user provided options
  # or add it if not to avoid issues
  # Assign rather than String#prepend: config values can be frozen
  # literals, and mutating them in place edits the user's kitchen.yml
  # data for the rest of the run.
  unless config[:chef_options].start_with? " "
    config[:chef_options] = " #{config[:chef_options]}"
  end

  # strip spaces from all other options
  config[:chef_binary] = config[:chef_binary].strip
  config[:chef_log_level] = config[:chef_log_level].strip
  config[:chef_output_format] = config[:chef_output_format].strip

  # if the user wants to be funny and pass empty strings
  # just use the defaults
  config[:chef_log_level] = "warn" if config[:chef_log_level].empty?
  config[:chef_output_format] = "doc" if config[:chef_output_format].empty?

  # ChefBase#chef_args appends `--log_level #{config[:log_level]}` to
  # whatever base command it is handed, so the parent's flag lands
  # *after* the `-l` built below. `-l` and `--log_level` are the same
  # chef-client option and the last occurrence wins, which meant
  # chef_log_level was parsed, written into the staged run_command, and
  # then silently overridden by the parent's default of "auto".
  # Keeping the two in step makes the documented setting the one chef
  # actually runs at.
  config[:log_level] = config[:chef_log_level]
end