* [pve-devel] [PATCH installer v2 1/5] fix #5579: first-boot: add initial service packaging
2024-11-18 12:38 [pve-devel] [PATCH installer v2 0/5] fix #5579: allow specifying optional first-boot script Christoph Heiss
@ 2024-11-18 12:38 ` Christoph Heiss
2024-11-18 12:38 ` [pve-devel] [PATCH installer v2 2/5] fix #5579: setup: introduce 'first_boot' low-level installer options Christoph Heiss
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Christoph Heiss @ 2024-11-18 12:38 UTC (permalink / raw)
To: pve-devel
While there is the `systemd-first-boot.service`, it uses the
non-existence of `/etc/machine-id` as condition to run. As we already
set up that file in the installer ourselves, we cannot use that.
Instead our service depends on a custom flag file in
/var/lib/proxmox-first-boot and will only run if that is present.
Signed-off-by: Christoph Heiss <c.heiss@proxmox.com>
---
Changes v1 -> v2:
* changed to three separate services, of which the requested one gets
enabled manually, as suggested by Thomas
Makefile | 13 ++++++++++---
debian/control | 7 +++++++
debian/proxmox-first-boot.install | 3 +++
debian/rules | 5 +++++
proxmox-first-boot/Makefile | 10 ++++++++++
.../etc/proxmox-first-boot-multi-user.service | 15 +++++++++++++++
.../proxmox-first-boot-network-online.service | 17 +++++++++++++++++
.../etc/proxmox-first-boot-network-pre.service | 17 +++++++++++++++++
8 files changed, 84 insertions(+), 3 deletions(-)
create mode 100644 debian/proxmox-first-boot.install
create mode 100644 proxmox-first-boot/Makefile
create mode 100644 proxmox-first-boot/etc/proxmox-first-boot-multi-user.service
create mode 100644 proxmox-first-boot/etc/proxmox-first-boot-network-online.service
create mode 100644 proxmox-first-boot/etc/proxmox-first-boot-network-pre.service
diff --git a/Makefile b/Makefile
index d85347f..a17f6c5 100644
--- a/Makefile
+++ b/Makefile
@@ -5,6 +5,10 @@ BUILDDIR ?= $(PACKAGE)-$(DEB_VERSION_UPSTREAM)
DEB=$(PACKAGE)_$(DEB_VERSION)_$(DEB_HOST_ARCH).deb
ASSISTANT_DEB=proxmox-auto-install-assistant_$(DEB_VERSION)_$(DEB_HOST_ARCH).deb
+FIRST_BOOT_DEB=proxmox-first-boot_$(DEB_VERSION)_$(DEB_HOST_ARCH).deb
+
+ALL_DEBS = $(DEB) $(ASSISTANT_DEB) $(FIRST_BOOT_DEB)
+
DSC=$(PACKAGE)_$(DEB_VERSION).dsc
CARGO ?= cargo
@@ -61,6 +65,7 @@ $(BUILDDIR):
proxmox-tui-installer/ \
proxmox-installer-common/ \
proxmox-post-hook \
+ proxmox-first-boot \
test/ \
$(SHELL_SCRIPTS) \
$@.tmp
@@ -73,9 +78,10 @@ country.dat: country.pl
deb: $(DEB)
$(ASSISTANT_DEB): $(DEB)
+$(FIRST_BOOT_DEB): $(DEB)
$(DEB): $(BUILDDIR)
cd $(BUILDDIR); dpkg-buildpackage -b -us -uc
- lintian $(DEB) $(ASSISTANT_DEB)
+ lintian $(ALL_DEBS)
test-$(DEB): $(INSTALLER_SOURCES)
rsync --exclude='test*.img' --exclude='*.deb' --exclude='build' -a * build
@@ -114,6 +120,7 @@ HTMLDIR=$(VARLIBDIR)/html/common
install: $(INSTALLER_SOURCES) $(COMPILED_BINS)
$(MAKE) -C banner install
$(MAKE) -C Proxmox install
+ $(MAKE) -C proxmox-first-boot install
install -D -m 644 interfaces $(DESTDIR)/etc/network/interfaces
install -D -m 755 fake-start-stop-daemon $(VARLIBDIR)/fake-start-stop-daemon
install -D -m 755 policy-disable-rc.d $(VARLIBDIR)/policy-disable-rc.d
@@ -143,8 +150,8 @@ cargo-build:
.PHONY: upload
upload: UPLOAD_DIST ?= $(DEB_DISTRIBUTION)
-upload: $(DEB) $(ASSISTANT_DEB)
- tar cf - $(DEB) $(ASSISTANT_DEB) | ssh -X repoman@repo.proxmox.com -- upload --product pve,pmg,pbs --dist $(UPLOAD_DIST)
+upload: $(ALL_DEBS)
+ tar cf - $(ALL_DEBS) | ssh -X repoman@repo.proxmox.com -- upload --product pve,pmg,pbs --dist $(UPLOAD_DIST)
%.img:
truncate -s 2G $@
diff --git a/debian/control b/debian/control
index ff00cc2..fd0f4df 100644
--- a/debian/control
+++ b/debian/control
@@ -62,3 +62,10 @@ Description: Assistant to help with automated installations
Provides a helper that can assist with creating an answer file for a automated
installation of a Proxmox project, and preparing a official ISO image to use
this answer file.
+
+Package: proxmox-first-boot
+Architecture: any
+Depends: ${misc:Depends},
+Description: Service which runs on the first system boot for additional setup
+ Provides a service which will run on the first boot if the a script was
+ configured through the auto-installer.
diff --git a/debian/proxmox-first-boot.install b/debian/proxmox-first-boot.install
new file mode 100644
index 0000000..715f11a
--- /dev/null
+++ b/debian/proxmox-first-boot.install
@@ -0,0 +1,3 @@
+lib/systemd/system/proxmox-first-boot-network-pre.service
+lib/systemd/system/proxmox-first-boot-network-online.service
+lib/systemd/system/proxmox-first-boot-multi-user.service
diff --git a/debian/rules b/debian/rules
index 8a3f879..84d5943 100755
--- a/debian/rules
+++ b/debian/rules
@@ -19,3 +19,8 @@ override_dh_strip:
-executable -type f); do \
debian/scripts/elf-strip-unused-dependencies.sh "$$exe" || true; \
done
+
+override_dh_installsystemd:
+ # disables all services by default, as we enable them ourselves in
+ # the installer
+ dh_installsystemd --no-stop-on-upgrade --no-start --no-enable
diff --git a/proxmox-first-boot/Makefile b/proxmox-first-boot/Makefile
new file mode 100644
index 0000000..d889c67
--- /dev/null
+++ b/proxmox-first-boot/Makefile
@@ -0,0 +1,10 @@
+all:
+
+DESTDIR =
+LIBSYSTEMD_DIR = $(DESTDIR)/lib/systemd/system
+
+.PHONY: install
+install:
+ install -D -m 644 etc/proxmox-first-boot-network-pre.service $(LIBSYSTEMD_DIR)/proxmox-first-boot-network-pre.service
+ install -D -m 644 etc/proxmox-first-boot-network-online.service $(LIBSYSTEMD_DIR)/proxmox-first-boot-network-online.service
+ install -D -m 644 etc/proxmox-first-boot-multi-user.service $(LIBSYSTEMD_DIR)/proxmox-first-boot-multi-user.service
diff --git a/proxmox-first-boot/etc/proxmox-first-boot-multi-user.service b/proxmox-first-boot/etc/proxmox-first-boot-multi-user.service
new file mode 100644
index 0000000..d3c798d
--- /dev/null
+++ b/proxmox-first-boot/etc/proxmox-first-boot-multi-user.service
@@ -0,0 +1,15 @@
+[Unit]
+Description=Proxmox First Boot Setup (Fully Booted)
+After=systemd-remount-fs.service
+ConditionPathExists=/var/lib/proxmox-first-boot/pending-first-boot-setup
+ConditionPathIsReadWrite=/var/lib
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=/var/lib/proxmox-first-boot/proxmox-first-boot fully-up
+ExecStartPost=/usr/bin/rm -v /var/lib/proxmox-first-boot/pending-first-boot-setup
+
+[Install]
+Alias=proxmox-first-boot.service
+WantedBy=multi-user.target
diff --git a/proxmox-first-boot/etc/proxmox-first-boot-network-online.service b/proxmox-first-boot/etc/proxmox-first-boot-network-online.service
new file mode 100644
index 0000000..8417747
--- /dev/null
+++ b/proxmox-first-boot/etc/proxmox-first-boot-network-online.service
@@ -0,0 +1,17 @@
+[Unit]
+Description=Proxmox First Boot Setup (Network Online)
+After=systemd-remount-fs.service
+After=network-online.target
+Wants=network-online.target
+ConditionPathExists=/var/lib/proxmox-first-boot/pending-first-boot-setup
+ConditionPathIsReadWrite=/var/lib
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=/var/lib/proxmox-first-boot/proxmox-first-boot network-online
+ExecStartPost=/usr/bin/rm -v /var/lib/proxmox-first-boot/pending-first-boot-setup
+
+[Install]
+Alias=proxmox-first-boot.service
+WantedBy=multi-user.target
diff --git a/proxmox-first-boot/etc/proxmox-first-boot-network-pre.service b/proxmox-first-boot/etc/proxmox-first-boot-network-pre.service
new file mode 100644
index 0000000..1b4e396
--- /dev/null
+++ b/proxmox-first-boot/etc/proxmox-first-boot-network-pre.service
@@ -0,0 +1,17 @@
+[Unit]
+Description=Proxmox First Boot Setup (Pre-Network)
+After=systemd-remount-fs.service
+Before=network-pre.target
+Wants=network-pre.target
+ConditionPathExists=/var/lib/proxmox-first-boot/pending-first-boot-setup
+ConditionPathIsReadWrite=/var/lib
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=/var/lib/proxmox-first-boot/proxmox-first-boot before-network
+ExecStartPost=/usr/bin/rm -v /var/lib/proxmox-first-boot/pending-first-boot-setup
+
+[Install]
+Alias=proxmox-first-boot.service
+WantedBy=network.target
--
2.47.0
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 7+ messages in thread
* [pve-devel] [PATCH installer v2 2/5] fix #5579: setup: introduce 'first_boot' low-level installer options
2024-11-18 12:38 [pve-devel] [PATCH installer v2 0/5] fix #5579: allow specifying optional first-boot script Christoph Heiss
2024-11-18 12:38 ` [pve-devel] [PATCH installer v2 1/5] fix #5579: first-boot: add initial service packaging Christoph Heiss
@ 2024-11-18 12:38 ` Christoph Heiss
2024-11-18 12:38 ` [pve-devel] [PATCH installer v2 3/5] fix #5579: auto-install-assistant: enable baking in first-boot script Christoph Heiss
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Christoph Heiss @ 2024-11-18 12:38 UTC (permalink / raw)
To: pve-devel
.. to enable the setup of the 'proxmox-first-boot' service, as well as
optionally setting the ordering.
Signed-off-by: Christoph Heiss <c.heiss@proxmox.com>
---
Changes v1 -> v2:
* add tests
* introduce `first_boot.enabled` low-level option to tell the
installer explicitly about it
Proxmox/Install/Config.pm | 20 +++++++++++++++++++
proxmox-auto-installer/src/utils.rs | 6 ++++--
.../tests/resources/parse_answer/btrfs.json | 3 ++-
.../resources/parse_answer/disk_match.json | 3 ++-
.../parse_answer/disk_match_all.json | 3 ++-
.../parse_answer/disk_match_any.json | 3 ++-
.../resources/parse_answer/first-boot.json | 19 ++++++++++++++++++
.../resources/parse_answer/first-boot.toml | 18 +++++++++++++++++
.../parse_answer/hashed_root_password.json | 3 ++-
.../tests/resources/parse_answer/minimal.json | 3 ++-
.../resources/parse_answer/nic_matching.json | 3 ++-
.../resources/parse_answer/specific_nic.json | 3 ++-
.../tests/resources/parse_answer/zfs.json | 3 ++-
proxmox-installer-common/src/setup.rs | 17 ++++++++++++++++
proxmox-tui-installer/src/setup.rs | 4 +++-
15 files changed, 99 insertions(+), 12 deletions(-)
create mode 100644 proxmox-auto-installer/tests/resources/parse_answer/first-boot.json
create mode 100644 proxmox-auto-installer/tests/resources/parse_answer/first-boot.toml
diff --git a/Proxmox/Install/Config.pm b/Proxmox/Install/Config.pm
index 6d47b75..b3a257e 100644
--- a/Proxmox/Install/Config.pm
+++ b/Proxmox/Install/Config.pm
@@ -111,6 +111,14 @@ my sub init_cfg {
gateway => undef,
dns => undef,
target_cmdline => undef,
+
+ # proxmox-first-boot setup
+ first_boot => {
+ enabled => 0,
+ # Must be kept in sync with proxmox_auto_installer::answer::FirstBootHookServiceOrdering
+ # and the service files in the proxmox-first-boot package
+ ordering_target => 'multi-user', # one of `network-pre`, `network-online` or `multi-user`
+ },
};
$initial = parse_kernel_cmdline($initial);
@@ -279,4 +287,16 @@ sub get_target_cmdline { return get('target_cmdline'); }
sub set_existing_storage_auto_rename { set_key('existing_storage_auto_rename', $_[0]); }
sub get_existing_storage_auto_rename { return get('existing_storage_auto_rename'); }
+sub set_first_boot_opt {
+ my ($k, $v) = @_;
+ my $opts = get('first_boot');
+ croak "unknown first boot override key '$k'" if !exists($opts->{$k});
+ $opts->{$k} = $v;
+}
+sub get_first_boot_opt {
+ my ($k) = @_;
+ my $opts = get('first_boot');
+ return defined($k) ? $opts->{$k} : $opts;
+}
+
1;
diff --git a/proxmox-auto-installer/src/utils.rs b/proxmox-auto-installer/src/utils.rs
index dd686c0..9c399a5 100644
--- a/proxmox-auto-installer/src/utils.rs
+++ b/proxmox-auto-installer/src/utils.rs
@@ -11,8 +11,8 @@ use crate::{
use proxmox_installer_common::{
options::{email_validate, FsType, NetworkOptions, ZfsChecksumOption, ZfsCompressOption},
setup::{
- InstallBtrfsOption, InstallConfig, InstallRootPassword, InstallZfsOption, LocaleInfo,
- RuntimeInfo, SetupInfo,
+ InstallBtrfsOption, InstallConfig, InstallFirstBootSetup, InstallRootPassword,
+ InstallZfsOption, LocaleInfo, RuntimeInfo, SetupInfo,
},
};
use serde::{Deserialize, Serialize};
@@ -374,6 +374,8 @@ pub fn parse_answer(
cidr: network_settings.address,
gateway: network_settings.gateway,
dns: network_settings.dns_server,
+
+ first_boot: InstallFirstBootSetup::default(),
};
set_disks(answer, udev_info, runtime_info, &mut config)?;
diff --git a/proxmox-auto-installer/tests/resources/parse_answer/btrfs.json b/proxmox-auto-installer/tests/resources/parse_answer/btrfs.json
index 0330a38..de4c6e5 100644
--- a/proxmox-auto-installer/tests/resources/parse_answer/btrfs.json
+++ b/proxmox-auto-installer/tests/resources/parse_answer/btrfs.json
@@ -20,5 +20,6 @@
"timezone": "Europe/Vienna",
"btrfs_opts": {
"compress": "zlib"
- }
+ },
+ "first_boot": { "enabled": 0 }
}
diff --git a/proxmox-auto-installer/tests/resources/parse_answer/disk_match.json b/proxmox-auto-installer/tests/resources/parse_answer/disk_match.json
index 6c8d6d9..48a82e6 100644
--- a/proxmox-auto-installer/tests/resources/parse_answer/disk_match.json
+++ b/proxmox-auto-installer/tests/resources/parse_answer/disk_match.json
@@ -26,5 +26,6 @@
"checksum": "on",
"compress": "on",
"copies": 1
- }
+ },
+ "first_boot": { "enabled": 0 }
}
diff --git a/proxmox-auto-installer/tests/resources/parse_answer/disk_match_all.json b/proxmox-auto-installer/tests/resources/parse_answer/disk_match_all.json
index 2d2e94e..f012eb1 100644
--- a/proxmox-auto-installer/tests/resources/parse_answer/disk_match_all.json
+++ b/proxmox-auto-installer/tests/resources/parse_answer/disk_match_all.json
@@ -23,5 +23,6 @@
"checksum": "on",
"compress": "on",
"copies": 1
- }
+ },
+ "first_boot": { "enabled": 0 }
}
diff --git a/proxmox-auto-installer/tests/resources/parse_answer/disk_match_any.json b/proxmox-auto-installer/tests/resources/parse_answer/disk_match_any.json
index 1f3b2eb..ad3e304 100644
--- a/proxmox-auto-installer/tests/resources/parse_answer/disk_match_any.json
+++ b/proxmox-auto-installer/tests/resources/parse_answer/disk_match_any.json
@@ -30,5 +30,6 @@
"checksum": "on",
"compress": "on",
"copies": 1
- }
+ },
+ "first_boot": { "enabled": 0 }
}
diff --git a/proxmox-auto-installer/tests/resources/parse_answer/first-boot.json b/proxmox-auto-installer/tests/resources/parse_answer/first-boot.json
new file mode 100644
index 0000000..ff3f859
--- /dev/null
+++ b/proxmox-auto-installer/tests/resources/parse_answer/first-boot.json
@@ -0,0 +1,19 @@
+{
+ "autoreboot": 1,
+ "cidr": "192.168.1.114/24",
+ "country": "at",
+ "dns": "192.168.1.254",
+ "domain": "testinstall",
+ "filesys": "ext4",
+ "gateway": "192.168.1.1",
+ "hdsize": 223.57088470458984,
+ "existing_storage_auto_rename": 1,
+ "hostname": "pveauto",
+ "keymap": "de",
+ "mailto": "mail@no.invalid",
+ "mngmt_nic": "eno1",
+ "root_password": { "plain": "123456" },
+ "target_hd": "/dev/sda",
+ "timezone": "Europe/Vienna",
+ "first_boot": { "enabled": 1, "ordering_target": "network-pre" }
+}
diff --git a/proxmox-auto-installer/tests/resources/parse_answer/first-boot.toml b/proxmox-auto-installer/tests/resources/parse_answer/first-boot.toml
new file mode 100644
index 0000000..75c6a5d
--- /dev/null
+++ b/proxmox-auto-installer/tests/resources/parse_answer/first-boot.toml
@@ -0,0 +1,18 @@
+[global]
+keyboard = "de"
+country = "at"
+fqdn = "pveauto.testinstall"
+mailto = "mail@no.invalid"
+timezone = "Europe/Vienna"
+root_password = "123456"
+
+[first-boot]
+source = "from-iso"
+ordering = "before-network"
+
+[network]
+source = "from-dhcp"
+
+[disk-setup]
+filesystem = "ext4"
+disk_list = ["sda"]
diff --git a/proxmox-auto-installer/tests/resources/parse_answer/hashed_root_password.json b/proxmox-auto-installer/tests/resources/parse_answer/hashed_root_password.json
index 4cae547..4e049bd 100644
--- a/proxmox-auto-installer/tests/resources/parse_answer/hashed_root_password.json
+++ b/proxmox-auto-installer/tests/resources/parse_answer/hashed_root_password.json
@@ -16,5 +16,6 @@
"hashed": "$y$j9T$VgMv8lsz/TEvzesCZU3xD.$SK.h4QW51Jr/EmjuaTz5Bt4kYiX2Iezz6omzoqVEwj9"
},
"target_hd": "/dev/sda",
- "timezone": "Europe/Vienna"
+ "timezone": "Europe/Vienna",
+ "first_boot": { "enabled": 0 }
}
diff --git a/proxmox-auto-installer/tests/resources/parse_answer/minimal.json b/proxmox-auto-installer/tests/resources/parse_answer/minimal.json
index 9fe9150..62b45c9 100644
--- a/proxmox-auto-installer/tests/resources/parse_answer/minimal.json
+++ b/proxmox-auto-installer/tests/resources/parse_answer/minimal.json
@@ -14,5 +14,6 @@
"mngmt_nic": "eno1",
"root_password": { "plain": "123456" },
"target_hd": "/dev/sda",
- "timezone": "Europe/Vienna"
+ "timezone": "Europe/Vienna",
+ "first_boot": { "enabled": 0 }
}
diff --git a/proxmox-auto-installer/tests/resources/parse_answer/nic_matching.json b/proxmox-auto-installer/tests/resources/parse_answer/nic_matching.json
index 610060e..e8b5424 100644
--- a/proxmox-auto-installer/tests/resources/parse_answer/nic_matching.json
+++ b/proxmox-auto-installer/tests/resources/parse_answer/nic_matching.json
@@ -14,5 +14,6 @@
"mngmt_nic": "enp65s0f0",
"root_password": { "plain": "123456" },
"target_hd": "/dev/sda",
- "timezone": "Europe/Vienna"
+ "timezone": "Europe/Vienna",
+ "first_boot": { "enabled": 0 }
}
diff --git a/proxmox-auto-installer/tests/resources/parse_answer/specific_nic.json b/proxmox-auto-installer/tests/resources/parse_answer/specific_nic.json
index 5f456bb..a5a4e0b 100644
--- a/proxmox-auto-installer/tests/resources/parse_answer/specific_nic.json
+++ b/proxmox-auto-installer/tests/resources/parse_answer/specific_nic.json
@@ -14,5 +14,6 @@
"mngmt_nic": "enp129s0f1np1",
"root_password": { "plain": "123456" },
"target_hd": "/dev/sda",
- "timezone": "Europe/Vienna"
+ "timezone": "Europe/Vienna",
+ "first_boot": { "enabled": 0 }
}
diff --git a/proxmox-auto-installer/tests/resources/parse_answer/zfs.json b/proxmox-auto-installer/tests/resources/parse_answer/zfs.json
index 025dd8f..090b58d 100644
--- a/proxmox-auto-installer/tests/resources/parse_answer/zfs.json
+++ b/proxmox-auto-installer/tests/resources/parse_answer/zfs.json
@@ -24,5 +24,6 @@
"checksum": "on",
"compress": "lz4",
"copies": 2
- }
+ },
+ "first_boot": { "enabled": 0 }
}
diff --git a/proxmox-installer-common/src/setup.rs b/proxmox-installer-common/src/setup.rs
index 79b17ed..fefedf6 100644
--- a/proxmox-installer-common/src/setup.rs
+++ b/proxmox-installer-common/src/setup.rs
@@ -339,6 +339,13 @@ where
serializer.collect_str(value)
}
+fn serialize_bool_as_u32<S>(value: &bool, serializer: S) -> Result<S::Ok, S::Error>
+where
+ S: Serializer,
+{
+ serializer.serialize_u32(if *value { 1 } else { 0 })
+}
+
#[derive(Clone, Deserialize)]
pub struct RuntimeInfo {
/// Whether is system was booted in (legacy) BIOS or UEFI mode.
@@ -464,6 +471,14 @@ pub struct InstallRootPassword {
pub hashed: Option<String>,
}
+#[derive(Clone, Default, Deserialize, Serialize)]
+pub struct InstallFirstBootSetup {
+ #[serde(serialize_with = "serialize_bool_as_u32")]
+ pub enabled: bool,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub ordering_target: Option<String>,
+}
+
pub fn spawn_low_level_installer(test_mode: bool) -> io::Result<process::Child> {
let (path, args, envs): (&str, &[&str], Vec<(&str, &str)>) = if test_mode {
(
@@ -530,4 +545,6 @@ pub struct InstallConfig {
pub cidr: CidrAddress,
pub gateway: IpAddr,
pub dns: IpAddr,
+
+ pub first_boot: InstallFirstBootSetup,
}
diff --git a/proxmox-tui-installer/src/setup.rs b/proxmox-tui-installer/src/setup.rs
index 8146511..b2a3511 100644
--- a/proxmox-tui-installer/src/setup.rs
+++ b/proxmox-tui-installer/src/setup.rs
@@ -3,7 +3,7 @@ use std::collections::BTreeMap;
use crate::options::InstallerOptions;
use proxmox_installer_common::{
options::AdvancedBootdiskOptions,
- setup::{InstallConfig, InstallRootPassword},
+ setup::{InstallConfig, InstallFirstBootSetup, InstallRootPassword},
};
impl From<InstallerOptions> for InstallConfig {
@@ -44,6 +44,8 @@ impl From<InstallerOptions> for InstallConfig {
cidr: options.network.address,
gateway: options.network.gateway,
dns: options.network.dns_server,
+
+ first_boot: InstallFirstBootSetup::default(),
};
match &options.bootdisk.advanced {
--
2.47.0
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 7+ messages in thread
* [pve-devel] [PATCH installer v2 3/5] fix #5579: auto-install-assistant: enable baking in first-boot script
2024-11-18 12:38 [pve-devel] [PATCH installer v2 0/5] fix #5579: allow specifying optional first-boot script Christoph Heiss
2024-11-18 12:38 ` [pve-devel] [PATCH installer v2 1/5] fix #5579: first-boot: add initial service packaging Christoph Heiss
2024-11-18 12:38 ` [pve-devel] [PATCH installer v2 2/5] fix #5579: setup: introduce 'first_boot' low-level installer options Christoph Heiss
@ 2024-11-18 12:38 ` Christoph Heiss
2024-11-18 12:38 ` [pve-devel] [PATCH installer v2 4/5] fix #5579: auto-installer: add optional first-boot hook script Christoph Heiss
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Christoph Heiss @ 2024-11-18 12:38 UTC (permalink / raw)
To: pve-devel
Adds a new parameter `--on-first-boot` to the `prepare-iso` command, to
specify a file to bake into the ISO.
To later use it with the auto-installer, the following must be set in
the answer file:
[first-boot]
source = "from-iso"
Signed-off-by: Christoph Heiss <c.heiss@proxmox.com>
---
Changes v1 -> v2:
* add filesize check; only allow up to 1 MiB scripts
proxmox-auto-install-assistant/Cargo.toml | 1 +
proxmox-auto-install-assistant/src/main.rs | 30 +++++++++++++++++++++-
proxmox-installer-common/src/lib.rs | 6 +++++
3 files changed, 36 insertions(+), 1 deletion(-)
diff --git a/proxmox-auto-install-assistant/Cargo.toml b/proxmox-auto-install-assistant/Cargo.toml
index c4486f8..07e6ffb 100644
--- a/proxmox-auto-install-assistant/Cargo.toml
+++ b/proxmox-auto-install-assistant/Cargo.toml
@@ -13,6 +13,7 @@ homepage = "https://www.proxmox.com"
[dependencies]
anyhow.workspace = true
log.workspace = true
+proxmox-installer-common.workspace = true
proxmox-auto-installer.workspace = true
serde = { workspace = true, features = ["derive"] }
serde_json.workspace = true
diff --git a/proxmox-auto-install-assistant/src/main.rs b/proxmox-auto-install-assistant/src/main.rs
index bdcf067..d7aa134 100644
--- a/proxmox-auto-install-assistant/src/main.rs
+++ b/proxmox-auto-install-assistant/src/main.rs
@@ -19,6 +19,7 @@ use proxmox_auto_installer::{
FetchAnswerFrom, HttpOptions,
},
};
+use proxmox_installer_common::{FIRST_BOOT_EXEC_MAX_SIZE, FIRST_BOOT_EXEC_NAME};
static PROXMOX_ISO_FLAG: &str = "/auto-installer-capable";
@@ -149,6 +150,13 @@ struct CommandPrepareISO {
// so shorten "Automated Installer Source" to "AIS" to be safe.
#[arg(long, default_value_t = { "proxmox-ais".to_owned() } )]
partition_label: String,
+
+ /// Executable file to include, which should be run on the first system boot after the
+ /// installation. Can be used for further bootstrapping the new system.
+ ///
+ /// Must be appropriately enabled in the answer file.
+ #[arg(long)]
+ on_first_boot: Option<PathBuf>,
}
/// Show the system information that can be used to identify a host.
@@ -201,7 +209,7 @@ fn main() {
Commands::SystemInfo(args) => show_system_info(args),
};
if let Err(err) = res {
- eprintln!("{err}");
+ eprintln!("Error: {err:?}");
std::process::exit(1);
}
}
@@ -305,6 +313,17 @@ fn prepare_iso(args: &CommandPrepareISO) -> Result<()> {
bail!("You must set '--fetch-from' to 'iso' to place the answer file directly in the ISO.");
}
+ if let Some(first_boot) = &args.on_first_boot {
+ let metadata = fs::metadata(first_boot)?;
+
+ if metadata.len() > FIRST_BOOT_EXEC_MAX_SIZE.try_into()? {
+ bail!(
+ "Maximum file size for first-boot executable file is {} MiB",
+ FIRST_BOOT_EXEC_MAX_SIZE / 1024 / 1024
+ )
+ }
+ }
+
if let Some(file) = &args.answer_file {
println!("Checking provided answer file...");
parse_answer(file)?;
@@ -352,6 +371,15 @@ fn prepare_iso(args: &CommandPrepareISO) -> Result<()> {
inject_file_to_iso(&tmp_iso, answer_file, "/answer.toml", &uuid)?;
}
+ if let Some(first_boot) = &args.on_first_boot {
+ inject_file_to_iso(
+ &tmp_iso,
+ first_boot,
+ &format!("/{FIRST_BOOT_EXEC_NAME}"),
+ &uuid,
+ )?;
+ }
+
println!("Moving prepared ISO to target location...");
fs::rename(&tmp_iso, &iso_target)?;
println!("Final ISO is available at {iso_target:?}.");
diff --git a/proxmox-installer-common/src/lib.rs b/proxmox-installer-common/src/lib.rs
index 10b5940..13acb89 100644
--- a/proxmox-installer-common/src/lib.rs
+++ b/proxmox-installer-common/src/lib.rs
@@ -11,3 +11,9 @@ pub const RUNTIME_DIR: &str = "/run/proxmox-installer";
/// Default placeholder value for the administrator email address.
pub const EMAIL_DEFAULT_PLACEHOLDER: &str = "mail@example.invalid";
+
+/// Name of the executable for the first-boot hook.
+pub const FIRST_BOOT_EXEC_NAME: &str = "proxmox-first-boot";
+
+/// Maximum file size for the first-boot hook executable.
+pub const FIRST_BOOT_EXEC_MAX_SIZE: usize = 1024 * 1024; // 1 MiB
--
2.47.0
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 7+ messages in thread
* [pve-devel] [PATCH installer v2 4/5] fix #5579: auto-installer: add optional first-boot hook script
2024-11-18 12:38 [pve-devel] [PATCH installer v2 0/5] fix #5579: allow specifying optional first-boot script Christoph Heiss
` (2 preceding siblings ...)
2024-11-18 12:38 ` [pve-devel] [PATCH installer v2 3/5] fix #5579: auto-install-assistant: enable baking in first-boot script Christoph Heiss
@ 2024-11-18 12:38 ` Christoph Heiss
2024-11-18 12:38 ` [pve-devel] [PATCH installer v2 5/5] fix #5579: install: setup proxmox-first-boot service if enabled Christoph Heiss
2024-11-18 21:35 ` [pve-devel] applied: [PATCH installer v2 0/5] fix #5579: allow specifying optional first-boot script Thomas Lamprecht
5 siblings, 0 replies; 7+ messages in thread
From: Christoph Heiss @ 2024-11-18 12:38 UTC (permalink / raw)
To: pve-devel
Users can specifying an optional file - either fetched from an URL or
backed into the ISO - to execute on the first boot after the
installation, using the 'proxmox-first-boot' oneshot service.
Essentially adds an (optional) `[first-boot]` section to the answer
file. If specified, the `source` key must be at least set, which gives
the location of the hook script.
Signed-off-by: Christoph Heiss <c.heiss@proxmox.com>
---
Changes v1 -> v2:
* adapt to new low-level format
* add settable ordering of service
proxmox-auto-installer/Cargo.toml | 2 +-
proxmox-auto-installer/src/answer.rs | 59 +++++++++++++++++++
.../src/bin/proxmox-auto-installer.rs | 49 +++++++++++++--
proxmox-auto-installer/src/utils.rs | 22 ++++++-
4 files changed, 126 insertions(+), 6 deletions(-)
diff --git a/proxmox-auto-installer/Cargo.toml b/proxmox-auto-installer/Cargo.toml
index 21ed538..7e3d90c 100644
--- a/proxmox-auto-installer/Cargo.toml
+++ b/proxmox-auto-installer/Cargo.toml
@@ -13,7 +13,7 @@ homepage = "https://www.proxmox.com"
[dependencies]
anyhow.workspace = true
log.workspace = true
-proxmox-installer-common.workspace = true
+proxmox-installer-common = { workspace = true, features = ["http"] }
serde = { workspace = true, features = ["derive"] }
serde_json.workspace = true
serde_plain.workspace = true
diff --git a/proxmox-auto-installer/src/answer.rs b/proxmox-auto-installer/src/answer.rs
index 73e5869..c206fcc 100644
--- a/proxmox-auto-installer/src/answer.rs
+++ b/proxmox-auto-installer/src/answer.rs
@@ -22,6 +22,8 @@ pub struct Answer {
pub disks: Disks,
#[serde(default)]
pub post_installation_webhook: Option<PostNotificationHookInfo>,
+ #[serde(default)]
+ pub first_boot: Option<FirstBootHookInfo>,
}
impl Answer {
@@ -62,6 +64,63 @@ pub struct PostNotificationHookInfo {
pub cert_fingerprint: Option<String>,
}
+/// Possible sources for the optional first-boot hook script/executable file.
+#[derive(Clone, Deserialize, Debug, PartialEq)]
+#[serde(rename_all = "kebab-case", deny_unknown_fields)]
+pub enum FirstBootHookSourceMode {
+ /// Fetch the executable file from an URL, specified in the parent.
+ FromUrl,
+ /// The executable file has been baked into the ISO at a known location,
+ /// and should be retrieved from there.
+ FromIso,
+}
+
+/// Possible orderings for the `proxmox-first-boot` systemd service.
+///
+/// Determines the final value of `Unit.Before` and `Unit.Wants` in the service
+/// file.
+// Must be kept in sync with Proxmox::Install::Config and the service files in the
+// proxmox-first-boot package.
+#[derive(Clone, Default, Deserialize, Debug, PartialEq)]
+#[serde(rename_all = "kebab-case", deny_unknown_fields)]
+pub enum FirstBootHookServiceOrdering {
+ /// Needed for bringing up the network itself, runs before any networking is attempted.
+ BeforeNetwork,
+ /// Network needs to be already online, runs after networking was brought up.
+ NetworkOnline,
+ /// Runs after the system has successfully booted up completely.
+ #[default]
+ FullyUp,
+}
+
+impl FirstBootHookServiceOrdering {
+ /// Maps the enum to the appropriate systemd target name, without the '.target' suffix.
+ pub fn as_systemd_target_name(&self) -> &str {
+ match self {
+ FirstBootHookServiceOrdering::BeforeNetwork => "network-pre",
+ FirstBootHookServiceOrdering::NetworkOnline => "network-online",
+ FirstBootHookServiceOrdering::FullyUp => "multi-user",
+ }
+ }
+}
+
+/// Describes from where to fetch the first-boot hook script, either being baked into the ISO or
+/// from a URL.
+#[derive(Clone, Deserialize, Debug)]
+#[serde(rename_all = "kebab-case", deny_unknown_fields)]
+pub struct FirstBootHookInfo {
+ /// Mode how to retrieve the first-boot executable file, either from an URL or from the ISO if
+ /// it has been baked-in.
+ pub source: FirstBootHookSourceMode,
+ /// Determines the service order when the hook will run on first boot.
+ #[serde(default)]
+ pub ordering: FirstBootHookServiceOrdering,
+ /// Retrieve the post-install script from a URL, if source == "from-url".
+ pub url: Option<String>,
+ /// SHA256 cert fingerprint if certificate pinning should be used, if source == "from-url".
+ pub cert_fingerprint: Option<String>,
+}
+
#[derive(Clone, Deserialize, Debug, Default, PartialEq)]
#[serde(deny_unknown_fields)]
enum NetworkConfigMode {
diff --git a/proxmox-auto-installer/src/bin/proxmox-auto-installer.rs b/proxmox-auto-installer/src/bin/proxmox-auto-installer.rs
index ea45c29..4b9d73d 100644
--- a/proxmox-auto-installer/src/bin/proxmox-auto-installer.rs
+++ b/proxmox-auto-installer/src/bin/proxmox-auto-installer.rs
@@ -1,18 +1,22 @@
use anyhow::{bail, format_err, Result};
use log::{error, info, LevelFilter};
use std::{
- env,
+ env, fs,
io::{BufRead, BufReader, Write},
path::PathBuf,
process::ExitCode,
};
-use proxmox_installer_common::setup::{
- installer_setup, read_json, spawn_low_level_installer, LocaleInfo, RuntimeInfo, SetupInfo,
+use proxmox_installer_common::{
+ http,
+ setup::{
+ installer_setup, read_json, spawn_low_level_installer, LocaleInfo, RuntimeInfo, SetupInfo,
+ },
+ FIRST_BOOT_EXEC_MAX_SIZE, FIRST_BOOT_EXEC_NAME, RUNTIME_DIR,
};
use proxmox_auto_installer::{
- answer::Answer,
+ answer::{Answer, FirstBootHookInfo, FirstBootHookSourceMode},
log::AutoInstLogger,
udevinfo::UdevInfo,
utils::{parse_answer, LowLevelMessage},
@@ -27,6 +31,38 @@ pub fn init_log() -> Result<()> {
.map_err(|err| format_err!(err))
}
+fn setup_first_boot_executable(first_boot: &FirstBootHookInfo) -> Result<()> {
+ let content = match first_boot.source {
+ FirstBootHookSourceMode::FromUrl => {
+ if let Some(url) = &first_boot.url {
+ info!("Fetching first-boot hook from {url} ..");
+ Some(http::get(url, first_boot.cert_fingerprint.as_deref())?)
+ } else {
+ bail!("first-boot hook source set to URL, but none specified!");
+ }
+ }
+ FirstBootHookSourceMode::FromIso => Some(fs::read_to_string(format!(
+ "/cdrom/{FIRST_BOOT_EXEC_NAME}"
+ ))?),
+ };
+
+ if let Some(content) = content {
+ if content.len() > FIRST_BOOT_EXEC_MAX_SIZE {
+ bail!(
+ "Maximum file size for first-boot executable file is {} MiB",
+ FIRST_BOOT_EXEC_MAX_SIZE / 1024 / 1024
+ )
+ }
+
+ Ok(fs::write(
+ format!("/{RUNTIME_DIR}/{FIRST_BOOT_EXEC_NAME}"),
+ content,
+ )?)
+ } else {
+ Ok(())
+ }
+}
+
fn auto_installer_setup(in_test_mode: bool) -> Result<(Answer, UdevInfo)> {
let base_path = if in_test_mode { "./testdir" } else { "/" };
let mut path = PathBuf::from(base_path);
@@ -43,6 +79,11 @@ fn auto_installer_setup(in_test_mode: bool) -> Result<(Answer, UdevInfo)> {
};
let answer = Answer::try_from_reader(std::io::stdin().lock())?;
+
+ if let Some(first_boot) = &answer.first_boot {
+ setup_first_boot_executable(first_boot)?;
+ }
+
Ok((answer, udev_info))
}
diff --git a/proxmox-auto-installer/src/utils.rs b/proxmox-auto-installer/src/utils.rs
index 9c399a5..ea7176a 100644
--- a/proxmox-auto-installer/src/utils.rs
+++ b/proxmox-auto-installer/src/utils.rs
@@ -5,7 +5,7 @@ use log::info;
use std::{collections::BTreeMap, process::Command};
use crate::{
- answer::{self, Answer},
+ answer::{self, Answer, FirstBootHookSourceMode},
udevinfo::UdevInfo,
};
use proxmox_installer_common::{
@@ -325,6 +325,18 @@ fn verify_email_and_root_password_settings(answer: &Answer) -> Result<()> {
}
}
+fn verify_first_boot_settings(answer: &Answer) -> Result<()> {
+ info!("Verifying first boot settings");
+
+ if let Some(first_boot) = &answer.first_boot {
+ if first_boot.source == FirstBootHookSourceMode::FromUrl && first_boot.url.is_none() {
+ bail!("first-boot executable source set to URL, but none specified!");
+ }
+ }
+
+ Ok(())
+}
+
pub fn parse_answer(
answer: &Answer,
udev_info: &UdevInfo,
@@ -341,6 +353,7 @@ pub fn parse_answer(
verify_locale_settings(answer, locales)?;
verify_email_and_root_password_settings(answer)?;
+ verify_first_boot_settings(answer)?;
let mut config = InstallConfig {
autoreboot: 1_usize,
@@ -419,6 +432,13 @@ pub fn parse_answer(
})
}
}
+
+ if let Some(first_boot) = &answer.first_boot {
+ config.first_boot.enabled = true;
+ config.first_boot.ordering_target =
+ Some(first_boot.ordering.as_systemd_target_name().to_owned());
+ }
+
Ok(config)
}
--
2.47.0
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 7+ messages in thread
* [pve-devel] [PATCH installer v2 5/5] fix #5579: install: setup proxmox-first-boot service if enabled
2024-11-18 12:38 [pve-devel] [PATCH installer v2 0/5] fix #5579: allow specifying optional first-boot script Christoph Heiss
` (3 preceding siblings ...)
2024-11-18 12:38 ` [pve-devel] [PATCH installer v2 4/5] fix #5579: auto-installer: add optional first-boot hook script Christoph Heiss
@ 2024-11-18 12:38 ` Christoph Heiss
2024-11-18 21:35 ` [pve-devel] applied: [PATCH installer v2 0/5] fix #5579: allow specifying optional first-boot script Thomas Lamprecht
5 siblings, 0 replies; 7+ messages in thread
From: Christoph Heiss @ 2024-11-18 12:38 UTC (permalink / raw)
To: pve-devel
The auto-installer will place an executable file named
`proxmox-first-boot` in the installer runtime-directory if the user set
up.
Signed-off-by: Christoph Heiss <c.heiss@proxmox.com>
---
Changes v1 -> v2:
* factor out of extract_data()
* implement enabling correct service depending on set order
Proxmox/Install.pm | 55 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 54 insertions(+), 1 deletion(-)
diff --git a/Proxmox/Install.pm b/Proxmox/Install.pm
index d409577..c64e1d4 100644
--- a/Proxmox/Install.pm
+++ b/Proxmox/Install.pm
@@ -15,7 +15,7 @@ use Proxmox::Install::StorageConfig;
use Proxmox::Sys::Block qw(get_cached_disks wipe_disk partition_bootable_disk);
use Proxmox::Sys::Command qw(run_command syscmd);
-use Proxmox::Sys::File qw(file_read_firstline file_write_all);
+use Proxmox::Sys::File qw(file_read_firstline file_read_all file_write_all);
use Proxmox::Sys::ZFS;
use Proxmox::UI;
@@ -678,6 +678,55 @@ my sub setup_root_password {
}
}
+my sub setup_proxmox_first_boot_service {
+ my ($targetdir) = @_;
+
+ return if !Proxmox::Install::Config::get_first_boot_opt('enabled');
+
+ my $iso_env = Proxmox::Install::ISOEnv::get();
+ my $proxmox_rundir = $iso_env->{locations}->{run};
+
+ my $exec_name = 'proxmox-first-boot';
+ my $pending_flagfile = "pending-first-boot-setup";
+ my $targetpath = "$targetdir/var/lib/proxmox-first-boot";
+
+ die "cannot find proxmox-first-boot hook executable?\n"
+ if ! -f "$proxmox_rundir/$exec_name";
+
+ # Create /var/lib/proxmox-first-boot state directory
+ syscmd("mkdir -p $targetpath/") == 0
+ || die "failed to create $targetpath directory\n";
+
+ syscmd("cp $proxmox_rundir/$exec_name $targetpath/") == 0
+ || die "unable to copy $exec_name executable\n";
+ syscmd("touch $targetpath/$pending_flagfile") == 0
+ || die "unable to create $pending_flagfile flag file\n";
+
+ # Explicitly mark the entire directory only accessible, to prevent
+ # possible secret leaks from the bootstrap script.
+ syscmd("chmod -R 0700 $targetpath") == 0
+ || warn "failed to set permissions for $targetpath\n";
+
+ # Enable the correct unit according the requested target ordering
+ my $ordering = Proxmox::Install::Config::get_first_boot_opt('ordering_target');
+
+ # .. so do it ourselves
+ my $linktarget = "/lib/systemd/system/proxmox-first-boot-$ordering.service";
+ syscmd("ln -sf $linktarget $targetdir/etc/systemd/system/proxmox-first-boot.service") == 0
+ || die "failed to link proxmox-first-boot-$ordering.service\n";
+
+ my $servicefile = file_read_all("$targetdir/$linktarget");
+ if ($servicefile =~ m/^WantedBy=(.+)$/m) {
+ my $wantedby = $1;
+
+ syscmd("mkdir -p $targetdir/etc/systemd/system/$wantedby.wants") == 0
+ || die "failed to create $wantedby.wants directory\n";
+
+ syscmd("ln -sf $linktarget $targetdir/etc/systemd/system/$wantedby.wants/proxmox-first-boot-$ordering.service") == 0
+ || die "failed to link $wantedby.wants/proxmox-first-boot-$ordering.service\n";
+ }
+}
+
sub extract_data {
my $iso_env = Proxmox::Install::ISOEnv::get();
my $run_env = Proxmox::Install::RunEnv::get();
@@ -1171,6 +1220,7 @@ _EOD
next if ($deb =~ /grub-efi-amd64_/ && $run_env->{boot_type} ne 'efi');
next if ($deb =~ /^proxmox-grub/ && $run_env->{boot_type} ne 'efi');
next if ($deb =~ /^proxmox-secure-boot-support_/ && !$run_env->{secure_boot});
+ next if ($deb =~ /^proxmox-first-boot/ && !Proxmox::Install::Config::get_first_boot_opt('enabled'));
update_progress($count/$pkg_count, 0.5, 0.75, "extracting $deb");
@@ -1251,6 +1301,9 @@ _EOD
my $ask_for_patience = "";
$ask_for_patience = " (multiple disks detected, please be patient)" if $diskcount > 3;
update_progress(0.8, 0.95, 1, "make system bootable$ask_for_patience");
+
+ setup_proxmox_first_boot_service($targetdir);
+
my $target_cmdline='';
if ($target_cmdline = Proxmox::Install::Config::get_target_cmdline()) {
my $target_cmdline_snippet = '';
--
2.47.0
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 7+ messages in thread
* [pve-devel] applied: [PATCH installer v2 0/5] fix #5579: allow specifying optional first-boot script
2024-11-18 12:38 [pve-devel] [PATCH installer v2 0/5] fix #5579: allow specifying optional first-boot script Christoph Heiss
` (4 preceding siblings ...)
2024-11-18 12:38 ` [pve-devel] [PATCH installer v2 5/5] fix #5579: install: setup proxmox-first-boot service if enabled Christoph Heiss
@ 2024-11-18 21:35 ` Thomas Lamprecht
5 siblings, 0 replies; 7+ messages in thread
From: Thomas Lamprecht @ 2024-11-18 21:35 UTC (permalink / raw)
To: Proxmox VE development discussion, Christoph Heiss
Am 18.11.24 um 13:38 schrieb Christoph Heiss:
> This implements #5579 [0] as proposed by Thomas [1].
>
> Adds a new (optional) section to the auto-installer answer file called
> `first-boot`, which can be used to the configure a script/executable
> file to run on the first boot after the installation.
>
> To used the baked-in (via the `proxmox-auto-install-assistant prepare-iso
> --on-first-boot`) file from the ISO:
>
> [first-boot]
> source = "from-iso"
>
> Or fetching it from a URL:
>
> [first-boot]
> source = "from-url"
> url = "http://example.com/first-boot"
> cert_fingerprint = ".." # if needed
>
> Optionally, a ordering can be specified, when to run the script:
>
> [first-boot]
> source = "from-url"
> ordering = "fully-up" # default value
> # one of "before-network", "network-online" or "fully-up"
>
> The structure the section is mostly taken from the `network` section to
> provide consistency.
>
> [0] https://bugzilla.proxmox.com/show_bug.cgi?id=5579
> [1] https://bugzilla.proxmox.com/show_bug.cgi?id=5579#c5
>
Looks all right to me, nice work! Would be great if you could add that new feature
to our auto-installer docs.
> Diffstat
> ========
>
> Christoph Heiss (5):
> fix #5579: first-boot: add initial service packaging
> fix #5579: setup: introduce 'first_boot' low-level installer options
> fix #5579: auto-install-assistant: enable baking in first-boot script
> fix #5579: auto-installer: add optional first-boot hook script
> fix #5579: install: setup proxmox-first-boot service if enabled
applied, thanks!
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 7+ messages in thread