From f1a8dc1f922cb4c8cfb59718a4d0cc700bffb53f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20F=20Bj=C3=B6rklund?= Date: Mon, 8 Jan 2024 22:30:39 +0100 Subject: [PATCH] Option to upgrade packages and reboot if required MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will run "apt upgrade" or "dnf upgrade" on the first boot, to make sure that all packages are updated to the latest version. It adds to the initial startup time and to the size of the diffdisk, so it is better to update the basedisk with a newer cloud release. Signed-off-by: Anders F Björklund --- examples/default.yaml | 5 +++++ .../boot/00-reboot-if-required.sh | 15 +++++++++++++++ pkg/cidata/cidata.TEMPLATE.d/user-data | 6 ++++++ pkg/cidata/cidata.go | 1 + pkg/cidata/template.go | 1 + pkg/limayaml/defaults.go | 10 ++++++++++ pkg/limayaml/defaults_test.go | 3 +++ pkg/limayaml/limayaml.go | 1 + 8 files changed, 42 insertions(+) create mode 100644 pkg/cidata/cidata.TEMPLATE.d/boot/00-reboot-if-required.sh diff --git a/examples/default.yaml b/examples/default.yaml index 65ccc6b6a28..42a02ffbcf4 100644 --- a/examples/default.yaml +++ b/examples/default.yaml @@ -166,6 +166,11 @@ caCerts: # YOUR-ORGS-TRUSTED-CA-CERT-HERE # -----END CERTIFICATE----- +# Upgrade the instance on boot +# Reboot after upgrade if required +# 🟢 Builtin default: false +upgradePackages: null + containerd: # Enable system-wide (aka rootful) containerd and its dependencies (BuildKit, Stargz Snapshotter) # Note that `nerdctl.lima` only works in rootless mode; you have to use `lima sudo nerdctl ...` diff --git a/pkg/cidata/cidata.TEMPLATE.d/boot/00-reboot-if-required.sh b/pkg/cidata/cidata.TEMPLATE.d/boot/00-reboot-if-required.sh new file mode 100644 index 00000000000..968181a13ec --- /dev/null +++ b/pkg/cidata/cidata.TEMPLATE.d/boot/00-reboot-if-required.sh @@ -0,0 +1,15 @@ +#!/bin/sh +set -eux + +# Check if cloud-init forgot to reboot_if_required +# (only implemented for apt at the moment, not dnf) + +if command -v dnf >/dev/null 2>&1; then + # dnf-utils needs to be installed, for needs-restarting + if dnf -h needs-restarting >/dev/null 2>&1; then + # needs-restarting returns "false" if needed (!) + if ! dnf needs-restarting -r >/dev/null 2>&1; then + systemctl reboot + fi + fi +fi diff --git a/pkg/cidata/cidata.TEMPLATE.d/user-data b/pkg/cidata/cidata.TEMPLATE.d/user-data index 59e6b74e736..8f35b2a2d3a 100644 --- a/pkg/cidata/cidata.TEMPLATE.d/user-data +++ b/pkg/cidata/cidata.TEMPLATE.d/user-data @@ -5,6 +5,12 @@ growpart: mode: auto devices: ['/'] +{{- if .UpgradePackages }} +package_update: true +package_upgrade: true +package_reboot_if_required: true +{{- end }} + {{- if or (eq .MountType "9p") (eq .MountType "virtiofs") }} {{- if .Mounts }} mounts: diff --git a/pkg/cidata/cidata.go b/pkg/cidata/cidata.go index 58a2a472ce6..99f2e569232 100644 --- a/pkg/cidata/cidata.go +++ b/pkg/cidata/cidata.go @@ -128,6 +128,7 @@ func GenerateISO9660(instDir, name string, y *limayaml.LimaYAML, udpDNSLocalPort UID: uid, Home: fmt.Sprintf("/home/%s.linux", u.Username), GuestInstallPrefix: *y.GuestInstallPrefix, + UpgradePackages: *y.UpgradePackages, Containerd: Containerd{System: *y.Containerd.System, User: *y.Containerd.User}, SlirpNICName: networks.SlirpNICName, diff --git a/pkg/cidata/template.go b/pkg/cidata/template.go index e1fa8c642a6..dbd17a7c389 100644 --- a/pkg/cidata/template.go +++ b/pkg/cidata/template.go @@ -63,6 +63,7 @@ type TemplateArgs struct { MountType string Disks []Disk GuestInstallPrefix string + UpgradePackages bool Containerd Containerd Networks []Network SlirpNICName string diff --git a/pkg/limayaml/defaults.go b/pkg/limayaml/defaults.go index f8c1dc41663..00ccf6bd551 100644 --- a/pkg/limayaml/defaults.go +++ b/pkg/limayaml/defaults.go @@ -444,6 +444,16 @@ func FillDefault(y, d, o *LimaYAML, filePath string) { y.GuestInstallPrefix = ptr.Of(defaultGuestInstallPrefix()) } + if y.UpgradePackages == nil { + y.UpgradePackages = d.UpgradePackages + } + if o.UpgradePackages != nil { + y.UpgradePackages = o.UpgradePackages + } + if y.UpgradePackages == nil { + y.UpgradePackages = ptr.Of(false) + } + if y.Containerd.System == nil { y.Containerd.System = d.Containerd.System } diff --git a/pkg/limayaml/defaults_test.go b/pkg/limayaml/defaults_test.go index 3b32a1fb7c9..e6ada70be62 100644 --- a/pkg/limayaml/defaults_test.go +++ b/pkg/limayaml/defaults_test.go @@ -73,6 +73,7 @@ func TestFillDefault(t *testing.T) { Memory: ptr.Of(defaultMemoryAsString()), Disk: ptr.Of(defaultDiskSizeAsString()), GuestInstallPrefix: ptr.Of(defaultGuestInstallPrefix()), + UpgradePackages: ptr.Of(false), Containerd: Containerd{ System: ptr.Of(false), User: ptr.Of(true), @@ -309,6 +310,7 @@ func TestFillDefault(t *testing.T) { {Name: "data"}, }, GuestInstallPrefix: ptr.Of("/opt"), + UpgradePackages: ptr.Of(true), Containerd: Containerd{ System: ptr.Of(true), User: ptr.Of(false), @@ -498,6 +500,7 @@ func TestFillDefault(t *testing.T) { {Name: "test"}, }, GuestInstallPrefix: ptr.Of("/usr"), + UpgradePackages: ptr.Of(true), Containerd: Containerd{ System: ptr.Of(true), User: ptr.Of(false), diff --git a/pkg/limayaml/limayaml.go b/pkg/limayaml/limayaml.go index eb1e3ea22f3..38ce1e5a408 100644 --- a/pkg/limayaml/limayaml.go +++ b/pkg/limayaml/limayaml.go @@ -23,6 +23,7 @@ type LimaYAML struct { Audio Audio `yaml:"audio,omitempty" json:"audio,omitempty"` Video Video `yaml:"video,omitempty" json:"video,omitempty"` Provision []Provision `yaml:"provision,omitempty" json:"provision,omitempty"` + UpgradePackages *bool `yaml:"upgradePackages,omitempty" json:"upgradePackages,omitempty"` Containerd Containerd `yaml:"containerd,omitempty" json:"containerd,omitempty"` GuestInstallPrefix *string `yaml:"guestInstallPrefix,omitempty" json:"guestInstallPrefix,omitempty"` Probes []Probe `yaml:"probes,omitempty" json:"probes,omitempty"`