Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
e78f3ce
docs: describe the 'files' section
imobachgs May 23, 2025
22b1915
docs: describe the 'bootloader' section
imobachgs May 28, 2025
5ef7ad6
docs: describe the 'hostname' section
imobachgs May 28, 2025
befba01
docs: describe the 'localization' section
imobachgs May 28, 2025
73097e6
docs: describe the 'product' section
imobachgs May 28, 2025
2882511
docs: describe the 'security' section
imobachgs May 28, 2025
8731ec0
docs: describe the 'software' section
imobachgs May 28, 2025
67f4a5e
docs: describe the 'network' section
imobachgs May 28, 2025
a56abc2
docs: move profiles docs to profiles/
imobachgs Jun 2, 2025
a9188b9
docs: move AutoYaST section to "Unattended installation"
imobachgs Jun 2, 2025
58bf760
docs: extract profiles handling to a "Working with profiles" section
imobachgs Jun 2, 2025
4b96fba
docs: add a section about dynamic profiles
imobachgs Jun 2, 2025
3cf04be
docs: rewrite the overview of "Unattended installation"
imobachgs Jun 2, 2025
bf5bcd7
fix: fix broken links
imobachgs Jun 2, 2025
b5e231f
docs: describe missing network elements
imobachgs Jun 3, 2025
af25bf5
chore: minor fixes and formatting
imobachgs Jun 3, 2025
c7b6b8a
docs: clarify how relative URLs are processed
imobachgs Jun 3, 2025
6148d3a
fix: fix broken links
imobachgs Jun 3, 2025
c18e178
fix: fixes from the review
imobachgs Jun 3, 2025
281807f
fix: typo
imobachgs Jun 4, 2025
0c0b2f4
try to extend documentation with extraRepositories
jreidinger Jun 9, 2025
05b49a7
Change test deploy to run it without limiting to main
jreidinger Jun 10, 2025
50bc5b7
changes from review
jreidinger Jun 10, 2025
80244c2
consistent formatting
jreidinger Jun 10, 2025
79bcbe5
Merge pull request #85 from agama-project/extraRepositories
imobachgs Jun 10, 2025
f2c2f28
Merge branch 'main' into unattended
imobachgs Jun 11, 2025
c6e17de
Apply suggestions from code review
imobachgs Jun 11, 2025
25c6928
docs: updates from review
imobachgs Jun 11, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .github/workflows/test-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ name: Test deployment

on:
pull_request:
branches:
- main
# Review gh actions docs if you want to further define triggers, paths, etc
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#on

Expand Down
2 changes: 1 addition & 1 deletion blog/2025-02-27-releasing-version-12-and-a-roadmap.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ that are considered to be out of its scope even for the future.
The report can be disabled by specifying `agama.ay_check=0` as a boot parameter.

We also took the opportunity to update the corresponding information at the [AutoYaST compatibility
reference document](/docs/user/autoyast/reference). What is even better, we introduced some
reference document](/docs/user/unattended/autoyast/reference). What is even better, we introduced some
mechanisms to generate such a document based on the same information used by Agama to generate the
compatibility report during execution, so we can make sure the documentation is in sync with the
actual implementation.
Expand Down
2 changes: 1 addition & 1 deletion blog/2025-04-08-agama-13.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ automatically search for it in the same pre-defined locations used by AutoYaST.
Agama expects a file named `autoinst.jsonnet`, `autoinst.json` or `autoinst.xml` (in that
order) to be located on:

- The root of a file system named `OEMDRV`.
- The root of a file system with the label `OEMDRV`.
- Or the root (`/`) of the installation environment.

The first file found is used as the profile, starting the installation right away.
Expand Down
5 changes: 2 additions & 3 deletions docs/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,11 @@ But there are also some caveats. Bear in mind that Agama is focused on the insta
further configuration to other tools. Therefore it includes less features and there are some
sections you can find in an AutoYaST profile that are ignored by Agama.

You can find further details in the [AutoYaST support section](/docs/user/autoyast).
You can find further details in the [AutoYaST support section](/docs/user/unattended/autoyast).

## Will Agama replace YaST as the main installer for SUSE Linux?

Although nothing is set in stone, that is the plan for SUSE Linux Enterprise Server 16.
Although nothing is set in stone, that is the plan for SUSE Linux Enterprise Server 16.

## Will Agama replace YaST as the main installer for openSUSE distributions?

Expand All @@ -93,4 +93,3 @@ There are no concrete plans in that regard.
The YaST Team works in close collaboration with several openSUSE contributors to make sure Agama can
install openSUSE Tumbleweed, openSUSE MicroOS and the first prototypes of Leap 16.0. But there is
no concrete roadmap for the adoption of Agama as an endorsed installer for those distributions.

4 changes: 2 additions & 2 deletions docs/user/interactive/storage.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ developed.
Every change to any of the configuration options will result in an immediate re-calculation of the
section that presents the result. As already mentioned, the configuration options are identical to
the case of unattended installation (see detailed description at the [corresponding
section](../unattended/storage.md)), although the user interface presents more clearly the
section](../unattended/profile/storage)), although the user interface presents more clearly the
relationship between those settings and the system being used for installation.

![Selecting a device for installation](/img/user/storage-device.png)
Expand All @@ -67,7 +67,7 @@ storage configuration. For example, there is not support yet for representing RA
If a given configuration is not manageable by the web interface, then the storage section shows a
message explaining the situation and offers to reset to the default settings. Such an alert is
always shown if the loaded configuration uses [the legacy AutoYaST
mode](../unattended/storage#unattended-installation-using-the-legacy-autoyast-mode).
mode](../unattended/profile/storage#unattended-installation-using-the-legacy-autoyast-mode).
:::

There are several interactive elements allowing to control several aspects of the installation.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
sidebar_position: 3
sidebar_position: 4
---

# AutoYaST support
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Loading an AutoYaST profile

The typical way of starting an unattended installation in Agama is by passing the URL of an AutoYaST
profile through the [`inst.auto`](../boot_options/index.md#boot-options) argument in the kernel's
command-line[^agama-profile-import]. For example:
profile through the [`inst.auto`](/docs/user/boot_options) argument in the kernel's
command-line[^agama-config-load]. For example:

```text
inst.auto=http://example.net/agama/tumbleweed.xml
Expand All @@ -27,4 +27,4 @@ this pre-processing, it supports handling of [dynamic profiles][dynamic-profiles
[ask-list-runner]: https://github.com/yast/yast-autoinstallation/blob/c2dc34560df4ba890688a0c84caec94cc2718f14/src/lib/autoinstall/ask/runner.rb#L50
[ask-list-dialog]: https://github.com/yast/yast-autoinstallation/blob/c2dc34560df4ba890688a0c84caec94cc2718f14/src/lib/autoinstall/ask/dialog.rb#L23

[^agama-profile-import]: You can use the `agama profile import` command, but that's out of the scope of this document.
[^agama-config-load]: You can use the `agama config load` command, but that's out of the scope of this document. Check the [Working with profiles](/docs/user/unattended/working-with-profiles) section.
70 changes: 70 additions & 0 deletions docs/user/unattended/dynamic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
---
sidebar_position: 3
---

# Writing a dynamic profile

It is not unusual that you need to write a profile that adapts dynamically to the underlying system.
For instance, you might want Agama to take some decisions depending on the hardware of the system
you are installing.

Fortunately, Jsonnet can work as a templating language and it offers many structures that allow
generating data. For that reason, Agama injects the hardware information that you can process using
the powerful [Jsonnet standard library](https://jsonnet.org/ref/stdlib.html).

You can access to the hardware information by importing the `hw.libsonnet` library, as you can see
in the example below.

```jsonnet
// There are included also helpers to search this hardware tree. To see helpers check
// "/usr/share/agama-cli/agama.libsonnet"
local agama = import 'hw.libsonnet';
// Find the biggest disk which is suitable for installing the system.
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;
// Find how much physical memory system has.
local memory = agama.findByID(agama.lshw, 'memory').size;
{
product: {
id: if memory < 8000000000 then 'MicroOS' else 'Tumbleweed',
},
user: {
fullName: 'Jane Doe',
userName: 'jane.doe',
password: '123456',
},
root: {
password: 'nots3cr3t',
sshPublicKey: '...',
},
storage: {
boot: {
configure: true,
device: 'boot',
},
drives: [
{
search: findBiggestDisk(agama.selectByClass(agama.lshw, 'disk')),
alias: 'boot',
},
],
},
}
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JFYI, with /testing_using_container.sh, this fails because there are no disks, and we may want to improve the error formatting:

cc153869b9da:/checkout # agama config generate -
// There are included also helpers to search this hardware tree. To see helpers check
// "/usr/share/agama-cli/agama.libsonnet"
local agama = import 'hw.libsonnet';

// Find the biggest disk which is suitable for installing the system.
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;
// ^ sorted[0] makes it fail
...
{
  product: {...  },
...,
}
Error: Backend call failed with status 400 and text '{"error":"Could not evaluate the profile: Jsonnet evaluation failed:\nRUNTIME ERROR: Index 0 out of bounds, not within [0, 0)\n\tprofile.jsonnet:9:3-12\t\n\tprofile.jsonnet:34:17-73\tobject <anonymous>\n\tField \"search\"\t\n\tArray element 0\t\n\tField \"drives\"\t\n\tField \"storage\"\t\n\tDuring manifestation\t\n\n"}'


Agama ships a few helpers to make it easier to search for the information you need from the hardware
tree. See
[agama.libsonnet](https://github.com/agama-project/agama/blob/master/rust/share/agama.libsonnet) for
further details.

:::tip Getting hardware information

You can inspect the available data by installing the `lshw` package and running the following
command: `lshw -json`.

:::
127 changes: 21 additions & 106 deletions docs/user/unattended/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,118 +4,33 @@ sidebar_position: 2

# Unattended installation

One of the main use cases of Agama is unatteded installation. The user provides a file, known as a
"profile", that describes how the system should look like (partitioning, networking, software
selection, etc.) and Agama takes care of installing the system according to such a description. This
approach might sound familiar to AutoYaST users.
Agama is able to install a system without user interaction. The user provides a definition of the
system, known as a "profile", that describes how the system should look like (partitioning,
networking, software selection, etc.) and Agama takes care of installing the system. This approach
might sound familiar to AutoYaST users.

Although Agama defines its own [profile
format](https://github.com/openSUSE/agama/blob/master/rust/agama-lib/share/profile.schema.json), it
is able to partially handle AutoYaST profiles. Please, check the [AutoYaST support
section](./autoyast) for further information.
Agama uses [Jsonnet](https://jsonnet.org/), a superset of JSON, which allows writing readable and
concise profiles. The example below instructs Agama to install _Tumbleweed_ and create a first user
so you can log in.

## Profile format

A profile defines which options to use during installation: which product to install, localization
settings, partitioning schema, etc. Although it sounds similar to AutoYaST, there are some essential
differences:

- Profiles are written in [Jsonnet](https://jsonnet.org/) instead of XML. Jsonnet is a superset of
JSON (so you can use just plain JSON), which allows for writing more readable and concise
profiles.
- You can take advantage of Jsonnet to build dynamic profiles, without having to rely on _rules_ or
_Embedded Ruby (ERB)_. Agama injects hardware information that can be processed using the [Jsonnet
standard library](https://jsonnet.org/ref/stdlib.html).

You can check the [Tumbleweed installation
profile](https://github.com/openSUSE/agama/blob/master/rust/agama-lib/share/examples/profile_tw.json)
included in the repository to get an impression of how a profile looks like.

### A minimal example

```json
```jsonnet
{
"localization": {
"language": "en_US.UTF-8"
},
"product": {
"id": "Tumbleweed"
product: {
id: "Tumbleweed"
},
"user": {
"fullName": "Jane Doe",
"userName": "jane.doe",
"password": "123456"
user: {
fullName: "Jane Doe",
userName: "jane.doe",
password: "123456"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docs is fine but let me take this opportunity to show that while I am validating all the examples in this PR, I have found a bug in the recent users PR.

The first object is what I paste in, the second one is agama output:

cc153869b9da:/checkout # agama config generate -
{
  user: {
    fullName: "Jane Doe",
    userName: "jane.doe",
    password: "123456"
  }
}

{
  "user": {
    "fullName": "Jane Doe",
    "userName": "jane.doe"
  }
}
✗ The profile is not valid. Please, check the following errors:

        * "password" is a required property. /user

✗ Internal error: the profile was made invalid by InstallSettings round trip

Including hashedPassword: false would hide the bug.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I will check it.

}
}
```

### Supported configuration values

Check the [JSON
Schema](https://github.com/openSUSE/agama/blob/master/rust/agama-lib/share/profile.schema.json) to
learn about the supported elements.

Some areas are relatively complex and just looking at the schema may not be enough to fully
understand how they work. That is definitely the case of the storage setup, that is described in its
own [separate section](./storage.md).

### Dynamic profiles

The profile can be adapted at runtime depending on the system where the auto-installation is
running. For such use cases, Agama injects the hardware information into the profile to be processed
using Jsonnet.

Please, check [the example
profile](https://github.com/openSUSE/agama/blob/master/rust/agama-lib/share/examples/profile.jsonnet)
for further information.

:::tip Getting hardware information
You can inspect the available data by installing the `lshw` package and running the following
command: `lshw -json`.
:::

### Validating and evaluating a profile

Agama includes a handy command-line interface available in the `agama` package. Among many other
things, it allows downloading, validating and evaluating profiles. For instance, we could check the
result of the previous profile by running the following command:

```console
sudo agama profile evaluate my-profile.jsonnet
```

:::warning Use `sudo`
You need to use `sudo` to access the hardware information.
:::

Do you want to check whether your profile is valid? `agama` have you covered. Bear in mind that you
can only validate JSON profiles (a Jsonnet profile must be evaluated first).

```console
agama profile validate my-profile.json
```

### Generating a configuration file

Writing the profile by hand is relatively easy. However, you might want to ask Agama to do it for
you. You can boot the installation, use the web interface to tweak all the values and, from the
terminal, generate the file by running the following command:

```console
sudo agama config show > profile.json
```

## Starting the installation

To start an unattended installation process, you need to tell Agama where to find the profile. When
using the Live ISO, you must use the `inst.auto` boot option. Please, check the
[boot options](../boot_options/index.md) for further information.

If you do not specify any profile, Agama will automatically search for it in a few predefined
locations. Agama expects a file named `autoinst.jsonnet`, `autoinst.json` or `autoinst.xml` (in that
order) to be located on:

- The root of a file system named `OEMDRV`.
- Or the root (`/`) of the installation environment.
It is possible to define the storage layout, which software to install, the network configuration,
etc. Check the [profile format](./unattended/profile) section to learn more. Once you have your
first profile, you might want to learn how to
[start the installation](./unattended/working-with-profiles#starting-the-installation).

The first file found is used as the profile, starting the installation right away.
Finally, it is worth to mention that although Agama defines its own profile format, it is able to
partially handle AutoYaST profiles. Please, check the
[AutoYaST support section](./unattended/autoyast) for further information.
25 changes: 25 additions & 0 deletions docs/user/unattended/profile/bootloader.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
sidebar_position: 11
---

# Bootloader configuration

Agama offers a reduced set of settings to change the bootloader configuration, although it is able
to set it up correctly in many situations and architectures.

These options are defined in the `bootloader` section.

- `stopOnBootMenu`: stop on the menu instead of booting the system automatically.
- `timeout`: specify how many seconds the bootloader should wait on the menu before booting the
default entry. Unlike AutoYaST, the timeout should be a positive number. If you want the
bootloader to stop indefinitely, just set `stopOnBootMenu` to `true`.
- `extraKernelParams`: additional kernel parameters.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe I would explain here that if there is need for specific kernel parameter for kernel already for installation, then it will be reused in proposal. So it is mainly for parameters that are only for installed system and not installation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not get it, sorry.


```
{
bootloader: {
stopOnBootMenu: true,
extraKernelParams: "processor.max_cstate=1"
}
}
```
71 changes: 71 additions & 0 deletions docs/user/unattended/profile/files.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
---
sidebar_position: 7
---

# Copying files

In many cases, you might need to copy some files to the installed system. This feature is especially
useful when you want to tweak your system configuration (for instance, dropping a file to
`/etc/sysctl.d`), but it can be used in other situations too.

## File properties

Agama provides a `files` key where you can define the source (the content or an URL to fetch the
file from), the permissions, the owner and the destination of the file.

- `content`: the content of the file.
- `url`: alternatively to the `content`, you can define a URL to fetch the file from. The files are
downloaded and written to the disk at the end of the installation. In addition to the
[supported URLs](../../urls) you can use a URL relative to the profile (e.g., "/motd").
- `destination`: the location of the file in the installed system.
- `permissions`: a string describing the file permissions in numeric mode (e.g.: `"0640"`). By
default it is set to `"0644"`).
- `user`: user owner of the file (`"root"` by default).
- `group`: group owner of the file (`"root"` by default).

:::note Working with relative URLs

If you use the `inst.auto` boot option to specify the URL of the profile, any relative URL will use
the URL of the profile as its base.

However, loading the profile using the `agama config load` will not work in the same way.
Check the [Manually loading a profile](../working-with-profiles#manually-loading-a-profile) section
for further information.

:::

## Example

The example below adds a welcome message to the system and registers a new user by deploying a file
in `/etc/issue.d`:

```jsonnet
{
files: [
{
url: "/motd",
destination: "/etc/issue.d/welcome.issue",
permissions: "0644",
},
{
destination: "/etc/sysusers.d/myapp.conf",
content: |||
# Type Name ID GECOS Home
u myapp - "My Application" /var/lib/myapp
|||
}
]
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JFYI, the InstallSettings round trip makes the remaining attributes explicit:

cc153869b9da:/checkout # agama config generate -
{
  files: [
    {
      url: "/motd",
      destination: "/etc/issue.d/welcome.issue",
      permissions: "0644",
    },
    {
      destination: "/etc/sysusers.d/myapp.conf",
      content: |||
        # Type Name ID GECOS Home
        u      myapp - "My Application" /var/lib/myapp
      |||
    }
  ]
}
{
  "files": [
    {
      "url": "file:///motd",
      "permissions": "0644",
      "user": "root",
      "group": "root",
      "destination": "/etc/issue.d/welcome.issue"
    },
    {
      "content": "# Type Name ID GECOS Home\nu      myapp - \"My Application\" /var/lib/myapp\n",
      "permissions": "0644",
      "user": "root",
      "group": "root",
      "destination": "/etc/sysusers.d/myapp.conf"
    }
  ]
}
✓ The profile is valid.

Copy link
Contributor Author

@imobachgs imobachgs Jun 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which is wrong, although out of scope. We have the same problem in several places.

```

## Binary files

Although the intention is to work with text files, Agama does not impose any limitation of the kind
of files you can deploy. So using a URL to a binary file should work too.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was curious so I checked: not even Jsonnet can represent binary data, which makes sense once you realize it needs a JSON representation.


:::note Generating a file using a script

Unlike AutoYaST, Agama does not allow to generate the file using an script. For that use case, you
might use the [scripts](./scripts) section.

:::
Loading