Skip to content

Commit

Permalink
Merge branch 'master' into better-selector
Browse files Browse the repository at this point in the history
  • Loading branch information
dgdavid committed Feb 2, 2024
2 parents e4bc9a4 + f3aadda commit 79f0a30
Show file tree
Hide file tree
Showing 72 changed files with 2,997 additions and 1,360 deletions.
7 changes: 6 additions & 1 deletion .github/workflows/weblate-update-pot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,13 @@ jobs:
# disable unused repositories to have a faster refresh
run: zypper modifyrepo -d repo-non-oss repo-openh264 repo-update && zypper ref

- name: Install Default Ruby
run: zypper --non-interactive install --no-recommends ruby

- name: Install tools
run: zypper --non-interactive install --no-recommends diffutils git gettext-tools npm-default "rubygem(yast-rake)" "rubygem(gettext)" yast2-devtools
run: |
RUBY_VERSION=$(ruby -e "puts RbConfig::CONFIG['ruby_version']")
zypper --non-interactive install --no-recommends diffutils git gettext-tools npm-default "rubygem(ruby:$RUBY_VERSION:yast-rake)" "rubygem(ruby:$RUBY_VERSION:gettext)" yast2-devtools
- name: Checkout Agama sources
uses: actions/checkout@v3
Expand Down
91 changes: 91 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ Agama is a new Linux installer born in the core of the YaST team. It is designed
* [Architecture](#architecture)
* [How to Run](#how-to-run)
* [Live ISO Image](#live-iso-image)
* [Avahi/mDNS](#avahimdns)
* [Manual Configuration](#manual-configuration)
* [How to Contribute](#how-to-contribute)
* [Development Notes](#development-notes)
Expand Down Expand Up @@ -128,6 +129,96 @@ Service](https://download.opensuse.org/repositories/systemsmanagement:/Agama:/De
* Make sure to download the correct ISO file according to your system architecture (eg.
you would need to choose a file including `x86_64` if you use an Intel or AMD 64-bit processor)
and according to the system you want to install (openSUSE vs ALP).

#### Avahi/mDNS

The Live ISO is configured to use mDNS (sometimes called Avahi, Zeroconf,
Bonjour) for hostname resolution. The reason is that it might be quite difficult
to find out which URL should be used for connecting to a running Agama
installer.

##### :warning: Security Note :warning:

*Do not use the `.local` hostnames in untrusted networks (like public WiFi
networks, shared networks), it is a security risk. An attacker can easily send
malicious responses for the `.local` hostname resolutions and point you to a
wrong Agama instance which could for example steal your root password!*

##### Firewall Configuration

If you cannot connect to a server using the `.local` domain then maybe the
firewall is blocking the traffic. Then you need to enable the mDNS traffic using
these commands:

```shell
# enable the mDNS traffic in the current run
firewall-cmd --zone=public --add-service=mdns
# make the change permanent
firewall-cmd --permanent --zone=public --add-service=mdns
```

##### Using mDNS

The Live ISO by default uses the `agama.local` hostname. To connect to the
running instance simply type `https://agama.local` in your browser. In most
browsers the HTTPS is the default protocol so usually it is enough to just type
`agama.local`.

If you run multiple Agama instances, each one will have a different name. The server
appends a number to make it unique. So the second Agama instance gets the
`agama-2.local` hostname.

If you are not sure whether there are multiple Agama instances running you scan
the network, see the [service advertising](#service-advertising) below.

Alternatively you can set a different hostname for each instance manually. Use
the `hostname=` boot option to set a different hostname. For example set
`hostname=foo`, `hostname=bar` and then use `https://foo.local`,
`https://bar.local` URLs in the web browser to connect to the respective
instance.

It is possible to change the hostname later if needed:

```shell
# set the new hostname
hostnamectl hostname <hostname>
# restart the avahi daemon server
systemctl restart avahi-daemon
```

The mDNS resolution also works for other services like ping or SSH. So you can
use commands like:

```shell
ping agama.local
ssh root@agama.local
```

##### Fallback

The mDNS approach is just an addition, one more possibility how to connect to
the machine. If it does not work for you then you can always use the old good
classic IP address approach.

##### Service Advertising

The Agama Live ISO also uses Avahi service advertising. With this you can easily
search for all running Agama instances in the local network:

```shell
avahi-browse -t -r _agama._sub._https._tcp
```

The command will print the found servers and their hostnames and IP addresses.

##### Notes

- mDNS works only in the same local network, it does not work over internet
or separate network segments.
- mDNS might not be supported in all systems or it might be blocked by firewall.
- On mobile phones with Android OS mDNS is supported since Android version 12.
(but this might be vendor dependent...).

### Manual Configuration

You can run Agama from its sources by cloning and configuring the project:
Expand Down
118 changes: 118 additions & 0 deletions autoinstallation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,124 @@ set -ex
You might want to have a look to [Agama's default script for inspiration](./scripts/auto.sh). Such a
script comes into action when you provide a profile.

### Support for Custom Scripts

The goal of this section is to document examples and use cases for additional scripting support in Agama auto-installation.

#### Changes Before Installation

##### Hardware Activation

In some cases it is necessary to activate tricky devices manually before starting the installation. An example is when you have two network cards, one for the external network and the other for the internal network.

```sh
set -ex

/usr/bin/agama profile download ftp://my.server/tricky_hardware_setup.sh
sh tricky_hardware_setup.sh
/usr/bin/agama config set software.product=Tumbleweed
/usr/bin/agama config set user.userName=joe user.password=doe
/usr/bin/agama install
```

##### Modifying the Installation Profile


Jsonnet may be unable to handle all of the profile changes that users wish to make.


```
set -ex
/usr/bin/agama profile download ftp://my.server/profile.json
# modify profile.json here
/usr/bin/agama profile validate profile.json
/usr/bin/agama config load profile.json
/usr/bin/agama install
```

#### After Partitioning

Note: currently not supported (params to install is not implemented yet).

##### Partitioning Changes

Sometimes there is a more complex partitioning that needs to be modified after partitioning done by Agama and before installing RPMs, such as changing the fstab and mount an extra partition.


```sh
set -ex

/usr/bin/agama config set software.product=Tumbleweed
/usr/bin/agama config set user.userName=joe user.password=doe

/usr/bin/agama install --until partitioning # install till the partitioning step

# Place for specific changes to /dev

/usr/bin/agama install # do the rest of the installation
```

#### After Deployment

Note: not supported now (params to install is not implemented yet).

##### Setup Security


If there is a need to modify the system before rebooting, e.g. to install mandatory security software for internal network, then it must be modified before umount.


``` sh

set -ex

/usr/bin/agama profile download ftp://my.server/velociraptor.config

/usr/bin/agama config set software.product=Tumbleweed
/usr/bin/agama config set user.userName=joe user.password=doe

/usr/bin/agama install --until deploy # do partitioning, rpm installation and configuration step

# Example of enabling velociraptor

zypper --root /mnt install velociraptor-client

mkdir -p /mnt/etc/velociraptor
cp velociraptor.config /mnt/etc/velociraptor/client.config

systemctl --root /mnt enable velociraptor-client

/usr/bin/agama install # do the rest of the installation - basically unmount and copy logs

```

##### Tuning the Kernel

Another scenario is when you need to make some changes required for a successful reboot, such as some kernel tuning or adding some remote storage that needs to be mounted during boot.

``` sh
set -ex

/usr/bin/agama config set software.product=Tumbleweed
/usr/bin/agama config set user.userName=joe user.password=doe

/usr/bin/agama install --until deploy # do partitioning, rpm installation and configuration step

# Do custom modification of /mnt including call to dracut

/usr/bin/agama install # do the rest of the installation - basically unmount and copy logs
```

#### After Reboot

Users usually do a lot of things with post installation scripts in AutoYaST e.g. calling zypper to install additional software, modify configuration files or manipulate with systemd services. This is done after the first reboot.
If this is the case, Agama will simply delegate it to any other tool the user prefers for initial configuration, such as ignition/combustion.

## Starting the auto-installation

The auto-installation is started by passing `agama.auto=<url>` on the kernel's command line. If you
Expand Down
2 changes: 1 addition & 1 deletion doc/deployment_guide_s390.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ Once ready boot the installation running the **sles.exec** REXX file
sles
```
Once the installation system finish the booting process just connect to the machine with the web browser (e.g. https://s390vsl111.suse.de:9090) or by SSH with (root / linux) user.
Once the installation system finish the booting process just connect to the machine with the web browser (e.g. https://s390vsl111.suse.de) or by SSH with (root / linux) user.
## Screenshots of the complete installation Z/VM installation workflow
Expand Down
2 changes: 1 addition & 1 deletion playwright/tests/take_screenshots.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { mainPagePath } from "../lib/installer";
// This test was designed for collecting the screenshots for the main
// README.md file. To take screenshots of the installation process run this:
//
// RUN_INSTALLATION=1 BASE_URL=https://<host>:9090 npx playwright test --headed take_screenshots
// RUN_INSTALLATION=1 BASE_URL=https://<host> npx playwright test --headed take_screenshots
//
// The "--headed" option shows the browser window so you can see the progress.
// You can use the "--debug" option to run the test step-by-step.
Expand Down
2 changes: 1 addition & 1 deletion rust/agama-dbus-server/src/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ mod nm;
pub mod system;

pub use action::Action;
pub use adapter::Adapter;
pub use adapter::{Adapter, NetworkAdapterError};
pub use dbus::NetworkService;
pub use model::NetworkState;
pub use nm::NetworkManagerAdapter;
Expand Down
10 changes: 6 additions & 4 deletions rust/agama-dbus-server/src/network/action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use tokio::sync::oneshot;
use uuid::Uuid;
use zbus::zvariant::OwnedObjectPath;

use super::error::NetworkStateError;
use super::{error::NetworkStateError, NetworkAdapterError};

pub type Responder<T> = oneshot::Sender<T>;
pub type ControllerConnection = (Connection, Vec<String>);
Expand All @@ -24,7 +24,9 @@ pub enum Action {
/// Gets a connection
GetConnection(Uuid, Responder<Option<Connection>>),
/// Gets a connection
GetConnectionPath(String, Responder<Option<OwnedObjectPath>>),
GetConnectionPath(Uuid, Responder<Option<OwnedObjectPath>>),
/// Gets a connection
GetConnectionPathById(String, Responder<Option<OwnedObjectPath>>),
/// Get connections paths
GetConnectionsPaths(Responder<Vec<OwnedObjectPath>>),
/// Gets a controller connection
Expand All @@ -44,7 +46,7 @@ pub enum Action {
/// Update a connection (replacing the old one).
UpdateConnection(Box<Connection>),
/// Remove the connection with the given Uuid.
RemoveConnection(String),
RemoveConnection(Uuid),
/// Apply the current configuration.
Apply,
Apply(Responder<Result<(), NetworkAdapterError>>),
}
23 changes: 20 additions & 3 deletions rust/agama-dbus-server/src/network/adapter.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,27 @@
use crate::network::NetworkState;
use agama_lib::error::ServiceError;
use async_trait::async_trait;
use std::error::Error;
use thiserror::Error;

#[derive(Error, Debug)]
pub enum NetworkAdapterError {
#[error("Could not read the network configuration: {0}")]
Read(ServiceError),
#[error("Could not update the network configuration: {0}")]
Write(ServiceError),
#[error("Checkpoint handling error: {0}")]
Checkpoint(ServiceError), // only relevant for adapters that implement a checkpoint mechanism
}

/// A trait for the ability to read/write from/to a network service
#[async_trait]
pub trait Adapter {
async fn read(&self) -> Result<NetworkState, Box<dyn Error>>;
async fn write(&self, network: &NetworkState) -> Result<(), Box<dyn Error>>;
async fn read(&self) -> Result<NetworkState, NetworkAdapterError>;
async fn write(&self, network: &NetworkState) -> Result<(), NetworkAdapterError>;
}

impl From<NetworkAdapterError> for zbus::fdo::Error {
fn from(value: NetworkAdapterError) -> zbus::fdo::Error {
zbus::fdo::Error::Failed(value.to_string())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,20 @@ impl Wireless {
.await?;
Ok(())
}

/// Whether the network is hidden or not.
#[dbus_interface(property)]
pub async fn hidden(&self) -> zbus::fdo::Result<bool> {
let config = self.get_config::<WirelessConfig>().await?;
Ok(config.hidden)
}

#[dbus_interface(property)]
pub async fn set_hidden(&mut self, hidden: bool) -> zbus::fdo::Result<()> {
self.update_config::<WirelessConfig, _>(|c| c.hidden = hidden)
.await?;
Ok(())
}
}

#[async_trait]
Expand Down
Loading

0 comments on commit 79f0a30

Please sign in to comment.