mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-30 12:33:02 +02:00
Merge pull request #1090 from kernelkit/doc
doc: minor markdownlint cleanup and fixes to admonitions
This commit is contained in:
+137
-136
@@ -1,37 +1,36 @@
|
|||||||
Boot Procedure
|
# Boot Procedure
|
||||||
==============
|
|
||||||
|
|
||||||
Systems running Infix will typically boot in multiple phases, forming
|
Systems running Infix will typically boot in multiple phases, forming
|
||||||
a boot chain. Each link in the chain has three main responsibilities:
|
a boot chain. Each link in the chain has three main responsibilities:
|
||||||
|
|
||||||
1. Ensuring the integrity of the next link before passing control to
|
1. Ensuring the integrity of the next link before passing control to
|
||||||
it. This avoids silent failures stemming from data corruption.
|
it. This avoids silent failures stemming from data corruption.
|
||||||
|
1. Ensuring the authenticity of the next link before passing control
|
||||||
2. Ensuring the authenticity of the next link before passing control
|
|
||||||
to it, commonly referred to as _Secure Boot_. This protects against
|
to it, commonly referred to as _Secure Boot_. This protects against
|
||||||
malicious attempts to modify a system's firmware.
|
malicious attempts to modify a system's firmware.
|
||||||
|
1. Preparing the system state according to the requirements of the
|
||||||
3. Preparing the system state according to the requirements of the
|
|
||||||
next link. E.g. the Linux kernel requires the system's RAM to be
|
next link. E.g. the Linux kernel requires the system's RAM to be
|
||||||
operational.
|
operational.
|
||||||
|
|
||||||
A typical chain consists of four stages:
|
A typical chain consists of four stages:
|
||||||
|
|
||||||
.---------.
|
```
|
||||||
| ROM >---. Determine the location of and load the SPL
|
.---------.
|
||||||
'---------' |
|
| ROM >---. Determine the location of and load the SPL
|
||||||
.-----------------'
|
'---------' |
|
||||||
| .---------.
|
.-----------------'
|
||||||
'---> SPL >---. Perform DDR training and load the TPL
|
| .---------.
|
||||||
'---------' |
|
'---> SPL >---. Perform DDR training and load the TPL
|
||||||
.-----------------'
|
'---------' |
|
||||||
| .---------.
|
.-----------------'
|
||||||
'---> TPL >---. Load Linux kernel, device tree, and root filesystem
|
| .---------.
|
||||||
'---------' |
|
'---> TPL >---. Load Linux kernel, device tree, and root filesystem
|
||||||
.-----------------'
|
'---------' |
|
||||||
| .---------.
|
.-----------------'
|
||||||
'---> Infix | Get down to business
|
| .---------.
|
||||||
'---------'
|
'---> Infix | Get down to business
|
||||||
|
'---------'
|
||||||
|
```
|
||||||
|
|
||||||
After a reset, hardware will pass control to a program (_ROM_) which
|
After a reset, hardware will pass control to a program (_ROM_) which
|
||||||
is almost always programmed into the SoC by the vendor. This program
|
is almost always programmed into the SoC by the vendor. This program
|
||||||
@@ -52,9 +51,7 @@ This document's focus is to describe the final two phases of the boot
|
|||||||
chain, as the initial phases are very hardware dependent, better
|
chain, as the initial phases are very hardware dependent, better
|
||||||
described by existing documentation provided by the SoC vendor.
|
described by existing documentation provided by the SoC vendor.
|
||||||
|
|
||||||
|
## Bootloader
|
||||||
Bootloader
|
|
||||||
----------
|
|
||||||
|
|
||||||
### Configuration
|
### Configuration
|
||||||
|
|
||||||
@@ -62,33 +59,42 @@ To mitigate the risk of a malicious user being able to circumvent the
|
|||||||
bootloader's validation procedure, user configuration is kept to a
|
bootloader's validation procedure, user configuration is kept to a
|
||||||
minimum. Two settings are available:
|
minimum. Two settings are available:
|
||||||
|
|
||||||
- **Boot order**: Since Infix maintains two copies of its software image,
|
**Boot order**: Since Infix maintains two copies of its software image,
|
||||||
and as some bootloaders support [netbooting][2], the order in which boot
|
and as some bootloaders support [netbooting][2], the order in which boot
|
||||||
sources are considered can be configured. To select the active
|
sources are considered can be configured. To select the active
|
||||||
source, use [RAUC][]:
|
source, use [RAUC][]:
|
||||||
|
|
||||||
rauc status mark-active <slot>
|
```
|
||||||
|
root@example:~# rauc status mark-active <slot>
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
Where `<slot>` is one of:
|
Where `<slot>` is one of:
|
||||||
|
|
||||||
| `<slot>` | Source |
|
| **`<slot>`** | **Source** |
|
||||||
|------------|---------------------------|
|
|--------------|---------------------------|
|
||||||
| `rootfs.0` | Primary partition |
|
| `rootfs.0` | Primary partition |
|
||||||
| `rootfs.1` | Secondary partition |
|
| `rootfs.1` | Secondary partition |
|
||||||
| `net.0` | Netboot (where supported) |
|
| `net.0` | Netboot (where supported) |
|
||||||
|
|
||||||
- **Debug**: By default, the kernel will only output errors to the
|
**Debug**: By default, the kernel will only output errors to the
|
||||||
console during boot. Optionally, this can be altered such that all
|
console during boot. Optionally, this can be altered such that all
|
||||||
enabled messages are logged.
|
enabled messages are logged.
|
||||||
|
|
||||||
On systems using _U-Boot_, this can be enabled by running `fw_setenv
|
On systems using _U-Boot_, this can be enabled by running `fw_setenv
|
||||||
DEBUG 1`. To restore the default behavior, run `fw_setenv DEBUG`.
|
DEBUG 1`. To restore the default behavior, run `fw_setenv DEBUG`.
|
||||||
|
|
||||||
On systems running _GRUB_, this can be enabled by running
|
On systems running _GRUB_, this can be enabled by running:
|
||||||
`grub-editenv /mnt/aux/grub/grubenv set DEBUG=1`. To restore the
|
|
||||||
default behavior, run `grub-editenv /mnt/aux/grub/grubenv unset
|
|
||||||
DEBUG`
|
|
||||||
|
|
||||||
|
```
|
||||||
|
root@example:~# grub-editenv /mnt/aux/grub/grubenv set DEBUG=1
|
||||||
|
```
|
||||||
|
|
||||||
|
To restore the default behavior, run:
|
||||||
|
|
||||||
|
```
|
||||||
|
root@example:~# grub-editenv /mnt/aux/grub/grubenv unset DEBUG
|
||||||
|
```
|
||||||
|
|
||||||
### U-Boot
|
### U-Boot
|
||||||
|
|
||||||
@@ -109,7 +115,6 @@ Access to U-Boot's shell is disabled to prevent side-loading of
|
|||||||
malicious software. To configure the active boot partition, refer to
|
malicious software. To configure the active boot partition, refer to
|
||||||
the [Bootloader Configuration](#configuration) section.
|
the [Bootloader Configuration](#configuration) section.
|
||||||
|
|
||||||
|
|
||||||
### GRUB
|
### GRUB
|
||||||
|
|
||||||
Used on _x86_64_ based systems. Neither the _integrity_ nor the
|
Used on _x86_64_ based systems. Neither the _integrity_ nor the
|
||||||
@@ -123,7 +128,6 @@ partition can be selected interactively at boot using the arrow keys. It
|
|||||||
is also possible to permanently configure the default partition from
|
is also possible to permanently configure the default partition from
|
||||||
Infix using the [Bootloader Configuration](#configuration).
|
Infix using the [Bootloader Configuration](#configuration).
|
||||||
|
|
||||||
|
|
||||||
## System Boot
|
## System Boot
|
||||||
|
|
||||||
After the system firmware (BIOS or and [boot loader](boot.md) start
|
After the system firmware (BIOS or and [boot loader](boot.md) start
|
||||||
@@ -132,49 +136,50 @@ password in VPD, are detailed later in this section.
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
1. Before mounting `/cfg` and `/var` partitions, hosting read-writable
|
1. Before mounting `/cfg` and `/var` partitions, hosting read-writable
|
||||||
data like `startup-config` and container images, the system first
|
data like `startup-config` and container images, the system first
|
||||||
checks if a factory reset has been requested by the user, if so it
|
checks if a factory reset has been requested by the user, if so it
|
||||||
wipes the contents of these partitions
|
wipes the contents of these partitions
|
||||||
2. Linux boots with a device tree which is used for detecting generic
|
1. Linux boots with a device tree which is used for detecting generic
|
||||||
make and model of the device, e.g., number of interfaces. It may
|
make and model of the device, e.g., number of interfaces. It may
|
||||||
also reference an EEPROM with [Vital Product Data](vpd.md). That is
|
also reference an EEPROM with [Vital Product Data](vpd.md). That is
|
||||||
where the base MAC address and per-device password hash is stored.
|
where the base MAC address and per-device password hash is stored.
|
||||||
(Generic builds use the same MAC address and password)
|
(Generic builds use the same MAC address and password)
|
||||||
3. On every boot the system's `factory-config` and `failure-config` are
|
1. On every boot the system's `factory-config` and `failure-config` are
|
||||||
generated from the YANG[^2] models of the current firmware version.
|
generated from the YANG[^2] models of the current firmware version.
|
||||||
This ensures that a factory reset device can always boot, and that
|
This ensures that a factory reset device can always boot, and that
|
||||||
there is a working fail safe, or rather *fail secure*, mode
|
there is a working fail safe, or rather *fail secure*, mode
|
||||||
4. On first power-on, and after a factory reset, the system does not
|
1. On first power-on, and after a factory reset, the system does not
|
||||||
have a `startup-config`, in which case `factory-config` is copied
|
have a `startup-config`, in which case `factory-config` is copied
|
||||||
to `startup-config` -- if a per-product specific version exists it
|
to `startup-config` -- if a per-product specific version exists it
|
||||||
is preferred over the generated one
|
is preferred over the generated one
|
||||||
5. Provided the integrity of the `startup-config` is OK, a system
|
1. Provided the integrity of the `startup-config` is OK, a system
|
||||||
service loads and activates the configuration
|
service loads and activates the configuration
|
||||||
|
|
||||||
### Failure Modes
|
### Failure Modes
|
||||||
|
|
||||||
So, what happens if any of the steps above fail?
|
So, what happens if any of the steps above fail?
|
||||||
|
|
||||||
**VPD Fail**
|
#### VPD Fail
|
||||||
|
|
||||||
The per-device password cannot be read, or is corrupt, so the system
|
The per-device password cannot be read, or is corrupt, so the system
|
||||||
`factory-config` and `failure-config` are not generated:
|
`factory-config` and `failure-config` are not generated:
|
||||||
|
|
||||||
1. First boot, or after factory reset: `startup-config` cannot be
|
1. First boot, or after factory reset: `startup-config` cannot be
|
||||||
created or loaded, and `failure-config` cannot be loaded. The
|
created or loaded, and `failure-config` cannot be loaded. The
|
||||||
system ends up in an unrecoverable state, i.e., **RMA[^3] Mode**
|
system ends up in an unrecoverable state, i.e., **RMA[^3] Mode**
|
||||||
2. The system has booted (at least) once with correct VPD and password
|
1. The system has booted (at least) once with correct VPD and password
|
||||||
and already has a `startup-config`. Provided the `startup-config`
|
and already has a `startup-config`. Provided the `startup-config`
|
||||||
is OK (see below), it is loaded and system boots successfully
|
is OK (see below), it is loaded and system boots successfully
|
||||||
|
|
||||||
In both cases, external factory reset modes/button will not help, and
|
In both cases, external factory reset modes/button will not help, and
|
||||||
in the second case will cause the device to fail on the next boot.
|
in the second case will cause the device to fail on the next boot.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
> The second case does not yet have any warning or event that can be
|
> The second case does not yet have any warning or event that can be
|
||||||
> detected from the outside. This is planned for a later release.
|
> detected from the outside. This is planned for a later release.
|
||||||
|
|
||||||
**Broken startup-config**
|
#### Broken startup-config
|
||||||
|
|
||||||
If loading `startup-config` fails for some reason, e.g., invalid JSON
|
If loading `startup-config` fails for some reason, e.g., invalid JSON
|
||||||
syntax, failed validation against the system's YANG model, or a bug in
|
syntax, failed validation against the system's YANG model, or a bug in
|
||||||
@@ -194,9 +199,7 @@ link-local, and device discovery protocols: LLDP, mDNS-SD. The login
|
|||||||
and shell prompt are set to `failure-c0-ff-ee`, the last three octets of
|
and shell prompt are set to `failure-c0-ff-ee`, the last three octets of
|
||||||
the device's base MAC address.
|
the device's base MAC address.
|
||||||
|
|
||||||
|
## System Upgrade
|
||||||
System Upgrade
|
|
||||||
--------------
|
|
||||||
|
|
||||||
Much of the minutiae of software upgrades is delegated to [RAUC][],
|
Much of the minutiae of software upgrades is delegated to [RAUC][],
|
||||||
which offers lots of benefits out-of-the-box:
|
which offers lots of benefits out-of-the-box:
|
||||||
@@ -204,18 +207,19 @@ which offers lots of benefits out-of-the-box:
|
|||||||
- Upgrade Bundles are always signed, such that their authenticity can
|
- Upgrade Bundles are always signed, such that their authenticity can
|
||||||
be verified by the running operating system, before the new one is
|
be verified by the running operating system, before the new one is
|
||||||
installed.
|
installed.
|
||||||
|
|
||||||
- The bureaucracy of interfacing with different bootloaders, manage
|
- The bureaucracy of interfacing with different bootloaders, manage
|
||||||
the boot order, is a simple matter of providing a compatible
|
the boot order, is a simple matter of providing a compatible
|
||||||
configuration.
|
configuration.
|
||||||
|
|
||||||
- Updates can be sourced from the local filesystem (including external
|
- Updates can be sourced from the local filesystem (including external
|
||||||
media like USB sticks or SD-cards) and from remote servers using FTP
|
media like USB sticks or SD-cards) and from remote servers using FTP
|
||||||
or HTTP(S).
|
or HTTP(S).
|
||||||
|
|
||||||
To initiate a system upgrade from the shell[^1], run:
|
To initiate a system upgrade from the shell[^1], run:
|
||||||
|
|
||||||
rauc install <file|url>
|
```
|
||||||
|
root@example:~# rauc install <file|url>
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
Where the file or URL points to a [RAUC Upgrade Bundle](#rauc-upgrade-bundle).
|
Where the file or URL points to a [RAUC Upgrade Bundle](#rauc-upgrade-bundle).
|
||||||
|
|
||||||
@@ -225,9 +229,7 @@ will then boot from the newly installed image. Since the partition
|
|||||||
from which you were originally running is now inactive, running the
|
from which you were originally running is now inactive, running the
|
||||||
same upgrade command again will bring both partitions into sync.
|
same upgrade command again will bring both partitions into sync.
|
||||||
|
|
||||||
|
## Image Formats
|
||||||
Image Formats
|
|
||||||
-------------
|
|
||||||
|
|
||||||
### SquashFS Image
|
### SquashFS Image
|
||||||
|
|
||||||
@@ -279,7 +281,6 @@ validate the SquashFS's contents. This path was chosen because:
|
|||||||
In its full form, it can be used to netboot Infix, as it contains all
|
In its full form, it can be used to netboot Infix, as it contains all
|
||||||
the information needed by U-Boot in a single file.
|
the information needed by U-Boot in a single file.
|
||||||
|
|
||||||
|
|
||||||
### RAUC Upgrade Bundle
|
### RAUC Upgrade Bundle
|
||||||
|
|
||||||
**Canonical Name**: `infix-${ARCH}.pkg`
|
**Canonical Name**: `infix-${ARCH}.pkg`
|
||||||
@@ -293,7 +294,6 @@ system.
|
|||||||
When performing a [System Upgrade](#system-upgrade), this is the format
|
When performing a [System Upgrade](#system-upgrade), this is the format
|
||||||
to use.
|
to use.
|
||||||
|
|
||||||
|
|
||||||
### Disk Image
|
### Disk Image
|
||||||
|
|
||||||
**Canonical Name**: `disk.img`
|
**Canonical Name**: `disk.img`
|
||||||
@@ -302,35 +302,37 @@ Infix runs from a block device (e.g. eMMC or virtio disk) with the
|
|||||||
following layout. The disk is expected to use the GPT partitioning
|
following layout. The disk is expected to use the GPT partitioning
|
||||||
scheme. Partitions marked with an asterisk are optional.
|
scheme. Partitions marked with an asterisk are optional.
|
||||||
|
|
||||||
.-----------.
|
```
|
||||||
| GPT Table |
|
.-----------.
|
||||||
:-----------:
|
| GPT Table |
|
||||||
| boot* |
|
:-----------:
|
||||||
:-----------:
|
| boot* |
|
||||||
| aux |
|
:-----------:
|
||||||
:-----------:
|
| aux |
|
||||||
| |
|
:-----------:
|
||||||
| primary |
|
| |
|
||||||
| |
|
| primary |
|
||||||
:-----------:
|
| |
|
||||||
| |
|
:-----------:
|
||||||
| secondary |
|
| |
|
||||||
| |
|
| secondary |
|
||||||
:-----------:
|
| |
|
||||||
| cfg |
|
:-----------:
|
||||||
:-----------:
|
| cfg |
|
||||||
| |
|
:-----------:
|
||||||
| var* |
|
| |
|
||||||
| |
|
| var* |
|
||||||
'-----------'
|
| |
|
||||||
|
'-----------'
|
||||||
|
```
|
||||||
|
|
||||||
#### `boot` - Bootloader
|
#### `boot` - Bootloader
|
||||||
|
|
||||||
| Parameter | Value |
|
| **Parameter** | **Value** |
|
||||||
|-----------|-----------------------------------------|
|
|---------------|-----------------------------------------|
|
||||||
| Required | No |
|
| Required | No |
|
||||||
| Size | 4 MiB |
|
| Size | 4 MiB |
|
||||||
| Format | Raw binary, as dictated by the hardware |
|
| Format | Raw binary, as dictated by the hardware |
|
||||||
|
|
||||||
Optional partition containing the system's bootloader. May also reside
|
Optional partition containing the system's bootloader. May also reside
|
||||||
in a separate storage device, e.g. a serial FLASH.
|
in a separate storage device, e.g. a serial FLASH.
|
||||||
@@ -340,11 +342,11 @@ the GRUB bootloader.
|
|||||||
|
|
||||||
#### `aux` - Auxiliary Data
|
#### `aux` - Auxiliary Data
|
||||||
|
|
||||||
| Parameter | Value |
|
| **Parameter** | **Value** |
|
||||||
|-----------|-----------------|
|
|---------------|-----------------|
|
||||||
| Required | Yes |
|
| Required | Yes |
|
||||||
| Size | 4 MiB |
|
| Size | 4 MiB |
|
||||||
| Format | EXT4 filesystem |
|
| Format | EXT4 filesystem |
|
||||||
|
|
||||||
Holds information that is shared between Infix and its bootloader,
|
Holds information that is shared between Infix and its bootloader,
|
||||||
such as image signatures required to validate the chain of trust,
|
such as image signatures required to validate the chain of trust,
|
||||||
@@ -353,10 +355,10 @@ bootloader configuration etc.
|
|||||||
Typical layout when using U-Boot bootloader:
|
Typical layout when using U-Boot bootloader:
|
||||||
|
|
||||||
```
|
```
|
||||||
/
|
/
|
||||||
├ primary.itbh
|
├ primary.itbh
|
||||||
├ secondary.itbh
|
├ secondary.itbh
|
||||||
└ uboot.env
|
└ uboot.env
|
||||||
```
|
```
|
||||||
|
|
||||||
During boot, an ITB header along with the corresponding root
|
During boot, an ITB header along with the corresponding root
|
||||||
@@ -370,11 +372,11 @@ required to configure the boot order.
|
|||||||
|
|
||||||
#### `primary`/`secondary` - Root Filesystems
|
#### `primary`/`secondary` - Root Filesystems
|
||||||
|
|
||||||
| Parameter | Value |
|
| **Parameter** | **Value** |
|
||||||
|-----------|-------------------|
|
|---------------|-------------------|
|
||||||
| Required | Yes |
|
| Required | Yes |
|
||||||
| Size | >= 256 MiB |
|
| Size | >= 256 MiB |
|
||||||
| Format | Squash filesystem |
|
| Format | Squash filesystem |
|
||||||
|
|
||||||
Holds the [SquashFS Image](#squashfs-image). Two copies exist so that
|
Holds the [SquashFS Image](#squashfs-image). Two copies exist so that
|
||||||
an incomplete upgrade does not brick the system, and to allow fast
|
an incomplete upgrade does not brick the system, and to allow fast
|
||||||
@@ -382,22 +384,22 @@ rollbacks when upgrading to a new version.
|
|||||||
|
|
||||||
#### `cfg` - Configuration Data
|
#### `cfg` - Configuration Data
|
||||||
|
|
||||||
| Parameter | Value |
|
| **Parameter** | **Value** |
|
||||||
|-----------|-----------------|
|
|---------------|-----------------|
|
||||||
| Required | Yes |
|
| Required | Yes |
|
||||||
| Size | >= 16 MiB |
|
| Size | >= 16 MiB |
|
||||||
| Format | EXT4 filesystem |
|
| Format | EXT4 filesystem |
|
||||||
|
|
||||||
Non-volatile storage of the system configuration and user data.
|
Non-volatile storage of the system configuration and user data.
|
||||||
Concretely, user data is everything stored under `/root` and `/home`.
|
Concretely, user data is everything stored under `/root` and `/home`.
|
||||||
|
|
||||||
#### `var` - Variable Data
|
#### `var` - Variable Data
|
||||||
|
|
||||||
| Parameter | Value |
|
| **Parameter** | **Value** |
|
||||||
|-----------|-----------------|
|
|---------------|-----------------|
|
||||||
| Required | No |
|
| Required | No |
|
||||||
| Size | >= 16 MiB |
|
| Size | >= 16 MiB |
|
||||||
| Format | EXT4 filesystem |
|
| Format | EXT4 filesystem |
|
||||||
|
|
||||||
Persistent storage for everything under `/var`. This is maintained as
|
Persistent storage for everything under `/var`. This is maintained as
|
||||||
a separate filesystem from the data in `cfg`, because while the system
|
a separate filesystem from the data in `cfg`, because while the system
|
||||||
@@ -410,7 +412,7 @@ If `var` is not available, Infix will still persist `/var/lib` using
|
|||||||
[^1]: See [Upgrade & Boot Order](upgrade.md) for more information.
|
[^1]: See [Upgrade & Boot Order](upgrade.md) for more information.
|
||||||
[^2]: YANG is a modeling language from IETF, replacing that used for
|
[^2]: YANG is a modeling language from IETF, replacing that used for
|
||||||
SNMP (MIB), used to describe the subsystems and properties of
|
SNMP (MIB), used to describe the subsystems and properties of
|
||||||
the system.
|
the system.
|
||||||
[^3]: Return Merchandise Authorization (RMA), i.e., broken beyond repair
|
[^3]: Return Merchandise Authorization (RMA), i.e., broken beyond repair
|
||||||
by end-user and eligible for return to manufacturer.
|
by end-user and eligible for return to manufacturer.
|
||||||
[^4]: Customer specific builds can define their own `failure-config`.
|
[^4]: Customer specific builds can define their own `failure-config`.
|
||||||
@@ -420,7 +422,6 @@ If `var` is not available, Infix will still persist `/var/lib` using
|
|||||||
security problems on the network. E.g., start forwarding traffic
|
security problems on the network. E.g., start forwarding traffic
|
||||||
between previously isolated VLANs.
|
between previously isolated VLANs.
|
||||||
|
|
||||||
|
|
||||||
[2]: netboot.md
|
[2]: netboot.md
|
||||||
[FIT]: https://u-boot.readthedocs.io/en/latest/usage/fit.html
|
[FIT]: https://u-boot.readthedocs.io/en/latest/usage/fit.html
|
||||||
[RAUC]: https://rauc.io
|
[RAUC]: https://rauc.io
|
||||||
|
|||||||
+86
-90
@@ -1,11 +1,9 @@
|
|||||||
Branding & Releases
|
# Branding & Releases
|
||||||
===================
|
|
||||||
|
|
||||||
This document is for projects using Infix as a br2-external, i.e., OEMs.
|
This document is for projects using Infix as a br2-external, i.e., OEMs
|
||||||
|
that want to create *their own "Spin"* of Infix.
|
||||||
|
|
||||||
|
## Branding
|
||||||
Branding
|
|
||||||
--------
|
|
||||||
|
|
||||||
Branding is done in menuconfig, there are several settings affecting
|
Branding is done in menuconfig, there are several settings affecting
|
||||||
it, most are in the Infix external subsection called "Branding", but
|
it, most are in the Infix external subsection called "Branding", but
|
||||||
@@ -24,25 +22,18 @@ check this for you and you may end up with odd results.
|
|||||||
|
|
||||||
Verify the result after a build by inspecting:
|
Verify the result after a build by inspecting:
|
||||||
|
|
||||||
- `output/images/*`: names, missing prefix, etc.
|
- `output/images/*`: names, missing prefix, etc.
|
||||||
- `output/target/etc/os-release`: this file is sourced by
|
- `output/target/etc/os-release`: this file is sourced by other build
|
||||||
other build scripts, e.g., `mkgns3a.sh`. For reference, see
|
scripts, e.g., `mkgns3a.sh`. For reference, see [os-release(5)][]
|
||||||
https://www.freedesktop.org/software/systemd/man/os-release.html
|
|
||||||
|
|
||||||
> **Note:** to get proper GIT revision (hash) from your composed OS,
|
> [!IMPORTANT]
|
||||||
> remember in menuconfig to set `INFIX_OEM_PATH`. When unset the
|
> To get a proper GIT revision (hash) from your OS spin, remember to set
|
||||||
> Infix `post-build.sh` script defaults to the Infix base path. The
|
> in menuconfig `INFIX_OEM_PATH`. When unset, the Infix `post-build.sh`
|
||||||
> revision is stored in the file `/etc/os-release` as BUILD_ID and
|
> script defaults to the Infix base path. The revision is stored in the
|
||||||
> is also in the file `/etc/version`. See below for more info.
|
> file `/etc/os-release` as `BUILD_ID`, also in the file `/etc/version`.
|
||||||
|
> See below for more info.
|
||||||
|
|
||||||
[^1]: The base MAC address is defined in the device's Vital Product
|
## Factory & Failure Config
|
||||||
Data (VPD) EEPROM, or similar, which is used by the kernel to
|
|
||||||
create the system interfaces. This MAC address is usually also
|
|
||||||
printed on a label on the device.
|
|
||||||
|
|
||||||
|
|
||||||
Factory & Failure Config
|
|
||||||
------------------------
|
|
||||||
|
|
||||||
To support booting the same image (CPU architecture) on multiple boards,
|
To support booting the same image (CPU architecture) on multiple boards,
|
||||||
Infix by default generates the device's initial configuration every time
|
Infix by default generates the device's initial configuration every time
|
||||||
@@ -56,7 +47,6 @@ However, for custom builds of Infix it is possible to override this with
|
|||||||
a single static `/etc/factory-config.cfg` (and failure-config) in your
|
a single static `/etc/factory-config.cfg` (and failure-config) in your
|
||||||
rootfs overlay -- with a [VPD](vpd.md) you can even support several!
|
rootfs overlay -- with a [VPD](vpd.md) you can even support several!
|
||||||
|
|
||||||
|
|
||||||
### Variables & Format Specifiers
|
### Variables & Format Specifiers
|
||||||
|
|
||||||
Parts of the configuration you likely always want to generated, like the
|
Parts of the configuration you likely always want to generated, like the
|
||||||
@@ -65,22 +55,22 @@ unique (per-device with a VPD) password hash. This section lists the
|
|||||||
available keywords, see the next section for examples of how to use
|
available keywords, see the next section for examples of how to use
|
||||||
them:
|
them:
|
||||||
|
|
||||||
- **Default password hash:** `$factory$` (from VPD, .dtb, or built-in)
|
- **Default password hash:** `$factory$` (from VPD, .dtb, or built-in)
|
||||||
XPath: `/ietf-system:system/authentication/user/password`
|
XPath: `/ietf-system:system/authentication/user/password`
|
||||||
- **Default SSH and NETCONF hostkey:** `genkey` (regenerated at factory reset)
|
- **Default SSH and NETCONF hostkey:** `genkey` (regenerated at factory reset)
|
||||||
XPath: `/ietf-keystore:keystore/asymmetric-keys/asymmetric-key[name='genkey']`
|
XPath: `/ietf-keystore:keystore/asymmetric-keys/asymmetric-key[name='genkey']`
|
||||||
- **Hostname format specifiers:**
|
- **Hostname format specifiers:**
|
||||||
XPath: `/ietf-system:system/hostname`
|
XPath: `/ietf-system:system/hostname`
|
||||||
- `%i`: OS ID, from `/etc/os-release`, from Menuconfig branding
|
- `%i`: OS ID, from `/etc/os-release`, from Menuconfig branding
|
||||||
- `%h`: Default hostname, from `/etc/os-release`, from branding
|
- `%h`: Default hostname, from `/etc/os-release`, from branding
|
||||||
- `%m`: NIC specific part of base MAC, e.g., to `c0-ff-ee`
|
- `%m`: NIC specific part of base MAC, e.g., to `c0-ff-ee`
|
||||||
- `%%`: Literal %
|
- `%%`: Literal %
|
||||||
|
|
||||||
|
|
||||||
### Static Files
|
### Static Files
|
||||||
|
|
||||||
> **Caveat:** maintaining static a factory-config and failure-config may
|
> [!CAUTION]
|
||||||
> seem like an obvious choice, but as YANG models evolve (even the IETF
|
> Maintaining a static `factory-config` and `failure-config` may seem
|
||||||
|
> like an obvious choice, but as YANG models evolve (even the IETF
|
||||||
> models get upgraded), you may need to upgrade your static files.
|
> models get upgraded), you may need to upgrade your static files.
|
||||||
|
|
||||||
First, for one-off builds (one image per product), the simplest way is
|
First, for one-off builds (one image per product), the simplest way is
|
||||||
@@ -103,9 +93,8 @@ after `00-probe` has run. The lower case version of the string is used.
|
|||||||
|
|
||||||
I.e., create a rootfs overlay that provides any combination of:
|
I.e., create a rootfs overlay that provides any combination of:
|
||||||
|
|
||||||
- `/usr/share/product/<PRODUCT>/etc/factory-config.cfg`
|
- `/usr/share/product/<PRODUCT>/etc/factory-config.cfg`
|
||||||
- `/usr/share/product/<PRODUCT>/etc/failure-config.cfg`
|
- `/usr/share/product/<PRODUCT>/etc/failure-config.cfg`
|
||||||
|
|
||||||
|
|
||||||
### Dynamically Generated
|
### Dynamically Generated
|
||||||
|
|
||||||
@@ -113,14 +102,14 @@ The generated `factory-config` and `failure-config` files consist of
|
|||||||
both static JSON files and part generated files at runtime for each
|
both static JSON files and part generated files at runtime for each
|
||||||
device. The resulting files are written to the RAM disk in `/run`:
|
device. The resulting files are written to the RAM disk in `/run`:
|
||||||
|
|
||||||
- `/run/confd/factory-config.gen`
|
- `/run/confd/factory-config.gen`
|
||||||
- `/run/confd/failure-config.gen`
|
- `/run/confd/failure-config.gen`
|
||||||
|
|
||||||
Provided no custom overrides (see above) have been installed already,
|
Provided no custom overrides (see above) have been installed already,
|
||||||
these files are then copied to:
|
these files are then copied to:
|
||||||
|
|
||||||
- `/etc/factory-config.cfg`
|
- `/etc/factory-config.cfg`
|
||||||
- `/etc/failure-config.cfg`
|
- `/etc/failure-config.cfg`
|
||||||
|
|
||||||
... where the bootstrap process expects them to be in the next step.
|
... where the bootstrap process expects them to be in the next step.
|
||||||
|
|
||||||
@@ -132,29 +121,33 @@ base hostname, set `BR2_TARGET_GENERIC_HOSTNAME` in your defconfig.
|
|||||||
The static files are installed by Infix `confd` in `/usr/share/confd/`
|
The static files are installed by Infix `confd` in `/usr/share/confd/`
|
||||||
at build time. It contains two subdirectories:
|
at build time. It contains two subdirectories:
|
||||||
|
|
||||||
/usr/share/confd/
|
```
|
||||||
|- factory.d/
|
/usr/share/confd/
|
||||||
| |- 10-foo.json
|
|- factory.d/
|
||||||
| |- 10-bar.json
|
| |- 10-foo.json
|
||||||
| `- 10-qux.json
|
| |- 10-bar.json
|
||||||
`- failure.d/
|
| `- 10-qux.json
|
||||||
|- 10-xyzzy.json
|
`- failure.d/
|
||||||
`- 10-garply.json
|
|- 10-xyzzy.json
|
||||||
|
`- 10-garply.json
|
||||||
|
```
|
||||||
|
|
||||||
To override, or extend, these files in you br2-external, set up a rootfs
|
To override, or extend, these files in you br2-external, set up a rootfs
|
||||||
overlay and add it last in `BR2_ROOTFS_OVERLAY`. Your overlay can look
|
overlay and add it last in `BR2_ROOTFS_OVERLAY`. Your overlay can look
|
||||||
something like this:
|
something like this:
|
||||||
|
|
||||||
./board/common/rootfs/
|
```
|
||||||
|- etc/
|
./board/common/rootfs/
|
||||||
| |- confdrc # See below
|
|- etc/
|
||||||
| `- confdrc.local
|
| |- confdrc # See below
|
||||||
`- usr/
|
| `- confdrc.local
|
||||||
`- share/
|
`- usr/
|
||||||
`- confd/
|
`- share/
|
||||||
|- 10-foo.json # Override Infix foo
|
`- confd/
|
||||||
|- 30-bar.json # Extend, probably 10-bar.json
|
|- 10-foo.json # Override Infix foo
|
||||||
`- 30-fred.json # Extend, your own defaults
|
|- 30-bar.json # Extend, probably 10-bar.json
|
||||||
|
`- 30-fred.json # Extend, your own defaults
|
||||||
|
```
|
||||||
|
|
||||||
Using the same filename in your overlay, here `10-foo.json`, completely
|
Using the same filename in your overlay, here `10-foo.json`, completely
|
||||||
replaces the contents of the same file provided by Infix. If you just
|
replaces the contents of the same file provided by Infix. If you just
|
||||||
@@ -168,17 +161,17 @@ provide a few custom ones that the `bootstrap` knows about, e.g.,
|
|||||||
`gen-ifs-custom` that overrides `20-interfaces.json`. See the
|
`gen-ifs-custom` that overrides `20-interfaces.json`. See the
|
||||||
bootstrap script for more help, and up-to-date information.
|
bootstrap script for more help, and up-to-date information.
|
||||||
|
|
||||||
> **Note:** you may not need to provide your own `/etc/confdrc`. The
|
> [!TIP]
|
||||||
> one installed by `confd` is usually enough. However, if you want to
|
> You may not need to provide your own `/etc/confdrc` for your spin.
|
||||||
> adjust the behavior of `bootstrap` you may want to override it. There
|
> The one installed by `confd` is usually enough. However, if you want
|
||||||
> is also `confdrc.local`, which usually is enough to change arguments
|
> to adjust the behavior of `bootstrap` you may want to override it.
|
||||||
> to scripts like `gen-interfaces`, e.g., to create a bridge by default,
|
> There is also `confdrc.local`, which usually is enough to change
|
||||||
> you may want to look into `GEN_IFACE_OPTS`.
|
> arguments to scripts like `gen-interfaces`, e.g., to create a bridge
|
||||||
|
> by default, you may want to look into `GEN_IFACE_OPTS`.
|
||||||
|
|
||||||
### Example Snippets
|
### Example Snippets
|
||||||
|
|
||||||
**IETF System:**
|
#### IETF System
|
||||||
|
|
||||||
```hsib
|
```hsib
|
||||||
"ietf-system:system": {
|
"ietf-system:system": {
|
||||||
@@ -211,15 +204,16 @@ bootstrap script for more help, and up-to-date information.
|
|||||||
The `motd-banner` is a binary type, which is basically a Base64 encoded
|
The `motd-banner` is a binary type, which is basically a Base64 encoded
|
||||||
text file without line breaks (`-w0`):
|
text file without line breaks (`-w0`):
|
||||||
|
|
||||||
```bash
|
```
|
||||||
$ echo "Li0tLS0tLS0uCnwgIC4gLiAgfCBJbmZpeCAtLSBhIE5ldHdvcmsgT3BlcmF0aW5nIFN5c3RlbQp8LS4gdiAuLXwgaHR0cHM6Ly9rZXJuZWxraXQuZ2l0aHViLmlvCictJy0tLSctJwo=" |base64 -d
|
$ echo "Li0tLS0tLS0uCnwgIC4gLiAgfCBJbmZpeCAtLSBhIE5ldHdvcmsgT3BlcmF0aW5nIFN5c3RlbQp8LS4gdiAuLXwgaHR0cHM6Ly9rZXJuZWxraXQuZ2l0aHViLmlvCictJy0tLSctJwo=" \
|
||||||
|
| base64 -d
|
||||||
.-------.
|
.-------.
|
||||||
| . . | Infix OS — Immutable.Friendly.Secure
|
| . . | Infix OS — Immutable.Friendly.Secure
|
||||||
|-. v .-| https://kernelkit.github.io
|
|-. v .-| https://kernelkit.github.io
|
||||||
'-'---'-'
|
'-'---'-'
|
||||||
```
|
```
|
||||||
|
|
||||||
**IETF Keystore**
|
#### IETF Keystore
|
||||||
|
|
||||||
Notice how both the public and private keys are left empty here, this
|
Notice how both the public and private keys are left empty here, this
|
||||||
cause them to be always automatically regenerated after each factory reset.
|
cause them to be always automatically regenerated after each factory reset.
|
||||||
@@ -245,7 +239,7 @@ use-case and not documented here.
|
|||||||
},
|
},
|
||||||
```
|
```
|
||||||
|
|
||||||
**IETF NETCONF Server**
|
#### IETF NETCONF Server
|
||||||
|
|
||||||
```json
|
```json
|
||||||
"ietf-netconf-server:netconf-server": {
|
"ietf-netconf-server:netconf-server": {
|
||||||
@@ -278,7 +272,8 @@ use-case and not documented here.
|
|||||||
},
|
},
|
||||||
```
|
```
|
||||||
|
|
||||||
**Infix Services**
|
#### Infix Services
|
||||||
|
|
||||||
```json
|
```json
|
||||||
"infix-services:ssh": {
|
"infix-services:ssh": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
@@ -300,10 +295,7 @@ use-case and not documented here.
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Integration
|
||||||
|
|
||||||
Integration
|
|
||||||
-----------
|
|
||||||
|
|
||||||
When integrating your software stack with Infix there may be protocols
|
When integrating your software stack with Infix there may be protocols
|
||||||
that want to change system settings like hostname and dynamically set
|
that want to change system settings like hostname and dynamically set
|
||||||
@@ -344,8 +336,8 @@ activate all.)
|
|||||||
|
|
||||||
You can consider the system composed of two entities:
|
You can consider the system composed of two entities:
|
||||||
|
|
||||||
- NETCONF starts up the system using `startup-config`, then
|
- NETCONF starts up the system using `startup-config`, then
|
||||||
- Hands over control to your application at runtime
|
- Hands over control to your application at runtime
|
||||||
|
|
||||||
Infix is prepared for this by already having two "runlevels" for these
|
Infix is prepared for this by already having two "runlevels" for these
|
||||||
two states. The `startup-config` is applied in runlevel S (bootstrap)
|
two states. The `startup-config` is applied in runlevel S (bootstrap)
|
||||||
@@ -359,9 +351,7 @@ E.g., to prevent changes to startup after initial deployment. In
|
|||||||
that case a proper factory reset would be needed to get back to a
|
that case a proper factory reset would be needed to get back to a
|
||||||
"pre-deployment" state where you can reconfigure your baseline.
|
"pre-deployment" state where you can reconfigure your baseline.
|
||||||
|
|
||||||
|
## Releases
|
||||||
Releases
|
|
||||||
--------
|
|
||||||
|
|
||||||
A release build requires the global variable `INFIX_RELEASE` to be set.
|
A release build requires the global variable `INFIX_RELEASE` to be set.
|
||||||
It can be derived from GIT, if the source tree is kept in GIT VCS. First,
|
It can be derived from GIT, if the source tree is kept in GIT VCS. First,
|
||||||
@@ -371,14 +361,14 @@ let us talk about versioning in general.
|
|||||||
|
|
||||||
Two popular scheme for versioning a product derived from Infix:
|
Two popular scheme for versioning a product derived from Infix:
|
||||||
|
|
||||||
1. Track Infix major.minor, e.g. *Foobar v23.08.z*, where `z` is
|
1. Track Infix major.minor, e.g. *Foobar v23.08.z*, where `z` is
|
||||||
your patch level. I.e., Foobar v23.08.0 could be based on Infix
|
your patch level. I.e., Foobar v23.08.0 could be based on Infix
|
||||||
v23.08.0, or v23.08.12, it is up to you. Maybe you based it on
|
v23.08.0, or v23.08.12, it is up to you. Maybe you based it on
|
||||||
v23.08.12 and then back ported changes from v23.10.0, but it was
|
v23.08.12 and then back ported changes from v23.10.0, but it was
|
||||||
the first release you made to your customer(s).
|
the first release you made to your customer(s).
|
||||||
2. Start from v1.0.0 and step the major number every time you sync
|
1. Start from v1.0.0 and step the major number every time you sync
|
||||||
with a new Infix release, or every time Infix bumps to the next
|
with a new Infix release, or every time Infix bumps to the next
|
||||||
Buildroot LTS.
|
Buildroot LTS.
|
||||||
|
|
||||||
The important thing is to be consistent, not only for your own sake,
|
The important thing is to be consistent, not only for your own sake,
|
||||||
but also for your end customers. The *major.minor.patch* style is
|
but also for your end customers. The *major.minor.patch* style is
|
||||||
@@ -386,10 +376,10 @@ the most common and often recommended style, which usually maps well
|
|||||||
to other systems, e.g. PROFINET GSDML files require this (*VX.Y.Z*).
|
to other systems, e.g. PROFINET GSDML files require this (*VX.Y.Z*).
|
||||||
But you can of course use only two numbers, *major.minor*, as well.
|
But you can of course use only two numbers, *major.minor*, as well.
|
||||||
|
|
||||||
|
> [!WARNING]
|
||||||
> What could be confusing, however, is if you use the name *Infix*
|
> What could be confusing, however, is if you use the name *Infix*
|
||||||
> with your own versioning scheme.
|
> with your own versioning scheme.
|
||||||
|
|
||||||
|
|
||||||
### Specifying Versioning Information
|
### Specifying Versioning Information
|
||||||
|
|
||||||
Two optional environment variables control the version information
|
Two optional environment variables control the version information
|
||||||
@@ -416,4 +406,10 @@ generated file names like disk images, etc.
|
|||||||
|
|
||||||
**Default:** `${INFIX_BUILD_ID}`
|
**Default:** `${INFIX_BUILD_ID}`
|
||||||
|
|
||||||
[NanoPi R2S]: https://github.com/kernelkit/infix/blob/main/board/aarch64/r2s/rootfs/etc/factory-config.cfg
|
[^1]: The base MAC address is defined in the device's Vital Product
|
||||||
|
Data (VPD) EEPROM, or similar, which is used by the kernel to
|
||||||
|
create the system interfaces. This MAC address is usually also
|
||||||
|
printed on a label on the device.
|
||||||
|
|
||||||
|
[NanoPi R2S]: https://github.com/kernelkit/infix/blob/main/board/aarch64/r2s/rootfs/etc/factory-config.cfg
|
||||||
|
[os-release(5)]: https://www.freedesktop.org/software/systemd/man/os-release.html
|
||||||
|
|||||||
+4
-4
@@ -51,9 +51,10 @@ Linux to use.
|
|||||||
|
|
||||||
### Configure USB port
|
### Configure USB port
|
||||||
|
|
||||||
> **Note:** You can only configure USB ports known to the system. See
|
> [!NOTE]
|
||||||
> `show hardware` in admin-exec context. (Use `do` prefix in configure
|
> You can only configure USB ports known to the system. See the CLI
|
||||||
> context.)
|
> command `show hardware` in admin-exec context. (Use `do` prefix in
|
||||||
|
> configure context.)
|
||||||
|
|
||||||
```
|
```
|
||||||
admin@example:/> configure
|
admin@example:/> configure
|
||||||
@@ -84,5 +85,4 @@ cached data to disk before returning the prompt:
|
|||||||
admin@example:~$ sudo umount /media/log
|
admin@example:~$ sudo umount /media/log
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
[1]: https://www.rfc-editor.org/rfc/rfc8348.html
|
[1]: https://www.rfc-editor.org/rfc/rfc8348.html
|
||||||
|
|||||||
+36
-33
@@ -8,10 +8,10 @@ details how to log to external media or remote syslog servers.
|
|||||||
It is also possible to set up the device to act as a syslog server (log
|
It is also possible to set up the device to act as a syslog server (log
|
||||||
sink), this is covered briefly at the very end of this document.
|
sink), this is covered briefly at the very end of this document.
|
||||||
|
|
||||||
> **Note:** the native logging cannot be modified, only the log file
|
> [!NOTE]
|
||||||
> rotation can be changed. Please see the `dir` admin-exec command for
|
> The default logging setup in the system cannot be modified, only the
|
||||||
> a listing of existing native log files.
|
> log file rotation. Please see the `dir` admin-exec command for a
|
||||||
|
> listing of existing log files.
|
||||||
|
|
||||||
## Log to File
|
## Log to File
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ an example.
|
|||||||
|
|
||||||
For a list of available log facilities, see the table in a later section.
|
For a list of available log facilities, see the table in a later section.
|
||||||
|
|
||||||
```bash
|
```
|
||||||
admin@example:/> configure
|
admin@example:/> configure
|
||||||
admin@example:/config/> edit syslog
|
admin@example:/config/> edit syslog
|
||||||
admin@example:/config/syslog/> edit actions log-file file:/media/log/mylog
|
admin@example:/config/syslog/> edit actions log-file file:/media/log/mylog
|
||||||
@@ -37,11 +37,11 @@ admin@example:/config/syslog/actions/log-file/file:/media/log/mylog/> leave
|
|||||||
admin@example:/>
|
admin@example:/>
|
||||||
```
|
```
|
||||||
|
|
||||||
> **Note:** the `log-file` syntax requires the leading prefix `file:`.
|
> [!IMPORTANT]
|
||||||
> If the path is not absolute, e.g., `file:mylog`, the file is saved to
|
> The `log-file` syntax requires the leading prefix `file:`. If the
|
||||||
> the system default path, i.e., `/log/mylog`. In this case, verify
|
> path is not absolute, e.g., `file:mylog`, the file is saved to the
|
||||||
> that the filename is not already in use.
|
> system default path, i.e., `/log/mylog`. In this case, verify that
|
||||||
|
> the filename is not already in use.
|
||||||
|
|
||||||
## Log Rotation
|
## Log Rotation
|
||||||
|
|
||||||
@@ -51,13 +51,16 @@ disk with outdated logs. A rotated file is saved in stages and older
|
|||||||
ones are also compressed (using `gzip`). Use the `show log` command in
|
ones are also compressed (using `gzip`). Use the `show log` command in
|
||||||
admin-exec context to start the log file viewer:
|
admin-exec context to start the log file viewer:
|
||||||
|
|
||||||
admin@example:/config/syslog/> do show log
|
```
|
||||||
log log.0 log.1.gz log.2.gz log.3.gz log.4.gz log.5.gz
|
admin@example:/config/syslog/> do show log
|
||||||
admin@example:/config/syslog/> do show log log.1.gz
|
log log.0 log.1.gz log.2.gz log.3.gz log.4.gz log.5.gz
|
||||||
|
admin@example:/config/syslog/> do show log log.1.gz
|
||||||
|
```
|
||||||
|
|
||||||
> **Tip:** use the Tab key on your keyboard list available log files.
|
> [!TIP]
|
||||||
> The `do` prefix is also very useful in configure context to access
|
> Use the Tab key on your keyboard list available log files. The `do`
|
||||||
> commands from admin-exec context.
|
> prefix is also very useful in configure context to access commands
|
||||||
|
> from admin-exec context.
|
||||||
|
|
||||||
By default 10 compressed older files are saved. Here the oldest is
|
By default 10 compressed older files are saved. Here the oldest is
|
||||||
`log.5.gz` and the most recently rotated one is `log.0`.
|
`log.5.gz` and the most recently rotated one is `log.0`.
|
||||||
@@ -66,7 +69,7 @@ Log file rotation can be configured both globally and per log file.
|
|||||||
Here we show the global settings, the set up is the same for per log
|
Here we show the global settings, the set up is the same for per log
|
||||||
file, which if unset inherit the global settings:
|
file, which if unset inherit the global settings:
|
||||||
|
|
||||||
```bash
|
```
|
||||||
admin@example:/> configure
|
admin@example:/> configure
|
||||||
admin@example:/config/> edit syslog file-rotation
|
admin@example:/config/> edit syslog file-rotation
|
||||||
admin@example:/config/syslog/file-rotation/> show
|
admin@example:/config/syslog/file-rotation/> show
|
||||||
@@ -76,7 +79,7 @@ admin@example:/config/syslog/file-rotation/>
|
|||||||
The defaults are not shown. We can inspect them by asking the YANG
|
The defaults are not shown. We can inspect them by asking the YANG
|
||||||
model for the help texts:
|
model for the help texts:
|
||||||
|
|
||||||
```bash
|
```
|
||||||
admin@example:/config/syslog/file-rotation/> help
|
admin@example:/config/syslog/file-rotation/> help
|
||||||
max-file-size number-of-files
|
max-file-size number-of-files
|
||||||
admin@example:/config/syslog/file-rotation/> help max-file-size
|
admin@example:/config/syslog/file-rotation/> help max-file-size
|
||||||
@@ -102,7 +105,7 @@ DEFAULT
|
|||||||
To change the defaults to something smaller, 512 kiB and 20 (remember
|
To change the defaults to something smaller, 512 kiB and 20 (remember
|
||||||
everything after .0 is compressed, and text compresses well):
|
everything after .0 is compressed, and text compresses well):
|
||||||
|
|
||||||
```bash
|
```
|
||||||
admin@example:/config/syslog/file-rotation/> set max-file-size 512
|
admin@example:/config/syslog/file-rotation/> set max-file-size 512
|
||||||
admin@example:/config/syslog/file-rotation/> set number-of-files 20
|
admin@example:/config/syslog/file-rotation/> set number-of-files 20
|
||||||
admin@example:/config/syslog/file-rotation/> show
|
admin@example:/config/syslog/file-rotation/> show
|
||||||
@@ -112,7 +115,6 @@ admin@example:/config/syslog/file-rotation/> leave
|
|||||||
admin@example:/>
|
admin@example:/>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## Log Format
|
## Log Format
|
||||||
|
|
||||||
There are three major syslog log formats, the default is [RFC3164][] for
|
There are three major syslog log formats, the default is [RFC3164][] for
|
||||||
@@ -121,9 +123,11 @@ and remote log server capabilities, or policies, the [RFC5424][] format
|
|||||||
is often preferred since it not only has better time resolution but also
|
is often preferred since it not only has better time resolution but also
|
||||||
supports structured logging:
|
supports structured logging:
|
||||||
|
|
||||||
BSD : myproc[8710]: Kilroy was here.
|
```
|
||||||
RFC3164 : Aug 24 05:14:15 192.0.2.1 myproc[8710]: Kilroy was here.
|
BSD : myproc[8710]: Kilroy was here.
|
||||||
RFC5424 : 2003-08-24T05:14:15.000003-07:00 192.0.2.1 myproc 8710 - - Kilroy was here.
|
RFC3164 : Aug 24 05:14:15 192.0.2.1 myproc[8710]: Kilroy was here.
|
||||||
|
RFC5424 : 2003-08-24T05:14:15.000003-07:00 192.0.2.1 myproc 8710 - - Kilroy was here.
|
||||||
|
```
|
||||||
|
|
||||||
The BSD format is only applicable to remote logging. It remains the
|
The BSD format is only applicable to remote logging. It remains the
|
||||||
default for compatibility reasons, and is recommended since the device
|
default for compatibility reasons, and is recommended since the device
|
||||||
@@ -132,7 +136,7 @@ perform time stamping at the time of arrival.
|
|||||||
|
|
||||||
Configuring the log format is the same for log files and remotes:
|
Configuring the log format is the same for log files and remotes:
|
||||||
|
|
||||||
```bash
|
```
|
||||||
admin@example:/config/> edit syslog actions log-file file:foobar
|
admin@example:/config/> edit syslog actions log-file file:foobar
|
||||||
admin@example:/config/syslog/actions/log-file/file:foobar/> set log-format
|
admin@example:/config/syslog/actions/log-file/file:foobar/> set log-format
|
||||||
bsd rfc3164 rfc5424
|
bsd rfc3164 rfc5424
|
||||||
@@ -141,9 +145,6 @@ admin@example:/config/syslog/actions/log-file/file:foobar/> leave
|
|||||||
admin@example:/>
|
admin@example:/>
|
||||||
```
|
```
|
||||||
|
|
||||||
[RFC3164]: https://datatracker.ietf.org/doc/html/rfc3164
|
|
||||||
[RFC5424]: https://datatracker.ietf.org/doc/html/rfc5424
|
|
||||||
|
|
||||||
## Log to Remote Server
|
## Log to Remote Server
|
||||||
|
|
||||||
Logging to a remote syslog server is the recommended way of supervising
|
Logging to a remote syslog server is the recommended way of supervising
|
||||||
@@ -158,7 +159,7 @@ remote syslog servers do not support receiving time stamped log messages
|
|||||||
-- this is of course entirely dependent on how the remote server is set
|
-- this is of course entirely dependent on how the remote server is set
|
||||||
up, as well as local policy.
|
up, as well as local policy.
|
||||||
|
|
||||||
```bash
|
```
|
||||||
admin@example:/config/> edit syslog
|
admin@example:/config/> edit syslog
|
||||||
actions file-rotation server
|
actions file-rotation server
|
||||||
admin@example:/config/> edit syslog actions destination moon
|
admin@example:/config/> edit syslog actions destination moon
|
||||||
@@ -172,16 +173,16 @@ admin@example:/config/syslog/actions/destination/moon/> leave
|
|||||||
admin@example:/>
|
admin@example:/>
|
||||||
```
|
```
|
||||||
|
|
||||||
> **Note:** the alternatives shown below each prompt in the example
|
> [!TIP]
|
||||||
> above can be found by tapping the Tab key.
|
> The alternatives shown below each prompt in the example above can be
|
||||||
|
> found by tapping the Tab key.
|
||||||
|
|
||||||
## Acting as a Log Server
|
## Acting as a Log Server
|
||||||
|
|
||||||
The syslog server can act as a log sink for other devices on a LAN. For
|
The syslog server can act as a log sink for other devices on a LAN. For
|
||||||
this to work you need a static IP address, here we use 10.0.0.1/24.
|
this to work you need a static IP address, here we use 10.0.0.1/24.
|
||||||
|
|
||||||
```bash
|
```
|
||||||
admin@example:/> configure
|
admin@example:/> configure
|
||||||
admin@example:/config/> edit syslog server
|
admin@example:/config/> edit syslog server
|
||||||
admin@example:/config/syslog/server/> set enabled true
|
admin@example:/config/syslog/server/> set enabled true
|
||||||
@@ -194,7 +195,6 @@ See the above [Log to File](#log-to-file) section on how to set up
|
|||||||
filtering of received logs to local files. Please note, filtering based
|
filtering of received logs to local files. Please note, filtering based
|
||||||
on property, e.g., hostname, is not supported yet.
|
on property, e.g., hostname, is not supported yet.
|
||||||
|
|
||||||
|
|
||||||
### Facilities
|
### Facilities
|
||||||
|
|
||||||
| **Code** | **Facility** | **Description** |
|
| **Code** | **Facility** | **Description** |
|
||||||
@@ -225,3 +225,6 @@ on property, e.g., hostname, is not supported yet.
|
|||||||
| 23 | web* | local7, reserved for nginx web server |
|
| 23 | web* | local7, reserved for nginx web server |
|
||||||
|
|
||||||
Facilities marked `*` are local augments to the model.
|
Facilities marked `*` are local augments to the model.
|
||||||
|
|
||||||
|
[RFC3164]: https://datatracker.ietf.org/doc/html/rfc3164
|
||||||
|
[RFC5424]: https://datatracker.ietf.org/doc/html/rfc5424
|
||||||
|
|||||||
+161
-114
@@ -1,19 +1,16 @@
|
|||||||
Regression Testing with Infamy
|
# Regression Testing with Infamy
|
||||||
==============================
|
|
||||||
|
|
||||||
Infix comes with a test suite that is intended to provide end-to-end
|
Infix comes with a test suite that is intended to provide end-to-end
|
||||||
verification of supported features. Generally speaking, this means
|
verification of supported features. Generally speaking, this means that
|
||||||
that one or more DUTs are configured over NETCONF; the resulting
|
one or more DUTs are configured over NETCONF or RESTCONF; the resulting
|
||||||
network is then black-box tested by injecting and inspecting network
|
network is then black-box tested by injecting and inspecting network
|
||||||
traffic at various points.
|
traffic at various points.
|
||||||
|
|
||||||
This document is intended to be a practical guide on how to run,
|
This document is intended to be a practical guide on how to run, develop
|
||||||
develop and debug tests. There is a separate document describing the
|
and debug tests. There is a separate document describing the [Test
|
||||||
[Test System Architecture](test-arch.md).
|
System Architecture](test-arch.md).
|
||||||
|
|
||||||
|
## Modes of Testing
|
||||||
Modes of Testing
|
|
||||||
----------------
|
|
||||||
|
|
||||||
### Virtual Devices
|
### Virtual Devices
|
||||||
|
|
||||||
@@ -21,23 +18,33 @@ By default, tests are run on a topology made up of virtual Infix nodes
|
|||||||
using [Qeneth][]. To run the full regression test suite: build Infix
|
using [Qeneth][]. To run the full regression test suite: build Infix
|
||||||
for `x86_64`:
|
for `x86_64`:
|
||||||
|
|
||||||
$ make x86_64_defconfig
|
```
|
||||||
$ make
|
$ make x86_64_defconfig
|
||||||
$ make test
|
...
|
||||||
|
$ make
|
||||||
|
...
|
||||||
|
$ make test
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
### Physical Devices
|
### Physical Devices
|
||||||
|
|
||||||
To run the tests on a preexisting topology from the host's network
|
To run the tests on a preexisting topology from the host's network
|
||||||
namespace, specify the `host` `TEST_MODE`:
|
namespace, specify the `host` `TEST_MODE`:
|
||||||
|
|
||||||
$ make TEST_MODE=host test
|
```
|
||||||
|
$ make TEST_MODE=host test
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
This typically used when testing on physical hardware. By default the
|
This typically used when testing on physical hardware. By default the
|
||||||
topology will be sourced from `/etc/infamy.dot`, but this can be
|
topology will be sourced from `/etc/infamy.dot`, but this can be
|
||||||
overwritten by setting the `TOPOLOGY` variable:
|
overwritten by setting the `TOPOLOGY` variable:
|
||||||
|
|
||||||
$ make TEST_MODE=host TOPOLOGY=~/my-topology.dot test
|
```
|
||||||
|
$ make TEST_MODE=host TOPOLOGY=~/my-topology.dot test
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
### `make run` Devices
|
### `make run` Devices
|
||||||
|
|
||||||
@@ -48,26 +55,29 @@ instance is configured to use TAP networking.
|
|||||||
When the instance is running, you can open a separate terminal and run
|
When the instance is running, you can open a separate terminal and run
|
||||||
the subset of the test suite that can be mapped to it:
|
the subset of the test suite that can be mapped to it:
|
||||||
|
|
||||||
$ make TEST_MODE=run test
|
```
|
||||||
|
$ make TEST_MODE=run test
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
## Interactive Usage
|
||||||
Interactive Usage
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
When developing and debugging tests, the overhead of repeatedly
|
When developing and debugging tests, the overhead of repeatedly
|
||||||
setting up and tearing down the test environment can quickly start to
|
setting up and tearing down the test environment can quickly start to
|
||||||
weigh you down. In these situation, you can start an interactive test
|
weigh you down. In these situation, you can start an interactive test
|
||||||
environment:
|
environment:
|
||||||
|
|
||||||
$ make test-sh
|
```
|
||||||
Info: Generating topology
|
$ make test-sh
|
||||||
Info: Generating node YAML
|
Info: Generating topology
|
||||||
Info: Generating executables
|
Info: Generating node YAML
|
||||||
Info: Launching dut1
|
Info: Generating executables
|
||||||
Info: Launching dut2
|
Info: Launching dut1
|
||||||
Info: Launching dut3
|
Info: Launching dut2
|
||||||
Info: Launching dut4
|
Info: Launching dut3
|
||||||
11:42:52 infamy0:test #
|
Info: Launching dut4
|
||||||
|
11:42:52 infamy0:test #
|
||||||
|
```
|
||||||
|
|
||||||
The example above uses the default mode (`qeneth`), but the `host` and
|
The example above uses the default mode (`qeneth`), but the `host` and
|
||||||
`run` modes also support the `test-sh` target.
|
`run` modes also support the `test-sh` target.
|
||||||
@@ -77,22 +87,27 @@ inside the container running Infamy. It's a very limited environment,
|
|||||||
but it has enough to easily run single tests, connect to the virtual
|
but it has enough to easily run single tests, connect to the virtual
|
||||||
devices, and *step* your code.
|
devices, and *step* your code.
|
||||||
|
|
||||||
|
|
||||||
### Running Subsets of Tests
|
### Running Subsets of Tests
|
||||||
|
|
||||||
Each test case is a separate executable, which can be run without
|
Each test case is a separate executable, which can be run without
|
||||||
arguments:
|
arguments:
|
||||||
|
|
||||||
11:42:53 infamy0:test # ./case/infix_dhcp/dhcp_basic.py
|
```
|
||||||
|
11:42:53 infamy0:test # ./case/infix_dhcp/dhcp_basic.py
|
||||||
|
```
|
||||||
|
|
||||||
To run a suite of tests, e.g., only the DHCP client tests, pass the
|
To run a suite of tests, e.g., only the DHCP client tests, pass the
|
||||||
suite as an argument to [9PM][]:
|
suite as an argument to [9PM][]:
|
||||||
|
|
||||||
11:42:53 infamy0:test # ./9pm/9pm.py case/infix_dhcp/infix_dhcp.yaml
|
```
|
||||||
|
11:42:53 infamy0:test # ./9pm/9pm.py case/infix_dhcp/infix_dhcp.yaml
|
||||||
|
```
|
||||||
|
|
||||||
To run the suite of all tests:
|
To run the suite of all tests:
|
||||||
|
|
||||||
11:42:53 infamy0:test # ./9pm/9pm.py case/all.yaml
|
```
|
||||||
|
11:42:53 infamy0:test # ./9pm/9pm.py case/all.yaml
|
||||||
|
```
|
||||||
|
|
||||||
### Connecting to Infamy
|
### Connecting to Infamy
|
||||||
|
|
||||||
@@ -100,65 +115,76 @@ The test system runs in a Docker container, so to get a shell prompt in
|
|||||||
*another terminal* you need to connect to that container. Infamy comes
|
*another terminal* you need to connect to that container. Infamy comes
|
||||||
with a helper script for this:
|
with a helper script for this:
|
||||||
|
|
||||||
$ ./test/shell
|
```
|
||||||
11:42:53 infamy0:test #
|
$ ./test/shell
|
||||||
|
11:42:53 infamy0:test #
|
||||||
|
```
|
||||||
|
|
||||||
By default it connect to the latest started Infamy instance. If you for
|
By default it connect to the latest started Infamy instance. If you for
|
||||||
some reason run multiple instances of Infamy the `shell` script takes an
|
some reason run multiple instances of Infamy the `shell` script takes an
|
||||||
optional argument "system", which is the hostname of the container you
|
optional argument "system", which is the hostname of the container you
|
||||||
want to connect to:
|
want to connect to:
|
||||||
|
|
||||||
$ ./test/shell infamy2
|
```
|
||||||
11:42:53 infamy2:test #
|
$ ./test/shell infamy2
|
||||||
|
11:42:53 infamy2:test #
|
||||||
|
```
|
||||||
|
|
||||||
### Connecting to a DUT
|
### Connecting to a DUT
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> The `console` script uses `telnet` to connect to a port forwarded to
|
||||||
|
> `localhost` by the Docker container. To exit Telnet, use Ctrl-] and
|
||||||
|
> then 'q' followed by enter. This can be customized in `~/.telnetrc`
|
||||||
|
|
||||||
All DUTs in a virtual Infamy topology are emulated in Qemu instances
|
All DUTs in a virtual Infamy topology are emulated in Qemu instances
|
||||||
managed by qeneth. If you want to watch what's happening on one of the
|
managed by qeneth. If you want to watch what's happening on one of the
|
||||||
target systems, e.g., tail a log file or run `tcpdump` during the test,
|
target systems, e.g., tail a log file or run `tcpdump` during the test,
|
||||||
there is another helper script in Infamy for this:
|
there is another helper script in Infamy for this:
|
||||||
|
|
||||||
$ ./test/console 1
|
```
|
||||||
Trying 127.0.0.1...
|
$ ./test/console 1
|
||||||
Connected to 127.0.0.1.
|
Trying 127.0.0.1...
|
||||||
|
Connected to 127.0.0.1.
|
||||||
|
|
||||||
Infix OS — Immutable.Friendly.Secure v23.11.0-226-g0c144da (console)
|
Infix OS — Immutable.Friendly.Secure v23.11.0-226-g0c144da (console)
|
||||||
infix-00-00-00 login: admin
|
infix-00-00-00 login: admin
|
||||||
Password:
|
Password:
|
||||||
.-------.
|
.-------.
|
||||||
| . . | Infix OS — Immutable.Friendly.Secure
|
| . . | Infix OS — Immutable.Friendly.Secure
|
||||||
|-. v .-| https://kernelkit.org
|
|-. v .-| https://kernelkit.org
|
||||||
'-'---'-'
|
'-'---'-'
|
||||||
|
|
||||||
Run the command 'cli' for interactive OAM
|
Run the command 'cli' for interactive OAM
|
||||||
|
|
||||||
admin@infix-00-00-00:~$
|
admin@infix-00-00-00:~$
|
||||||
|
```
|
||||||
|
|
||||||
From here we can observe `dut1` freely while running tests.
|
From here we can observe `dut1` freely while running tests.
|
||||||
|
|
||||||
> The `console` script uses `telnet` to connect to a port forwarded to
|
|
||||||
> `localhost` by the Docker container. To exit Telnet, use Ctrl-] and
|
|
||||||
> then 'q' followed by enter. This can be customized in `~/.telnetrc`
|
|
||||||
|
|
||||||
Like the `shell` script, `console` takes an optional "system" argument
|
Like the `shell` script, `console` takes an optional "system" argument
|
||||||
in case you run multiple instances of Infamy:
|
in case you run multiple instances of Infamy:
|
||||||
|
|
||||||
$ ./test/console 1 infamy2
|
```
|
||||||
|
$ ./test/console 1 infamy2
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
You can also connect to the console of a DUT from within a `shell`:
|
You can also connect to the console of a DUT from within a `shell`:
|
||||||
|
|
||||||
$ ./test/shell
|
```
|
||||||
11:42:54 infamy0:test # qeneth status
|
$ ./test/shell
|
||||||
11:42:54 infamy0:test # qeneth console dut1
|
11:42:54 infamy0:test # qeneth status
|
||||||
login: admin
|
11:42:54 infamy0:test # qeneth console dut1
|
||||||
password: *****
|
login: admin
|
||||||
admin@infix-00-00-00:~$
|
password: *****
|
||||||
|
admin@infix-00-00-00:~$
|
||||||
> **Note:** disconnect from the qeneth console by using bringing up the
|
```
|
||||||
> old Telnet "menu" using Ctrl-], compared to standard Telnet this is
|
|
||||||
> the BusyBox version so you press 'e' + enter instead of 'q' to quit.
|
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> Disconnect from the qeneth console by bringing up the old Telnet
|
||||||
|
> "menu" using Ctrl-], compared to standard Telnet this is the BusyBox
|
||||||
|
> version so you press 'e' + enter instead of 'q' to quit.
|
||||||
|
|
||||||
### Attaching to MACVLANs
|
### Attaching to MACVLANs
|
||||||
|
|
||||||
@@ -171,27 +197,32 @@ interactively inject traffic into the test setup.
|
|||||||
|
|
||||||
First, connect to the Infamy instance in question:
|
First, connect to the Infamy instance in question:
|
||||||
|
|
||||||
$ ./test/shell
|
```
|
||||||
11:43:19 infamy0:test #
|
$ ./test/shell
|
||||||
|
11:43:19 infamy0:test #
|
||||||
|
```
|
||||||
|
|
||||||
Then, attach to the MACVLAN namespace by running the `nsenter` helper
|
Then, attach to the MACVLAN namespace by running the `nsenter` helper
|
||||||
script from the test directory, supplying the base interface name as
|
script from the test directory, supplying the base interface name as
|
||||||
the first argument:
|
the first argument:
|
||||||
|
|
||||||
11:43:19 infamy0:test # ./nsenter d1b
|
```
|
||||||
11:43:20 infamy0(d1b):test #
|
11:43:19 infamy0:test # ./nsenter d1b
|
||||||
|
11:43:20 infamy0(d1b):test #
|
||||||
|
```
|
||||||
|
|
||||||
By default, an interactive shell is started, but you can also supply
|
By default, an interactive shell is started, but you can also supply
|
||||||
another command:
|
another command:
|
||||||
|
|
||||||
11:43:19 infamy0:test # ./nsenter d1b ip -br addr
|
```
|
||||||
lo UNKNOWN 127.0.0.1/8 ::1/128
|
11:43:19 infamy0:test # ./nsenter d1b ip -br addr
|
||||||
iface@if7 UP 10.0.0.1/24 fe80::38d0:88ff:fe77:b7cd/64
|
lo UNKNOWN 127.0.0.1/8 ::1/128
|
||||||
|
iface@if7 UP 10.0.0.1/24 fe80::38d0:88ff:fe77:b7cd/64
|
||||||
|
```
|
||||||
|
|
||||||
You can now freely debug the network activity of your test and the
|
You can now freely debug the network activity of your test and the
|
||||||
responses from the DUT.
|
responses from the DUT.
|
||||||
|
|
||||||
|
|
||||||
### Using the Python Debugger
|
### Using the Python Debugger
|
||||||
|
|
||||||
The built in `breakpoint()` function in Python is very useful when you
|
The built in `breakpoint()` function in Python is very useful when you
|
||||||
@@ -202,13 +233,15 @@ Simply insert a call to `breakpoint()` at the point of interest in
|
|||||||
your test and run it as normal. Once Python executes the call, it will
|
your test and run it as normal. Once Python executes the call, it will
|
||||||
drop you into the Python debugger:
|
drop you into the Python debugger:
|
||||||
|
|
||||||
11:42:58 infamy0:test # ./case/infix_dhcp/dhcp_basic.py
|
```
|
||||||
# Starting (2024-02-10 11:42:59)
|
11:42:58 infamy0:test # ./case/infix_dhcp/dhcp_basic.py
|
||||||
# Probing dut1 on port d1a for IPv6LL mgmt address ...
|
# Starting (2024-02-10 11:42:59)
|
||||||
# Connecting to mgmt IP fe80::ff:fe00:0%d1a:830 ...
|
# Probing dut1 on port d1a for IPv6LL mgmt address ...
|
||||||
ok 1 - Initialize
|
# Connecting to mgmt IP fe80::ff:fe00:0%d1a:830 ...
|
||||||
> /home/jocke/src/infix/test/case/infix_dhcp/dhcp_basic.py(44)<module>()
|
ok 1 - Initialize
|
||||||
(Pdb)
|
> /home/jocke/src/infix/test/case/infix_dhcp/dhcp_basic.py(44)<module>()
|
||||||
|
(Pdb)
|
||||||
|
```
|
||||||
|
|
||||||
At this point you have full access to the test's state, but it is also
|
At this point you have full access to the test's state, but it is also
|
||||||
an opportunity to inspect the state of the DUTs (e.g. via their
|
an opportunity to inspect the state of the DUTs (e.g. via their
|
||||||
@@ -218,8 +251,9 @@ It is also possible to run a test under Pdb from the get-go, if you
|
|||||||
want to setup breakpoints without modifying the source, or simply step
|
want to setup breakpoints without modifying the source, or simply step
|
||||||
through the code:
|
through the code:
|
||||||
|
|
||||||
11:42:58 infamy0:test # python -m pdb case/infix_dhcp/dhcp_basic.py
|
```
|
||||||
|
11:42:58 infamy0:test # python -m pdb case/infix_dhcp/dhcp_basic.py
|
||||||
|
```
|
||||||
|
|
||||||
### Deterministic Topology Mappings
|
### Deterministic Topology Mappings
|
||||||
|
|
||||||
@@ -230,34 +264,40 @@ between phyical nodes. In such cases, supplying a `PYTHONHASHSEED`
|
|||||||
variable (set to any 32-bit unsigned integer) when launching the test
|
variable (set to any 32-bit unsigned integer) when launching the test
|
||||||
environment will make sure that topology mappings are deterministic:
|
environment will make sure that topology mappings are deterministic:
|
||||||
|
|
||||||
$ make PYTHONHASHSEED=0 test-sh
|
```
|
||||||
|
$ make PYTHONHASHSEED=0 test-sh
|
||||||
|
```
|
||||||
|
|
||||||
If a seed is not supplied, a random value is chosen. This seed is
|
If a seed is not supplied, a random value is chosen. This seed is
|
||||||
logged by the `meta/reproducible.py` test case when running a test
|
logged by the `meta/reproducible.py` test case when running a test
|
||||||
suite:
|
suite:
|
||||||
|
|
||||||
$ make test
|
```
|
||||||
Info: Generating topology
|
$ make test
|
||||||
Info: Generating node YAML
|
Info: Generating topology
|
||||||
Info: Generating executables
|
Info: Generating node YAML
|
||||||
Info: Launching dut1
|
Info: Generating executables
|
||||||
Info: Launching dut2
|
Info: Launching dut1
|
||||||
Info: Launching dut3
|
Info: Launching dut2
|
||||||
Info: Launching dut4
|
Info: Launching dut3
|
||||||
9PM - Simplicity is the ultimate sophistication
|
Info: Launching dut4
|
||||||
|
9PM - Simplicity is the ultimate sophistication
|
||||||
|
|
||||||
Starting test 0002-reproducible.py
|
Starting test 0002-reproducible.py
|
||||||
2024-05-03 10:40:30 # Starting (2024-05-03 10:40:30)
|
2024-05-03 10:40:30 # Starting (2024-05-03 10:40:30)
|
||||||
2024-05-03 10:40:30 # Specify PYTHONHASHSEED=3773822171 to reproduce this test environment
|
2024-05-03 10:40:30 # Specify PYTHONHASHSEED=3773822171 to reproduce this test environment
|
||||||
2024-05-03 10:40:30 ok 1 - $PYTHONHASHSEED is set
|
2024-05-03 10:40:30 ok 1 - $PYTHONHASHSEED is set
|
||||||
2024-05-03 10:40:30 # Exiting (2024-05-03 10:40:30)
|
2024-05-03 10:40:30 # Exiting (2024-05-03 10:40:30)
|
||||||
2024-05-03 10:40:30 1..1
|
2024-05-03 10:40:30 1..1
|
||||||
...
|
...
|
||||||
|
```
|
||||||
|
|
||||||
This is useful because this value can then be used to rerun a test (or
|
This is useful because this value can then be used to rerun a test (or
|
||||||
the whole suite) with identical topology mappings:
|
the whole suite) with identical topology mappings:
|
||||||
|
|
||||||
$ make PYTHONHASHSEED=3773822171 TESTS=case/ietf_system/hostname.py test
|
```
|
||||||
|
$ make PYTHONHASHSEED=3773822171 TESTS=case/ietf_system/hostname.py test
|
||||||
|
```
|
||||||
|
|
||||||
### Deterministic Transport Protocol
|
### Deterministic Transport Protocol
|
||||||
|
|
||||||
@@ -266,13 +306,16 @@ chosen randomly. If you supply a `PYTHONHASHSEED` as described above,
|
|||||||
you get the same protocol used for that hash. But if you want to choose
|
you get the same protocol used for that hash. But if you want to choose
|
||||||
the protocol, add extra arguments to Infamy:
|
the protocol, add extra arguments to Infamy:
|
||||||
|
|
||||||
$ make INFAMY_EXTRA_ARGS="--transport=restconf" TESTS=case/ietf_system/hostname.py test
|
```
|
||||||
|
$ make INFAMY_EXTRA_ARGS="--transport=restconf" TESTS=case/ietf_system/hostname.py test
|
||||||
|
```
|
||||||
|
|
||||||
or, when running interactively:
|
or, when running interactively:
|
||||||
|
|
||||||
$ make test-sh
|
```
|
||||||
09:08:17 infamy0:test # ./9pm/9pm.py -o"--transport=restconf" case/ietf_system/hostname.py
|
$ make test-sh
|
||||||
|
09:08:17 infamy0:test # ./9pm/9pm.py -o"--transport=restconf" case/ietf_system/hostname.py
|
||||||
|
```
|
||||||
|
|
||||||
### Test specification
|
### Test specification
|
||||||
|
|
||||||
@@ -287,13 +330,13 @@ for example:
|
|||||||
```python
|
```python
|
||||||
test.step("Set IPv4 address on the interface dut:cross")
|
test.step("Set IPv4 address on the interface dut:cross")
|
||||||
test.step("Verify the IP address is set on dut:cross")
|
test.step("Verify the IP address is set on dut:cross")
|
||||||
|
|
||||||
```
|
```
|
||||||
where dut, cross and the IPv4 address could be found inside the
|
|
||||||
|
where *dut*, *cross* and the IPv4 address could be found inside the
|
||||||
logical topology for the test.
|
logical topology for the test.
|
||||||
|
|
||||||
Each test case must begin with the test name followed by a empty line and
|
Each test case must begin with the test name followed by a empty line
|
||||||
the description of the test. For example:
|
and the description of the test. For example:
|
||||||
|
|
||||||
```
|
```
|
||||||
"""
|
"""
|
||||||
@@ -305,7 +348,10 @@ Verify that it it possible to change hostname
|
|||||||
|
|
||||||
The test specifaction can be genererated with:
|
The test specifaction can be genererated with:
|
||||||
|
|
||||||
$ make test-spec
|
```
|
||||||
|
$ make test-spec
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
### Test Development
|
### Test Development
|
||||||
|
|
||||||
@@ -320,9 +366,9 @@ services, such as LLDP and mDNS.
|
|||||||
While test grouping is flexible, each test should be placed in a
|
While test grouping is flexible, each test should be placed in a
|
||||||
logically relevant category.
|
logically relevant category.
|
||||||
|
|
||||||
When creating a new test group, add it to `infix/test/case/all.yaml`,
|
When creating a new test group, add it to `infix/test/case/all.yaml`, to
|
||||||
to enable it to run as a
|
enable it to run as a [subset of the test
|
||||||
[subset of the test suite](#running-subsets-of-tests):
|
suite](#running-subsets-of-tests):
|
||||||
|
|
||||||
```
|
```
|
||||||
- name: infix-services
|
- name: infix-services
|
||||||
@@ -348,8 +394,9 @@ include::lldp_enable_disable/Readme.adoc[]
|
|||||||
|
|
||||||
Each test case should have its own directory under,
|
Each test case should have its own directory under,
|
||||||
`infix/test/case/infix_services`, containing:
|
`infix/test/case/infix_services`, containing:
|
||||||
- `test.py` - the test script
|
|
||||||
- `topology.dot` - the logical topology definition.
|
- `test.py` - the test script
|
||||||
|
- `topology.dot` - the logical topology definition.
|
||||||
|
|
||||||
When the [test specification](#test-specification) is generated,
|
When the [test specification](#test-specification) is generated,
|
||||||
`topology.svg` and `Readme.adoc` should also be created.
|
`topology.svg` and `Readme.adoc` should also be created.
|
||||||
|
|||||||
+15
-10
@@ -9,33 +9,38 @@ These images also work with the Graphical Network Simulator ([GNS3][]),
|
|||||||
which is a very user-friendly tool for playing around with simple to
|
which is a very user-friendly tool for playing around with simple to
|
||||||
complex network setups, verifying interoperability between vendors, etc.
|
complex network setups, verifying interoperability between vendors, etc.
|
||||||
|
|
||||||
|
|
||||||
QEMU
|
QEMU
|
||||||
----
|
----
|
||||||
|
|
||||||
> **Note:** installation for Debian/Ubuntu based systems: <kbd>sudo apt
|
> [!TIP]
|
||||||
> install virt-manager</kbd> -- dependencies ensure the relevant Qemu
|
> Installation for Debian/Ubuntu based systems can be done by "simply":
|
||||||
> packages are pulled in as well. Installing [virt-manager][virt] helps
|
> <kbd>sudo apt install virt-manager</kbd> -- dependencies ensure the
|
||||||
> set up Qemu networking on your system.
|
> relevant Qemu packages are pulled in as well. This trick, installing
|
||||||
|
> [virt-manager][virt], helps set up Qemu networking on your system.
|
||||||
|
|
||||||
A virtualized Infix x86_64 instance can easily be launched from a Linux
|
A virtualized Infix x86_64 instance can easily be launched from a Linux
|
||||||
system, with [Qemu][] installed, by issuing:
|
system, with [Qemu][] installed, by issuing:
|
||||||
|
|
||||||
./qemu.sh
|
```
|
||||||
|
$ ./qemu.sh
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
from an unpacked [release tarball][rels]. From a built source tree of
|
from an unpacked [release tarball][rels]. From a built source tree of
|
||||||
Infix the same functionality is bundled as:
|
Infix the same functionality is bundled as:
|
||||||
|
|
||||||
make run
|
```
|
||||||
|
$ make run
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
To change settings, e.g. networking, <kbd>make run-menuconfig</kbd>, or
|
To change settings, e.g. networking, <kbd>make run-menuconfig</kbd>, or
|
||||||
from a pre-built Infix release tarball, using <kbd>./qemu.sh -c</kbd>
|
from a pre-built Infix release tarball, using <kbd>./qemu.sh -c</kbd>
|
||||||
|
|
||||||
The Infix test suite is built around Qemu and [Qeneth][qeth], see:
|
The Infix test suite is built around Qemu and [Qeneth][qeth], see:
|
||||||
|
|
||||||
* [Regression Testing with Infamy](testing.md)
|
* [Regression Testing with Infamy](testing.md)
|
||||||
* [Infamy Docker Image](https://github.com/kernelkit/infix/blob/main/test/docker/README.md)
|
* [Infamy Docker Image](https://github.com/kernelkit/infix/blob/main/test/docker/README.md)
|
||||||
|
|
||||||
|
|
||||||
GNS3
|
GNS3
|
||||||
----
|
----
|
||||||
|
|||||||
Reference in New Issue
Block a user