diff --git a/.github/workflows/iso-build.yaml b/.github/workflows/iso-build.yaml index 7ee7c4da4f..44d08efdf7 100644 --- a/.github/workflows/iso-build.yaml +++ b/.github/workflows/iso-build.yaml @@ -1,39 +1,39 @@ -# This workflow will build an Arch Linux ISO file with the commit on it +# # This workflow will build an Arch Linux ISO file with the commit on it -name: Build Arch ISO with ArchInstall Commit +# name: Build Arch ISO with ArchInstall Commit -on: - push: - branches: - - master - - main # In case we adopt this convention in the future - pull_request: - paths-ignore: - - 'docs/**' - - '**.editorconfig' - - '**.gitignore' - - '**.md' - - 'LICENSE' - - 'PKGBUILD' - release: - types: - - created +# on: +# push: +# branches: +# - master +# - main # In case we adopt this convention in the future +# pull_request: +# paths-ignore: +# - 'docs/**' +# - '**.editorconfig' +# - '**.gitignore' +# - '**.md' +# - 'LICENSE' +# - 'PKGBUILD' +# release: +# types: +# - created -jobs: - build: - runs-on: ubuntu-latest - container: - image: archlinux/archlinux:latest - options: --privileged - steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 - - run: pwd - - run: find . - - run: cat /etc/os-release - - run: pacman-key --init - - run: pacman --noconfirm -Sy archlinux-keyring - - run: ./build_iso.sh - - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6 - with: - name: Arch Live ISO - path: /tmp/archlive/out/*.iso +# jobs: +# build: +# runs-on: ubuntu-latest +# container: +# image: archlinux/archlinux:latest +# options: --privileged +# steps: +# - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 +# - run: pwd +# - run: find . +# - run: cat /etc/os-release +# - run: pacman-key --init +# - run: pacman --noconfirm -Sy archlinux-keyring +# - run: ./build_iso.sh +# - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6 +# with: +# name: Arch Live ISO +# path: /tmp/archlive/out/*.iso diff --git a/README.md b/README.md index 287f215a1b..48e959e72b 100644 --- a/README.md +++ b/README.md @@ -1,252 +1 @@ - -drawing - - -# Arch Installer -[![Lint Python and Find Syntax Errors](https://github.com/archlinux/archinstall/actions/workflows/flake8.yaml/badge.svg)](https://github.com/archlinux/archinstall/actions/workflows/flake8.yaml) - -Just another guided/automated [Arch Linux](https://wiki.archlinux.org/index.php/Arch_Linux) installer with a twist. -The installer also doubles as a python library to install Arch Linux and manage services, packages, and other things inside the installed system *(Usually from a live medium or from an existing installation)*. - -* archinstall [discord](https://discord.gg/aDeMffrxNg) server -* archinstall [#archinstall:matrix.org](https://matrix.to/#/#archinstall:matrix.org) Matrix channel -* archinstall [#archinstall@irc.libera.chat:6697](https://web.libera.chat/?channel=#archinstall) -* archinstall [documentation](https://archinstall.archlinux.page/) - -# Installation & Usage -> [!TIP] -> In the ISO you are root by default. Use sudo if running from an existing system. - -```shell - # pacman-key --init - # pacman -Sy archinstall - # archinstall -``` - -Alternative ways to install are `git clone` the repository (and is better since you get the latest code regardless of [build date](https://archlinux.org/packages/?sort=&q=archinstall)) or `pip install --upgrade archinstall`. - -## Running the [guided](https://github.com/archlinux/archinstall/blob/master/archinstall/scripts/guided.py) installer - -Assuming you are on an Arch Linux live-ISO or installed via `pip`: -```shell -archinstall -``` - -## Running the [guided](https://github.com/archlinux/archinstall/blob/master/archinstall/scripts/guided.py) installer using `git` - -```shell - # git clone https://github.com/archlinux/archinstall - # cd archinstall - # python -m archinstall $@ -``` - -#### Advanced -Some additional options that most users do not need are hidden behind the `--advanced` flag and all options/args can be consulted through `-h` or `--help`. - -## Running from a declarative configuration file or URL - -`archinstall` can be run with a JSON configuration file. There are 2 different configuration files to consider, -the `user_configuration.json` contains all general installation configuration, whereas the `user_credentials.json` -contains the sensitive user configuration such as user password, root password, and encryption password. - -An example of the user configuration file can be found here -[configuration file](https://github.com/archlinux/archinstall/blob/master/examples/config-sample.json) -and an example of the credentials configuration here -[credentials file](https://github.com/archlinux/archinstall/blob/master/examples/creds-sample.json). - -**HINT:** The configuration files can be auto-generated by starting `archinstall`, configuring all desired menu -points and then going to `Save configuration`. - -To load the configuration file into `archinstall` run the following command -```shell -archinstall --config --creds -``` - -### Credentials configuration file encryption -By default, all user account credentials are hashed with `yescrypt` and only the hash is stored in the saved `user_credentials.json` file. -This is not possible for disk encryption password which needs to be stored in plaintext to be able to apply it. - -However, when selecting to save configuration files, `archinstall` will prompt for the option to encrypt the `user_credentials.json` file content. -A prompt will require to enter a encryption password to encrypt the file. When providing an encrypted `user_configuration.json` as a argument with `--creds ` -there are multiple ways to provide the decryption key: -* Provide the decryption key via the command line argument `--creds-decryption-key ` -* Store the encryption key in the environment variable `ARCHINSTALL_CREDS_DECRYPTION_KEY` which will be read automatically -* If none of the above is provided a prompt will be shown to enter the decryption key manually - - -# Help or Issues - -If you come across any issues, kindly submit your issue here on GitHub or post your query in the -[discord](https://discord.gg/aDeMffrxNg) help channel. - -When submitting an issue, please: -* Provide the stacktrace of the output if applicable -* Attach the `/var/log/archinstall/install.log` to the issue ticket. This helps us help you! - * To extract the log from the ISO image, one way is to use
- ```shell - curl -F'file=@/var/log/archinstall/install.log' https://0x0.st - ``` - - -# Available Languages - -Archinstall is available in different languages which have been contributed and are maintained by the community. -The language can be switched inside the installer (first menu entry). Bear in mind that not all languages provide -full translations as we rely on contributors to do the translations. Each language has an indicator that shows -how much has been translated. - -Any contributions to the translations are more than welcome, -to get started please follow [the guide](https://github.com/archlinux/archinstall/blob/master/archinstall/locales/README.md) - -## Fonts -The ISO does not ship with all fonts needed for different languages. -Fonts that use a different character set than Latin will not be displayed correctly. If those languages -want to be selected then a proper font has to be set manually in the console. - -All available console fonts can be found in `/usr/share/kbd/consolefonts` and set with `setfont LatGrkCyr-8x16`. - - -# Scripting your own installation - -## Scripting interactive installation - -For an example of a fully scripted, interactive installation please refer to the example -[interactive_installation.py](https://github.com/archlinux/archinstall/blob/master/archinstall/scripts/guided.py) - - -> **To create your own ISO with this script in it:** Follow [ArchISO](https://wiki.archlinux.org/index.php/archiso)'s guide on creating your own ISO. - -## Script non-interactive automated installation - -For an example of a fully scripted, automated installation please refer to the example -[full_automated_installation.py](https://github.com/archlinux/archinstall/blob/master/examples/full_automated_installation.py) - -# Profiles - -`archinstall` comes with a set of pre-configured profiles available for selection during the installation process. - -- [Desktop](https://github.com/archlinux/archinstall/tree/master/archinstall/default_profiles/desktops) -- [Server](https://github.com/archlinux/archinstall/tree/master/archinstall/default_profiles/servers) - -The profiles' definitions and the packages they will install can be directly viewed in the menu, or -[default profiles](https://github.com/archlinux/archinstall/tree/master/archinstall/default_profiles) - - -# Testing - -## Using a Live ISO Image - -If you want to test a commit, branch, or bleeding edge release from the repository using the standard Arch Linux Live ISO image, -replace the archinstall version with a newer one and execute the subsequent steps defined below. - -*Note: When booting from a live USB, the space on the ramdisk is limited and may not be sufficient to allow -running a re-installation or upgrade of the installer. In case one runs into this issue, any of the following can be used -- Resize the root partition https://wiki.archlinux.org/title/Archiso#Adjusting_the_size_of_the_root_file_system -- The boot parameter `copytoram=y` (https://gitlab.archlinux.org/archlinux/mkinitcpio/mkinitcpio-archiso/-/blob/master/docs/README.bootparams#L26) -can be specified which will copy the root filesystem to tmpfs.* - -1. You need a working network connection -2. Install the build requirements with `pacman -Sy; pacman -S git python-pip gcc pkgconf` - *(note that this may or may not work depending on your RAM and current state of the squashfs maximum filesystem free space)* -3. Uninstall the previous version of archinstall with `pip uninstall --break-system-packages archinstall` -4. Now clone the latest repository with `git clone https://github.com/archlinux/archinstall` -5. Enter the repository with `cd archinstall` - *At this stage, you can choose to check out a feature branch for instance with `git checkout v2.3.1-rc1`* -6. To run the source code, there are 2 different options: - - Run a specific branch version from source directly using `python -m archinstall`, in most cases this will work just fine, the - rare case it will not work is if the source has introduced any new dependencies that are not installed yet - - Installing the branch version with `pip install --break-system-packages .` and `archinstall` - -## Without a Live ISO Image - -To test this without a live ISO, the simplest approach is to use a local image and create a loop device.
-This can be done by installing `pacman -S arch-install-scripts util-linux` locally and doing the following: - - # truncate -s 20G testimage.img - # losetup --partscan --show ./testimage.img - # pip install --upgrade archinstall - # python -m archinstall --script guided - # qemu-system-x86_64 -enable-kvm -machine q35,accel=kvm -device intel-iommu -cpu host -m 4096 -boot order=d -drive file=./testimage.img,format=raw -drive if=pflash,format=raw,readonly,file=/usr/share/ovmf/x64/OVMF.4m.fd -drive if=pflash,format=raw,readonly,file=/usr/share/ovmf/x64/OVMF.4m.fd - -This will create a *20 GB* `testimage.img` and create a loop device which we can use to format and install to.
-`archinstall` is installed and executed in [guided mode](#docs-todo). Once the installation is complete, ~~you can use qemu/kvm to boot the test media.~~
-*(You'd actually need to do some EFI magic in order to point the EFI vars to the partition 0 in the test medium, so this won't work entirely out of the box, but that gives you a general idea of what we're going for here)* - -There's also a [Building and Testing](https://github.com/archlinux/archinstall/wiki/Building-and-Testing) guide.
-It will go through everything from packaging, building and running *(with qemu)* the installer against a dev branch. - -## Boot an Arch ISO image in a VM - -You may want to boot an ISO image in a VM to test `archinstall` in there. - -* Download the latest [Arch ISO](https://archlinux.org/download/) -* Use the the below command to boot the ISO in a VM - -``` -qemu-system-x86_64 -enable-kvm \ --machine q35,accel=kvm -device intel-iommu \ --cpu host -m 4096 -boot order=d \ --drive if=pflash,format=raw,readonly,file=/usr/share/ovmf/x64/OVMF.4m.fd \ --drive if=pflash,format=raw,readonly,file=/usr/share/ovmf/x64/OVMF.4m.fd \ --drive file=./archlinux-2025.12.01-x86_64.iso,format=raw -``` - -HINT: For espeakup support -``` -qemu-system-x86_64 -enable-kvm \ --machine q35,accel=kvm -device intel-iommu \ --cpu host -m 4096 -boot order=d \ --drive if=pflash,format=raw,readonly,file=/usr/share/ovmf/x64/OVMF.4m.fd \ --drive if=pflash,format=raw,readonly,file=/usr/share/ovmf/x64/OVMF.4m.fd \ --drive file=./archlinux-2025.12.01-x86_64.iso,format=raw \ --device intel-hda -device hda-duplex,audiodev=snd0 \ --audiodev pa,id=snd0,server=/run/user/1000/pulse/native -``` - - -# FAQ - -## Keyring out-of-date -For a description of the problem see https://archinstall.archlinux.page/help/known_issues.html#keyring-is-out-of-date-2213 and discussion in issue https://github.com/archlinux/archinstall/issues/2213. - -For a quick fix the below command will install the latest keyrings - -```pacman -Sy archlinux-keyring``` - -## How to dual boot with Windows - -To install Arch Linux alongside an existing Windows installation using `archinstall`, follow these steps: - -1. Ensure some unallocated space is available for the Linux installation after the Windows installation. -2. Boot into the ISO and run `archinstall`. -3. Choose `Disk configuration` -> `Manual partitioning`. -4. Select the disk on which Windows resides. -5. Select `Create a new partition`. -6. Choose a filesystem type. -7. Determine the start and end sectors for the new partition location (values can be suffixed with various units). -8. Assign the mountpoint `/` to the new partition. -9. Assign the `Boot/ESP` partition the mountpoint `/boot` from the partitioning menu. -10. Confirm your settings and exit to the main menu by choosing `Confirm and exit`. -11. Modify any additional settings for your installation as necessary. -12. Start the installation upon completion of setup. - - -# Mission Statement - -Archinstall promises to ship a [guided installer](https://github.com/archlinux/archinstall/blob/master/archinstall/scripts/guided.py) that follows -the [Arch Linux Principles](https://wiki.archlinux.org/index.php/Arch_Linux#Principles) as well as a library to manage services, packages, and other Arch Linux aspects. - -The guided installer ensures a user-friendly experience, offering optional selections throughout the process. Emphasizing its flexible nature, these options are never obligatory. -In addition, the decision to use the guided installer remains entirely with the user, reflecting the Linux philosophy of providing full freedom and flexibility. - ---- - -Archinstall primarily functions as a flexible library for managing services, packages, and other elements within an Arch Linux system. -This core library is the backbone for the guided installer that Archinstall provides. It is also designed to be used by those who wish to script their own custom installations. - -Therefore, Archinstall will try its best to not introduce any breaking changes except for major releases which may break backward compatibility after notifying about such changes. - - -# Contributing - -Please see [CONTRIBUTING.md](https://github.com/archlinux/archinstall/blob/master/CONTRIBUTING.md) +# Alpha \ No newline at end of file diff --git a/archinstall/applications/monitor.py b/archinstall/applications/monitor.py new file mode 100644 index 0000000000..c0a3d0a58e --- /dev/null +++ b/archinstall/applications/monitor.py @@ -0,0 +1,36 @@ +from typing import TYPE_CHECKING + +from archinstall.lib.models.application import Monitor, MonitorConfiguration +from archinstall.lib.output import debug + +if TYPE_CHECKING: + from archinstall.lib.installer import Installer + + +class MonitorApp: + @property + def htop_package(self) -> list[str]: + return ['htop'] + + @property + def btop_package(self) -> list[str]: + return ['btop'] + + @property + def bottom_package(self) -> list[str]: + return ['bottom'] + + def install( + self, + install_session: 'Installer', + monitor_config: MonitorConfiguration, + ) -> None: + debug(f'Installing monitor: {monitor_config.monitor.value}') + + match monitor_config.monitor: + case Monitor.HTOP: + install_session.add_additional_packages(self.htop_package) + case Monitor.BTOP: + install_session.add_additional_packages(self.btop_package) + case Monitor.BOTTOM: + install_session.add_additional_packages(self.bottom_package) diff --git a/archinstall/default_profiles/desktop.py b/archinstall/default_profiles/desktop.py index ab582186e1..51c4cb32c6 100644 --- a/archinstall/default_profiles/desktop.py +++ b/archinstall/default_profiles/desktop.py @@ -28,7 +28,6 @@ def packages(self) -> list[str]: 'nano', 'vim', 'openssh', - 'htop', 'wget', 'iwd', 'wireless_tools', diff --git a/archinstall/lib/applications/application_handler.py b/archinstall/lib/applications/application_handler.py index e7d16058d5..4f62843db9 100644 --- a/archinstall/lib/applications/application_handler.py +++ b/archinstall/lib/applications/application_handler.py @@ -3,6 +3,7 @@ from archinstall.applications.audio import AudioApp from archinstall.applications.bluetooth import BluetoothApp from archinstall.applications.firewall import FirewallApp +from archinstall.applications.monitor import MonitorApp from archinstall.applications.power_management import PowerManagementApp from archinstall.applications.print_service import PrintServiceApp from archinstall.lib.models import Audio @@ -43,5 +44,11 @@ def install_applications(self, install_session: 'Installer', app_config: Applica app_config.firewall_config, ) + if app_config.monitor_config: + MonitorApp().install( + install_session, + app_config.monitor_config, + ) + application_handler = ApplicationHandler() diff --git a/archinstall/lib/applications/application_menu.py b/archinstall/lib/applications/application_menu.py index 7dd56e9871..acea1e2f83 100644 --- a/archinstall/lib/applications/application_menu.py +++ b/archinstall/lib/applications/application_menu.py @@ -9,6 +9,8 @@ BluetoothConfiguration, Firewall, FirewallConfiguration, + Monitor, + MonitorConfiguration, PowerManagement, PowerManagementConfiguration, PrintServiceConfiguration, @@ -78,6 +80,12 @@ def _define_menu_options(self) -> list[MenuItem]: preview_action=self._prev_firewall, key='firewall_config', ), + MenuItem( + text=tr('Monitor'), + action=select_monitor, + preview_action=self._prev_monitor, + key='monitor_config', + ), ] def _prev_power_management(self, item: MenuItem) -> str | None: @@ -116,6 +124,12 @@ def _prev_firewall(self, item: MenuItem) -> str | None: return f'{tr("Firewall")}: {config.firewall.value}' return None + def _prev_monitor(self, item: MenuItem) -> str | None: + if item.value is not None: + config: MonitorConfiguration = item.value + return f'{tr("Monitor")}: {config.monitor.value}' + return None + def select_power_management(preset: PowerManagementConfiguration | None = None) -> PowerManagementConfiguration | None: group = MenuItemGroup.from_enum(PowerManagement) @@ -240,3 +254,26 @@ def select_firewall(preset: FirewallConfiguration | None = None) -> FirewallConf return FirewallConfiguration(firewall=result.get_value()) case ResultType.Reset: return None + + +def select_monitor(preset: MonitorConfiguration | None = None) -> MonitorConfiguration | None: + group = MenuItemGroup.from_enum(Monitor) + + if preset: + group.set_focus_by_value(preset.monitor) + + result = SelectMenu[Monitor]( + group, + allow_skip=True, + alignment=Alignment.CENTER, + allow_reset=True, + frame=FrameProperties.min(tr('Monitor')), + ).run() + + match result.type_: + case ResultType.Skip: + return preset + case ResultType.Selection: + return MonitorConfiguration(monitor=result.get_value()) + case ResultType.Reset: + return None diff --git a/archinstall/lib/global_menu.py b/archinstall/lib/global_menu.py index dbf728a2cb..76fa5798e0 100644 --- a/archinstall/lib/global_menu.py +++ b/archinstall/lib/global_menu.py @@ -346,6 +346,11 @@ def _prev_applications(self, item: MenuItem) -> str | None: output += f'{tr("Firewall")}: {firewall_config.firewall.value}' output += '\n' + if app_config.monitor_config: + monitor_config = app_config.monitor_config + output += f'{tr("Monitor")}: {monitor_config.monitor.value}' + output += '\n' + return output return None diff --git a/archinstall/lib/models/application.py b/archinstall/lib/models/application.py index 7ecb7a0717..50d76ca077 100644 --- a/archinstall/lib/models/application.py +++ b/archinstall/lib/models/application.py @@ -38,6 +38,16 @@ class FirewallConfigSerialization(TypedDict): firewall: str +class Monitor(StrEnum): + HTOP = 'htop' + BTOP = 'btop' + BOTTOM = 'bottom' + + +class MonitorConfigSerialization(TypedDict): + monitor: str + + class ZramAlgorithm(StrEnum): ZSTD = 'zstd' LZO_RLE = 'lzo-rle' @@ -52,6 +62,7 @@ class ApplicationSerialization(TypedDict): power_management_config: NotRequired[PowerManagementConfigSerialization] print_service_config: NotRequired[PrintServiceConfigSerialization] firewall_config: NotRequired[FirewallConfigSerialization] + monitor_config: NotRequired[MonitorConfigSerialization] @dataclass @@ -126,6 +137,22 @@ def parse_arg(arg: dict[str, Any]) -> 'FirewallConfiguration': ) +@dataclass +class MonitorConfiguration: + monitor: Monitor + + def json(self) -> MonitorConfigSerialization: + return { + 'monitor': self.monitor.value, + } + + @staticmethod + def parse_arg(arg: MonitorConfigSerialization) -> 'MonitorConfiguration': + return MonitorConfiguration( + Monitor(arg['monitor']), + ) + + @dataclass(frozen=True) class ZramConfiguration: enabled: bool @@ -148,6 +175,7 @@ class ApplicationConfiguration: power_management_config: PowerManagementConfiguration | None = None print_service_config: PrintServiceConfiguration | None = None firewall_config: FirewallConfiguration | None = None + monitor_config: MonitorConfiguration | None = None @staticmethod def parse_arg( @@ -175,6 +203,9 @@ def parse_arg( if args and (firewall_config := args.get('firewall_config')) is not None: app_config.firewall_config = FirewallConfiguration.parse_arg(firewall_config) + if args and (monitor_config := args.get('monitor_config')) is not None: + app_config.monitor_config = MonitorConfiguration.parse_arg(monitor_config) + return app_config def json(self) -> ApplicationSerialization: @@ -195,4 +226,7 @@ def json(self) -> ApplicationSerialization: if self.firewall_config: config['firewall_config'] = self.firewall_config.json() + if self.monitor_config: + config['monitor_config'] = self.monitor_config.json() + return config diff --git a/build_iso.sh b/build_iso.sh index c9cb754f3e..e1e2767b66 100755 --- a/build_iso.sh +++ b/build_iso.sh @@ -1,53 +1,53 @@ -#!/bin/bash +# #!/bin/bash -set -e +# set -e -packages_file="/tmp/archlive/packages.x86_64" +# packages_file="/tmp/archlive/packages.x86_64" -# Packages to add to the archiso profile packages -packages=( - gcc - git - pkgconfig - python - python-pip - python-uv - python-setuptools - python-pyparted - python-pydantic - python-textual -) +# # Packages to add to the archiso profile packages +# packages=( +# gcc +# git +# pkgconfig +# python +# python-pip +# python-uv +# python-setuptools +# python-pyparted +# python-pydantic +# python-textual +# ) -if [ -d "/tmp/archlive" ]; then - rm -rf "/tmp/archlive" -fi -mkdir -p /tmp/archlive/airootfs/root/archinstall-git -cp -r . /tmp/archlive/airootfs/root/archinstall-git +# if [ -d "/tmp/archlive" ]; then +# rm -rf "/tmp/archlive" +# fi +# mkdir -p /tmp/archlive/airootfs/root/archinstall-git +# cp -r . /tmp/archlive/airootfs/root/archinstall-git -cat <<- _EOF_ | tee /tmp/archlive/airootfs/root/.zprofile - cd archinstall-git - rm -rf dist +# cat <<- _EOF_ | tee /tmp/archlive/airootfs/root/.zprofile +# cd archinstall-git +# rm -rf dist - uv build --no-build-isolation --wheel - uv pip install dist/*.whl --break-system-packages --system --no-build --no-deps +# uv build --no-build-isolation --wheel +# uv pip install dist/*.whl --break-system-packages --system --no-build --no-deps - echo "This is an unofficial ISO for development and testing of archinstall. No support will be provided." - echo "This ISO was built from Git SHA $GITHUB_SHA" - echo "Type archinstall to launch the installer." -_EOF_ +# echo "This is an unofficial ISO for development and testing of archinstall. No support will be provided." +# echo "This ISO was built from Git SHA $GITHUB_SHA" +# echo "Type archinstall to launch the installer." +# _EOF_ -pacman --noconfirm -S archiso +# pacman --noconfirm -S archiso -cp -r /usr/share/archiso/configs/releng/* /tmp/archlive +# cp -r /usr/share/archiso/configs/releng/* /tmp/archlive -sed -i /archinstall/d "$packages_file" +# sed -i /archinstall/d "$packages_file" -# Add packages to the archiso profile packages -for package in "${packages[@]}"; do - echo "$package" >> "$packages_file" -done +# # Add packages to the archiso profile packages +# for package in "${packages[@]}"; do +# echo "$package" >> "$packages_file" +# done -find /tmp/archlive -cd /tmp/archlive +# find /tmp/archlive +# cd /tmp/archlive -mkarchiso -v -w work/ -o out/ ./ +# mkarchiso -v -w work/ -o out/ ./