Class: Chef::Knife::ProxmoxVmBootstrap

Inherits:
Bootstrap
  • Object
show all
Includes:
ProxmoxBase, ProxmoxVmProvision
Defined in:
lib/chef/knife/proxmox_vm_bootstrap.rb

Overview

‘knife proxmox vm bootstrap NAME` — clone a Proxmox VE template, configure it, start it, wait for the guest to come up, then bootstrap it with Chef/CINC.

Subclasses Bootstrap (NOT Knife) so the whole post-provision lifecycle —connect, register, render, upload, perform — is inherited. We only fill the plugin hooks: setup, validate, create-instance, finalize. The clone→configure→start→wait pipeline and the CLI surface come from ProxmoxVmProvision (shared with ‘vm create`); this class adds the Chef bootstrap on top. The bootstrap target host is unknown until the VM exists, so #validate_name_args! is a deliberate no-op and the resolved IP is injected into @name_args in #plugin_create_instance!.

Constant Summary collapse

CINC_PRODUCT =

Bootstrap defaults to the community CINC build: a plain (even Chef-branded) knife then installs cinc-client and never hits Chef’s commercial license gate. Opt into Chef with knife = “chef” (or “chef-ice”) in config.rb.

"cinc"
CINC_INSTALL_URL =
"https://omnitruck.cinc.sh/install.sh"
PREINSTALL_WAIT_COMMAND =

A freshly cloned VM is still settling when SSH first answers, and two independent subsystems contend for the dpkg lock: cloud-init (which itself drives apt) and the apt-daily / unattended-upgrades systemd timers, which fire on their own schedule even after cloud-init reports done. Installing the client — or the first client run’s package resources — then races them for the lock and fails non-deterministically. Clear the field before the omnibus install, in order:

1. wait for cloud-init to finish;
2. stop the apt-daily / unattended-upgrades timers and any in-flight run, so nothing
   grabs the lock again for the rest of this boot (`stop`, not `disable`/`mask`: the
   services return on the next reboot, leaving the image unchanged);
3. block (bounded) until the dpkg lock a stopped run may still hold is released.

Every step is guarded on the tool existing and ‘|| true`, so non-cloud-init / non-systemd / non-apt images and degraded states still let the bootstrap proceed.

<<~SH
  if command -v cloud-init >/dev/null 2>&1; then cloud-init status --wait >/dev/null 2>&1 || true; fi
  if command -v systemctl >/dev/null 2>&1; then
    systemctl stop apt-daily.timer apt-daily-upgrade.timer apt-daily.service apt-daily-upgrade.service unattended-upgrades.service >/dev/null 2>&1 || true
  fi
  if command -v flock >/dev/null 2>&1; then
    for lock in /var/lib/dpkg/lock-frontend /var/lib/dpkg/lock; do
      [ -e "$lock" ] && flock -w 300 "$lock" true >/dev/null 2>&1 || true
    done
  fi
SH

Constants included from ProxmoxVmProvision

Chef::Knife::ProxmoxVmProvision::BRIDGE_PATTERN, Chef::Knife::ProxmoxVmProvision::ENV_CIPASSWORD, Chef::Knife::ProxmoxVmProvision::PRIVATE_KEY_MARKER, Chef::Knife::ProxmoxVmProvision::PUBLIC_KEY_PREFIXES

Constants included from ProxmoxBase

Chef::Knife::ProxmoxBase::BYTE_UNITS, Chef::Knife::ProxmoxBase::ENV_SECRET_GLOBAL, Chef::Knife::ProxmoxBase::ENV_SECRET_PREFIX

Instance Method Summary collapse

Methods included from ProxmoxVmProvision

included

Methods included from ProxmoxBase

#human_bytes, #human_duration, included, #msg_pair, #proxmox_api, #proxmox_client, #proxmox_cluster_config, #proxmox_token_secret_present?

Instance Method Details

#plugin_create_instance!Object



92
93
94
95
96
97
98
# File 'lib/chef/knife/proxmox_vm_bootstrap.rb', line 92

def plugin_create_instance!
  result = provision_vm!

  config[:chef_node_name] ||= @vm_name
  @name_args = [result.ip]
  @proxmox_result = result
end

#plugin_finalizeObject



100
101
102
103
104
105
106
# File 'lib/chef/knife/proxmox_vm_bootstrap.rb', line 100

def plugin_finalize
  result = @proxmox_result
  return unless result

  msg_provision_result(result)
  msg_pair("Chef node", config[:chef_node_name])
end

#plugin_setup!Object

plugin_setup! is the first hook Bootstrap#run invokes, so the CINC default is applied here — before render_template/perform_bootstrap build the omnibus install command. (In older knife this was done from a fetch_license override; knife 19.2 dropped that hook from the run sequence, so plugin_setup! is now the correct, earliest place.)



73
74
75
76
77
78
79
80
81
82
# File 'lib/chef/knife/proxmox_vm_bootstrap.rb', line 73

def plugin_setup!
  default_bootstrap_to_cinc!
  config[:connection_protocol] ||= "ssh"
  config[:connection_port] ||= 22
  # TOFU: a freshly cloned VM has no entry in known_hosts. Accept its key on
  # first connect rather than failing the bootstrap or disabling verification.
  config[:ssh_verify_host_key] ||= :accept_new
  # Drain cloud-init and the dpkg lock before the bootstrap installs the client (see constant).
  config[:bootstrap_preinstall_command] ||= PREINSTALL_WAIT_COMMAND
end

#plugin_validate_options!Object



88
89
90
# File 'lib/chef/knife/proxmox_vm_bootstrap.rb', line 88

def plugin_validate_options!
  validate_provision_options!(require_ssh_auth: true)
end

#validate_name_args!Object

The bootstrap target host does not exist yet — it is resolved to the VM’s IP in #plugin_create_instance!. Override the inherited “must pass an FQDN” guard.



86
# File 'lib/chef/knife/proxmox_vm_bootstrap.rb', line 86

def validate_name_args!; end