diff --git a/autoinstallation/README.md b/autoinstallation/README.md index 3d283357d1..5430b05a5d 100644 --- a/autoinstallation/README.md +++ b/autoinstallation/README.md @@ -76,7 +76,9 @@ running. For such use cases, Agama injects the hardware information into the pro using Jsonnet. In the following example, the profile is adapted to install the system on the biggest disk on the -system. The hardware information (from `lshw`) is available as a JSON object in the `hw.libsonnet`. +system. It also selects product based on amount of available RAM memory. The hardware information +(from `lshw`) is available as a JSON object in the `hw.libsonnet`. +There is also a set of helpers as part of hw. For documentation of those helpers see agama.libsonnet file. ```jsonnet local agama = import 'hw.libsonnet'; @@ -84,10 +86,11 @@ local findBiggestDisk(disks) = local sizedDisks = std.filter(function(d) std.objectHas(d, 'size'), disks); local sorted = std.sort(sizedDisks, function(x) x.size); sorted[0].logicalname; +local memory = agama.findByID(agama.lshw, 'memory').size; { software: { - product: 'ALP-Dolomite', + product: if memory < 8000000000 then 'MicroOS' else 'Tumbleweed', }, root: { password: 'nots3cr3t', @@ -97,13 +100,13 @@ local findBiggestDisk(disks) = language: 'en_US', }, storage: { - bootDevice: findBiggestDisk(agama.disks), + bootDevice: findBiggestDisk(agama.selectByClass(agama.lshw, 'disk')), }, } ``` -**:warning: At this point, only the storage information is injected. You can inspect the available -data by installing the `lshw` package and running the following command: `lshw -json -class disk`.** +**You can inspect the available +data by installing the `lshw` package and running the following command: `lshw -json`.** ### Validating and evaluating a profile diff --git a/rust/agama-lib/src/profile.rs b/rust/agama-lib/src/profile.rs index 8645fbc89a..ccc1da71f1 100644 --- a/rust/agama-lib/src/profile.rs +++ b/rust/agama-lib/src/profile.rs @@ -156,17 +156,22 @@ impl ProfileEvaluator { Ok(()) } - // Write the hardware information in JSON format to a given path + // Write the hardware information in JSON format to a given path and also helpers to help with it // // TODO: we need a better way to generate this information, as lshw and hwinfo are not usable // out of the box. fn write_hwinfo(&self, path: &Path) -> anyhow::Result<()> { let result = Command::new("/usr/sbin/lshw") - .args(["-json", "-class", "disk"]) + .args(["-json"]) .output() .context("Failed to run lshw")?; + let helpers = fs::read_to_string("agama.libsonnet") + .or_else(|_| fs::read_to_string("/usr/share/agama-cli/agama.libsonnet")) + .context("Failed to read agama.libsonnet")?; let mut file = fs::File::create(path)?; - file.write_all(b"{ \"disks\":\n")?; + file.write_all(b"{\n")?; + file.write_all(helpers.as_bytes())?; + file.write_all(b"\n\"lshw\":\n")?; file.write_all(&result.stdout)?; file.write_all(b"\n}")?; Ok(()) diff --git a/rust/package/agama.changes b/rust/package/agama.changes index 19f9f29e81..1da2d2f86c 100644 --- a/rust/package/agama.changes +++ b/rust/package/agama.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Wed May 22 12:31:25 UTC 2024 - Josef Reidinger + +- autoinstallation jsonnet: Inject complete lshw json output and + provide helper functions for filtering it (gh#openSUSE/agama#1242) + ------------------------------------------------------------------- Fri May 17 09:52:25 UTC 2024 - Imobach Gonzalez Sosa @@ -6,8 +12,8 @@ Fri May 17 09:52:25 UTC 2024 - Imobach Gonzalez Sosa ------------------------------------------------------------------- Tue May 16 12:48:42 UTC 2024 - Knut Anderssen -- Allow to download Agama los throgh the manager HTTP API - (gh#openSUSE/1216). +- Allow to download Agama logs through the manager HTTP API + (gh#openSUSE/agama#1216). ------------------------------------------------------------------- Thu May 16 12:34:43 UTC 2024 - Imobach Gonzalez Sosa diff --git a/rust/package/agama.spec b/rust/package/agama.spec index 828eb5095a..ccc83eefc9 100644 --- a/rust/package/agama.spec +++ b/rust/package/agama.spec @@ -89,6 +89,7 @@ install -m 0755 %{_builddir}/agama/target/release/agama-web-server %{buildroot}% install -D -p -m 644 %{_builddir}/agama/share/agama.pam $RPM_BUILD_ROOT%{_pam_vendordir}/agama install -D -d -m 0755 %{buildroot}%{_datadir}/agama-cli install -m 0644 %{_builddir}/agama/agama-lib/share/profile.schema.json %{buildroot}%{_datadir}/agama-cli +install -m 0644 %{_builddir}/agama/share/agama.libsonnet %{buildroot}%{_datadir}/agama-cli install --directory %{buildroot}%{_datadir}/dbus-1/agama-services install -m 0644 --target-directory=%{buildroot}%{_datadir}/dbus-1/agama-services %{_builddir}/agama/share/org.opensuse.Agama1.service install -D -m 0644 %{_builddir}/agama/share/agama-web-server.service %{buildroot}%{_unitdir}/agama-web-server.service diff --git a/rust/share/agama.libsonnet b/rust/share/agama.libsonnet new file mode 100644 index 0000000000..081c1d2b45 --- /dev/null +++ b/rust/share/agama.libsonnet @@ -0,0 +1,32 @@ +// function go throught lshw output and enlist only given class. +// Basically it is same as calling `lshw -class `. +// @param lshw: Object with content of `lshw -json` +// @param class: String with class identifier as can be found in "class" element of lshw +// @return Array of objects with given class +selectByClass(lshw, class):: + local selectClass_(parent, class) = + if std.objectHas(parent, 'class') && parent.class == class then + [ parent ] + else if std.objectHas(parent, 'children') then + std.flattenArrays(std.prune(std.map(function(x) selectClass_(x, class), parent.children ))) + else + []; + + local result = selectClass_(lshw, class); + result, + +// function go throught lshw output and returns object with given "id" or null if not found. +// @param lshw: Object with content of `lshw -json` +// @param id: String with identifier as can be found in "id" element of lshw +// @return Object with given id or null +findByID(lshw, id):: + local findID_(parent, id) = + if std.objectHas(parent, 'id') && parent.id == id then + [parent] + else if std.objectHas(parent, 'children') then + std.flattenArrays(std.prune(std.map(function(x) findID_(x, id), parent.children ))) + else + null; + + local result = findID_(lshw, id); + if std.length(result) > 0 then result[0] else null,