From 629f9b3055137ffb605cfe07884bf805bc030e11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Sch=C3=A4fer?= Date: Wed, 4 Feb 2026 15:27:36 +0100 Subject: [PATCH 1/3] Update documentation Fix language mistakes and wording --- README.md | 257 ++++++++++++++++++++++++++---------------------------- 1 file changed, 125 insertions(+), 132 deletions(-) diff --git a/README.md b/README.md index d951e7b..27e63ba 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Flake Pilot -## Semi Transparent Container/VM instances +## Semi-transparent Container/VM instances 1. [Introduction](#introduction) 1. [Use Cases](#usecases) @@ -14,61 +14,61 @@ ## Introduction -flake-pilot is a software to register, provision and launch applications -that are actually provided inside of a runtime environment like an -OCI container or a FireCracker VM. There are two main components: +Flake Pilot is software to register, provision, and launch applications +that are actually provided inside a runtime environment like an +OCI container or a Firecracker VM. There are two main components: 1. The launchers The launcher binary. Each application that was registered as a - flake is redirected to a launcher binary. As of today - support for the ```podman``` and ```firecracker``` engines are - implemented leading to the respective ```podman-pilot``` and + flake is redirected to a launcher binary. As of today, + support for the ```podman``` and ```firecracker``` engines is + implemented, leading to the respective ```podman-pilot``` and ```firecracker-pilot``` launcher binaries. 2. The flake registration tool ```flake-ctl``` is the management utility to list, register, - remove, and-more... flake applications on your host. + remove, and more... flake applications on your host. -The main idea for flake-pilot was not only to launch isolated apps like -native binaries but also allow to run a provision step prior calling -the application. This concept then allows to run semi transparent +The main idea for Flake Pilot was not only to launch isolated apps like +native binaries but also to allow running a provisioning step prior to calling +the application. This concept then allows running semi-transparent container/VM instances which can take information from other places -prior its execution. The following diagram visualizes this concept: +prior to their execution. The following diagram visualizes this concept: ![](images/transparency.png) -As a result we see some interesting use cases described in the following +As a result, we see some interesting use cases described in the following section. ### Use Cases -* delta containers used together with a base container such that - only small delta containers gets pulled to the registry used with +* Delta containers used together with a base container such that + only small delta containers are pulled to the registry, used with a base that exists only once. -* include arbitrary data without harming the host integrity e.g custom +* Include arbitrary data without harming host integrity, e.g., custom binaries, proprietary software not following package guidelines and - standards, e.g automotive industry processes which we will not be - able to change in this live ;) + standards (e.g., automotive industry processes which we will not be + able to change in this life). -* layering of several containers, e.g deltas on top of a base. Building - up a solution stack e.g base + python + python-app. +* Layering of several containers, e.g., deltas on top of a base. Building + a solution stack, e.g., base + python + python-app. -* provisioning app dependencies from the host instead of providing them - in the container, e.g a delta container providing the app using a base - container but take the certificates or other sensitive information - from the host; three way dependency model. +* Provisioning app dependencies from the host instead of providing them + in the container, e.g., a delta container providing the app using a base + container but taking the certificates or other sensitive information + from the host; a three-way dependency model. -* isolating applications that require different library versions - than the host provides, e.g old legacy applications. +* Isolating applications that require different library versions + than those the host provides, e.g., old legacy applications. -* running AI workloads in isolated environments +* Running AI workloads in isolated environments. -Actually some of the above use cases are immaterial if a proper packaging, -release and maintenance of the application is possible. However, I have -learned the world is not an ideal place and there might be a spot for +Actually, some of the above use cases are immaterial if proper packaging, +release, and maintenance of the application are possible. However, I have +learned the world is not an ideal place, and there might be a spot for this project to be useful, supporting users with "special" needs and adding an adaptive feature to the OS. @@ -78,7 +78,7 @@ for further details ## Installation -flake-pilot components are written in rust and are vailable as packages +Flake Pilot components are written in Rust and are available as packages for SUSE as follows: ```bash @@ -94,7 +94,7 @@ make build && make install ## Quick Start OCI containers -As a start let's register an application named ```aws``` which is +To start, let's register an application named ```aws``` which is connected to the ```aws-cli``` container provided by Amazon on ```docker.io/amazon```. @@ -110,23 +110,23 @@ connected to the ```aws-cli``` container provided by Amazon on flake-ctl podman register --container amazon/aws-cli --app /usr/bin/aws --target / ``` - This creates ```/usr/bin/aws``` on your host which actually + This creates ```/usr/bin/aws``` on your host, which actually launches the ```amazon/aws-cli``` container. The default entry point of the container was configured by Amazon to launch their - cloud API application. Thus the target program to call inside - of the container doesn't need to be explicitly configured in - the registration and is therefore just set to ```/``` + cloud API application. Thus, the target program to call inside + the container doesn't need to be explicitly configured in + the registration and is therefore just set to ```/```. 3. Launch the application - To run ```aws``` just call for example: + To run ```aws```, just call, for example: ```bash aws ec2 help ``` Let's register an editor application next. The following example uses -the ```joe``` editor flake which was produced as a delta container +the ```joe``` editor flake, which was produced as a delta container against the ```basesystem``` container. 1. Register the ```joe``` application @@ -141,33 +141,33 @@ against the ```basesystem``` container. 2. Launch the application - To run the ```joe``` editor just call: + To run the ```joe``` editor, just call: ```bash joe ``` This example also shows that it's not required to explicitly pull the -required containers. At launch time missing containers will be pulled +required containers. At launch time, missing containers will be pulled automatically. ## Quick Start FireCracker VMs Using containers to isolate applications from the host system is a common -approach. The limitation comes on the level of the kernel. Each container -shares the kernel with the host and if applications requires to run +approach. The limitation is at the kernel level. Each container +shares the kernel with the host, and if an application requires to run privileged, requires direct access to device nodes or kernel interfaces -like the device mapper, a deeper level of isolation might be needed. -At this point full virtual system instances running its own kernel, optional -initrd and processes inside provides a solution. The price to pay is on -the performance side but projects like KVM and FireCracker offers a nice -concept to run virtual machines accelerated through KVM as competitive -alternative to containers. Thus flake-pilot also implements support for the -firecracker engine. +like the device mapper, a deeper level of isolation may be needed. +At this point, full virtual system instances running their own kernel, optional +initrd, and processes inside provide a solution. The trade-off is performance, +but projects like KVM and Firecracker offer a nice +concept to run virtual machines accelerated through KVM as a competitive +alternative to containers. Thus, Flake Pilot also implements support for the +Firecracker engine. -Start an application as virtual machine (VM) instance as follows: +Start an application as a virtual machine (VM) instance as follows: -1. Pull a firecracker compatible VM +1. Pull a Firecracker-compatible VM ```bash flake-ctl firecracker pull --name leap \ @@ -181,29 +181,29 @@ Start an application as virtual machine (VM) instance as follows: --app /usr/bin/mybash --target /bin/bash --overlay-size 20GiB ``` - This registers an app named ```mybash``` to the system. Once called a - firecracker VM based on the pulled ```leap``` image is started and - the ```/bin/bash``` program is called inside of the VM instance. - In addition some write space of 20GB is added to the instance + This registers an app named ```mybash``` to the system. Once called, a + Firecracker VM based on the pulled ```leap``` image is started, and + the ```/bin/bash``` program is called inside the VM instance. + In addition, some write space of 20GB is added to the instance. 3. Launch the application - To run ```mybash``` just call for example: + To run ```mybash```, just call, for example: ```bash mybash ``` - Drops you into a bash shell inside of the VM + This drops you into a bash shell inside the VM. - **_NOTE:_** The data transfer from the virtual machine to the host + **_NOTE:_** Data transfer from the virtual machine to the host is done through the serial console. As the process of calling the - application includes the boot of the virtual machine, it might happen - that kernel messages are intermixed with the output of the application. + application includes the boot of the virtual machine, kernel messages + may be intermixed with the output of the application. Our default setting prevents kernel messages from being printed to - the console as much as possible but there are message that can hardly - be prevented or requires a customized kernel build to be suppressed. - If this is unwanted use the + the console as much as possible, but there are messages that can hardly + be prevented or require a customized kernel build to be suppressed. + If this is unwanted, use the ```bash --force-vsock @@ -211,21 +211,20 @@ Start an application as virtual machine (VM) instance as follows: option when registering the application. - There are still limitations such as that there is also - no differentiation between **stdout** and **stderr** anymore - and the exit code of the VM call is not matching the exit - code of the application call. + There are still limitations, such as no differentiation between **stdout** + and **stderr** anymore, and the exit code of the VM call does not match + the exit code of the application call. -### Use FireCracker VM image from components +### Use Firecracker VM image from components -In the quickstart for FireCracker a special image type called ```kis-image``` -was used. This image type is specific to the KIWI appliance builder and -it provides the required components to boot up a FireCracker VM in one -archive. However, it's also possible to pull a FireCracker VM image from +In the quickstart for Firecracker, a special image type called ```kis-image``` +was used. This image type is specific to the KIWI appliance builder, and +it provides the required components to boot up a Firecracker VM in one +archive. However, it's also possible to pull a Firecracker VM image from its single components. Mandatory components are the kernel image and the -rootfs image, whereas the initrd is optional. The FireCracker project -itself provides its images in single components and you can use them +rootfs image, whereas the initrd is optional. The Firecracker project +itself provides its images in single components, and you can use them as follows: 1. Pull a firecracker compatible VM @@ -253,18 +252,17 @@ as follows: ### Networking -As of today firecracker supports networking only through TUN/TAP devices. -As a consequence it is a user responsibility to setup the routing on the +As of today, Firecracker supports networking only through TUN/TAP devices. +As a consequence, it is the user's responsibility to set up the routing on the host from the TUN/TAP device to the outside world. There are many possible -solutions available and the following describes a simple static IP and NAT -based setup. +solutions available, and the following describes a simple static IP and NAT-based setup. The proposed example works within the following requirements: -* initrd_path must be set in the flake configuration -* The used initrd has to provide support for systemd-(networkd, resolved) - and must have been created by dracut such that the passed - boot_args in the flake setup will become effective +* `initrd_path` must be set in the flake configuration. +* The used initrd has to provide support for `systemd-(networkd, resolved)` + and must have been created by `dracut` such that the passed + `boot_args` in the flake setup will become effective. 1. Enable IP forwarding @@ -272,27 +270,27 @@ The proposed example works within the following requirements: sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward" ``` -2. Setup NAT on the outgoing interface +2. Set up NAT on the outgoing interface - Network Address Translation(NAT) is an easy way to route traffic + Network Address Translation (NAT) is an easy way to route traffic to the outside world even when it originates from another network. - All traffic looks like as if it would come from the outgoing + All traffic appears as if it would come from the outgoing interface. - **_NOTE:_** Please check what tooling is managing the firewall on + **_NOTE:_** Please check which tool is managing the firewall on your host and refer to its documentation on how to set up the - nat/postrouting rules. The information below assumes there is no - other firewall software active on your host and only serves the - purpose of an example setup ! + NAT/postrouting rules. The information below assumes there is no + other firewall software active on your host and serves only as + an example setup! - In this example we assume ```eth0``` to be the outgoing interface: + In this example, we assume ```eth0``` to be the outgoing interface: ```bash sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE sudo iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT ``` -3. Setup network configuration in the flake setup +3. Set up network configuration in the flake setup The flake configuration for the registered ```mybash``` app from above can be found at: @@ -302,7 +300,7 @@ The proposed example works within the following requirements: ``` The default network setup is based on DHCP because this is - the only generic setting that flake-ctl offers at the moment. + the only generic setting that `flake-ctl` offers at the moment. The setup offered for networking provides the setting ```ip=dhcp```. Change this setting to the following: @@ -316,43 +314,43 @@ The proposed example works within the following requirements: - nameserver=8.8.8.8 ``` - In this example the DHCP based setup changes to a static - IP: 172.16.0.2 using 172.16.0.1 as its gateway and Google + In this example, the DHCP-based setup changes to a static + IP: 172.16.0.2 using 172.16.0.1 as its gateway, and Google to perform name resolution. Please note: The name of the network interface in the guest is always ```eth0```. For - further information about network setup options refer - to ```man dracut.cmdline``` and lookup the section - about ```ip=``` + further information about network setup options, refer + to ```man dracut.cmdline``` and look up the section + about ```ip=```. -4. Create a tap device matching the app registration. In the above example - the app ```/usr/bin/mybash``` was registered. The firecracker pilot - configures the VM instance to pass trafic on the tap device name +4. Create a TAP device matching the app registration. In the above example, + the app ```/usr/bin/mybash``` was registered. The Firecracker pilot + configures the VM instance to pass traffic on the TAP device named ```tap-mybash```. If the application is called with an identifier like - ```mybash @id```, the tap device name ```tap-mybash@id``` is used. + ```mybash @id```, the TAP device name ```tap-mybash@id``` is used. ```bash sudo ip tuntap add tap-mybash mode tap ``` - **_NOTE:_** If the tap device does not exist, firecracker-pilot will - create it for you. However, this might be too late in case of e.g a - DHCP setup which requires the routing of the tap device to be present - before the actual network setup inside of the guest takes place. - If firecracker-pilot creates the tap device it will also be + **_NOTE:_** If the TAP device does not exist, `firecracker-pilot` will + create it for you. However, this may be too late in the case of, for example, a + DHCP setup which requires the routing of the TAP device to be present + before the actual network setup inside the guest takes place. + If `firecracker-pilot` creates the TAP device, it will also be removed if the instance shuts down. -5. Connect the tap device to the outgoing interface +5. Connect the TAP device to the outgoing interface - Select a subnet range for the tap and bring it up + Select a subnet range for the TAP and bring it up. - **_NOTE:_** The settings here must match with the flake configuration ! + **_NOTE:_** The settings here must match the flake configuration! ```bash ip addr add 172.16.0.1/24 dev tap-mybash ip link set tap-mybash up ``` - Forward tap to the outgoing interface + Forward TAP to the outgoing interface ```bash sudo iptables -A FORWARD -i tap-mybash -o eth0 -j ACCEPT @@ -367,22 +365,21 @@ The proposed example works within the following requirements: $ ping www.google.de ``` - **_NOTE:_** The tap device cannot be shared across multiple instances. - Each instance needs its own tap device. Thus the steps 3,4 and 5 needs + **_NOTE:_** The TAP device cannot be shared across multiple instances. + Each instance needs its own TAP device. Thus, steps 3, 4, and 5 need to be repeated for each instance. ## Application Setup -After the registration of an application they can be listed via +After an application is registered, it can be listed via: ```bash flake-ctl list ``` Each application provides a configuration below ```/usr/share/flakes/```. -The term ```flake``` is a short name that we came up with to provide -a generic name for an application running inside of an isolated environment. -For our above registered ```aws``` flake the config file structure +The term ```flake``` is a short name for an application running inside an isolated environment. +For our above registered ```aws``` flake, the config file structure looks like the following: ``` @@ -398,32 +395,28 @@ https://github.com/OSInside/flake-pilot/tree/main/doc ## How To Build Your Own App Images -Building images as container- or VM images can be done in different ways. -One option is to use the **Open Build Service** which is able to build -software packages and images and therefore allows to maintain the +Building images as container or VM images can be done in different ways. +One option is to use the **Open Build Service**, which is able to build +software packages and images and therefore allows maintaining the complete application stack. -For demo purposes and to showcase the mentioned [Use Cases](#usecases) -some example images were created and could be considered as a simple +For demonstration purposes and to showcase the mentioned [Use Cases](#usecases), +some example images were created and could be considered a simple ```flake store```. Please find them here: * https://build.opensuse.org/project/show/home:marcus.schaefer:delta_containers Feel free to browse through the project and have some fun testing. There -is a short description for each application how to use them. +is a short description for each application on how to use them. -**_NOTE:_** All images are build using the -[KIWI](https://github.com/OSInside/kiwi) appliance builder which is -supported by the Open Build Service backend and allows to build all the +**_NOTE:_** All images are built using the +[KIWI](https://github.com/OSInside/kiwi) appliance builder, which is +supported by the Open Build Service backend and allows building all the images in a maintainable way. KIWI uses an image description format to describe the image in a declarative way. Reading the above -examples should give you an idea how things fits together. In case -of questions regarding KIWI and the image builds please don't hesitate -to get in contact with us. +examples should give you an idea of how things fit together. If you have any questions +regarding KIWI and the image builds, please contact us. -Flake pilot is a project in its early stages and the result of -a fun conversation over beer on a conference. Feedback +Flake Pilot is a project in its early stages. Feedback is very much welcome. -Remember to have fun :) - From 207089be53d2c60cbbe5ed34600b002156f0f9eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Sch=C3=A4fer?= Date: Wed, 4 Feb 2026 15:41:41 +0100 Subject: [PATCH 2/3] Clippy fixes --- flake-ctl/src/firecracker.rs | 16 ++++++++-------- flake-ctl/src/podman.rs | 22 +++++++++++----------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/flake-ctl/src/firecracker.rs b/flake-ctl/src/firecracker.rs index 46d23bc..7894c22 100644 --- a/flake-ctl/src/firecracker.rs +++ b/flake-ctl/src/firecracker.rs @@ -489,14 +489,14 @@ pub fn purge_vm(vm: &str) { "{}/{}.yaml", get_flakes_dir(false), app_name ); match app_config::AppConfig::init_from_file(Path::new(&config_file)) { - Ok(mut app_conf) => { - if app_conf.vm.is_some() && - vm == app_conf.vm.as_mut().unwrap().name - { - app::remove( - &app_conf.vm.as_mut().unwrap().host_app_path, - defaults::FIRECRACKER_PILOT, false, false, false - ); + Ok(app_conf) => { + if let Some(ref vm_conf) = app_conf.vm { + if vm == vm_conf.name { + app::remove( + &vm_conf.host_app_path, + defaults::FIRECRACKER_PILOT, false, false, false + ); + } } }, Err(error) => { diff --git a/flake-ctl/src/podman.rs b/flake-ctl/src/podman.rs index aec1d51..dee000e 100644 --- a/flake-ctl/src/podman.rs +++ b/flake-ctl/src/podman.rs @@ -205,17 +205,17 @@ pub fn purge_container(container: &str, usermode: bool) { "{}/{}.yaml", get_flakes_dir(usermode), app_name ); match app_config::AppConfig::init_from_file(Path::new(&config_file)) { - Ok(mut app_conf) => { - if app_conf.container.is_some() && - container == app_conf.container.as_mut().unwrap().name - { - app::remove( - &app_conf.container.as_mut().unwrap().host_app_path, - defaults::PODMAN_PILOT, - usermode, - false, - false - ); + Ok(app_conf) => { + if let Some(ref container_conf) = app_conf.container { + if container == container_conf.name { + app::remove( + &container_conf.host_app_path, + defaults::PODMAN_PILOT, + usermode, + false, + false + ); + } } }, Err(error) => { From 214ada8f37a0bdded8f5f4fc107a09f3917a2c9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Sch=C3=A4fer?= Date: Wed, 4 Feb 2026 15:48:48 +0100 Subject: [PATCH 3/3] Add ai sandbox example workflow --- README.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/README.md b/README.md index 27e63ba..71240cc 100644 --- a/README.md +++ b/README.md @@ -151,6 +151,43 @@ This example also shows that it's not required to explicitly pull the required containers. At launch time, missing containers will be pulled automatically. +Let's register an AI application next. The following example uses +a gemini-cli container which was produced as a standalone container +via the KIWI appliance builder and hosted on AWS ECR Public. + +1. Create an AI space in your home directory + + ```bash + mkdir -p ~/ai + ``` + +2. Register the ```ok-google``` application + + ```bash + flake-ctl podman --user register \ + --app /home/$USER/ok-google \ + --target /usr/local/bin/gemini \ + --container public.ecr.aws/b9k1j9y6/ai/gemini:latest \ + --resume \ + --opt "\--net host" \ + --opt "\--interactive" \ + --opt "\--workdir /root/ai" \ + --opt "\--volume %HOME/ai:/root/ai" \ + --opt "\-e GEMINI_API_KEY=YOUR_KEY_HERE" + ``` + +3. Launch the application + + To run ```ok-google```, just call, for example: + + ```bash + ok-google "What is the capital of Germany?" + ``` + + This starts the gemini-cli application inside the container, + passing the question to it. The application uses the mounted + volume to store its data persistently in your home directory. + ## Quick Start FireCracker VMs Using containers to isolate applications from the host system is a common