Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for different distributions filesystems #12

Open
2 of 5 tasks
TechSupportJosh opened this issue Dec 31, 2020 · 6 comments
Open
2 of 5 tasks

Support for different distributions filesystems #12

TechSupportJosh opened this issue Dec 31, 2020 · 6 comments
Assignees
Labels
enhancement New feature or request in progress This issue is currently being worked on.

Comments

@TechSupportJosh
Copy link
Collaborator

TechSupportJosh commented Dec 31, 2020

Describe the solution you'd like
It would be great if we could use different distributions for the Netkit VMs rather than solely Debian. This could allow us to do something like this inside lab.conf files:

machineA[distro]=arch
machineB[distro]=ubuntu
machineC[distro]=debian

This would then mean machineA uses Arch for it's filesystem, machineB uses Ubuntu for it's filesystem and machineC uses the traditional Debian.

Our current build method uses debootstrap to build a Debian filesystem. debootstrap also has support for Ubuntu and therefore wouldn't be too much hassle changing. Arch uses pacstrap, which is very similar to debootstrap, making it a very viable option.

Implementation steps

  • Expose a variable at compile time to select which distribution of filesystem you would like to create (or an option for all, however we may be restricted by the host OS not having the command - Arch has debootstrap but Debian does not have pacstrap).
  • Create some form of shared build process between all different distributions (installing packages is likely the same on each distribution, but the initial creation will vary).
  • Create a shared folder for filesystem-tweaks and distribution specific filesystem-tweaks. Different distributions have different methods for providing ttys, logins, etc. and therefore will need specific tweaks to the shared tweaks.
  • Modify vstart scripts to support selecting a filesystem folder depending on distribution asked for. For example, we should be able to do vstart machineA --distro=arch. Therefore, we need to remove the netkit-fs symlink and replace it with something more like netkit-fs-debian, netkit-fs-arch, etc.
  • Modify lab.conf processing to pass --distro options using machineA[distro]=arch format.

We will also need to take care about not making updating Netkit really difficult. Wherever possible, we need to limit the number of changes and ensure they're well documented and therefore maintainable. This process will become easier when we have proper testing of Netkit releases.

@TechSupportJosh TechSupportJosh added enhancement New feature or request in progress This issue is currently being worked on. labels Dec 31, 2020
@b177y
Copy link
Contributor

b177y commented Jan 5, 2021

Some ideas for multiple filesystem implementation

File structure

/etc/netkit

  • netkit.conf
  • tmux.conf
  • filesystems.json
  • kernels.json
  • etc..

json files could be in some other format, but just something with filesystem / kernel name, version, url (from github release page) etc. For filesystems we could have something like 'compatible kernels' - not that its likely people will be swapping them around but it shouldnt be too difficult to add. The official filesystem and kernel files could be downloaded from github so that new filesystems are available before a new release of netkit core.

just a quick example:

{
    'default': 'debian:latest'
    'filesystems': [
        'debian': {
            'latest': '1.0.0'
            'versions': [
                '1.0.0': {
                    'fs_url': 'https://github.com/netkit-jh/netkit-jh-build/releases/download/1.0.0/netkit-fs-debian-1.0.0.tar.bz2',
                    'hash_url': 'https://github.com/netkit-jh/netkit-jh-build/releases/download/1.0.0/netkit-fs-debian-1.0.0.sha256',
                    'compatible_kernels': [
                        'linux-5.1.4:latest',
                        'linux-5.1.4:0.1.18'
                    ] 
                 }
            ]
    }
]
}

$HOME/.netkit-jh

filesystems

This could contain downloaded filesystems, custom filesystems and a json file for specifying custom filesystems. E.g. you've built your own for a particular purpose, or you want to define the path to filesystems build for dev purposes, so you can quickly test with vstart --filesystem=debian-dev

kernels

This could contain downloaded kernels, custom kernels and a json file for specifying custom kernels.

The custom json files for filesystems and kernels could be similar to the official ones in /etc/netkit but allow filepaths in addition to urls.

vstart

We would want vstart to be able to take options for --filesystem and --kernel. This would then need to look to see if the fs or kernel is downloaded to the $HOME/.netkit-jh directory and compare to the hash. If it is then all good, add those to $KERNELCMD, if not, attempt to download the filesystem (or exit and tell the user to download the fs?).

lstart

Need to be able to take --filesystem and --kernel from lstart and pass that to vstart.

Also lstart might be a good place to check if the official kernel and filesystem json files in /etc/netkit are up to date with the latest on github.

lab.conf

Would be useful to have an option for shared[kernel]=linux-5.1.4 and shared[filesystem]=ubuntu:1.0.0 to make a default for the lab, which could then be overriden with machine assignments, as mentioned in the opening of this issue -

machineA[filesystem]=arch
machineB[filesystem]=debian
machineC[kernel]=linux-hardened-5.1.1

new command for managing fs and kernels

not sure what this one would be called but something where you can download and delete downloaded filesystems and kernels. This should also just have an easy update option for those who dont care about custom fs / kernels, to just delete the current stuff and download the latest of debian.

Release Versions

This could be done a bit like docker tags, where the default is filesystem:latest / kernel:latest, but still with options to choose earlier versions. The default config should probably be to keep the latest debian filesystem, and delete old ones when downloading the new one, but this should be configurable. With this, versioning refers to changes weve made to a filesystem or kernel, not versions of the fs / kernel themselves (we wouldnt tag them like ubuntu:18.04 and ubuntu:20.04, we'd tag them as ubuntu-focal:1.0.0, ubuntu-bionic:1.0.0 as the versions are reflecting changes we've made to kernels and filesystems like patches and other improvements)

Core

I'm not sure where is best to install to the core tools to, but probably somewhere that is in the $PATH by default - usually when you install something you dont have to update your bashrc / zshrc to reflect that. When you install / update netkit, you should be installing the core tools and configuration - and these should handle updates in filesystems and kernels, rather than the releases being baked together. This means when theres a new filesystem or kernel its immediately available, or when theres an update to core, people dont need to reinstall filesystems.

These are just some ideas i've come up with that might be worth considering when thinking about multi-filesystem support. By not having large filesystems and kernels built into the package it might be possible to consider adding netkit to package repositories, e.g. the AUR.

@TechSupportJosh
Copy link
Collaborator Author

TechSupportJosh commented Jan 13, 2021

From conversating with @b177y and @AdamBromiley, our current plan of action is this:

  • We will seperate core versions from filesystem versions, to facilitate the ability to release new versions without having to update the core every time.
  • We will have try get a hosted file site to allow us to host all versions of filesystems/kernels. At the root of this is a releaseinfo file (name tbc) which contains info about all filesystems, their supported kernels, supported core versions and information about the filesystem itself. There will be a kernel version as well.

For each kernel or filesystem, we will have a tag associated with it in this format:
Kernel: KERNEL_TYPE:KERNEL_VERSION:RELEASE_VERSION
Filesystem: DISTRO:CODENAME:RELEASE_VERSION

Therefore, if you wanted to download v3 of Ubuntu Focal, you can specify ubuntu:focal:v3. Wherever a tag is missing, latest is implied. Therefore just debian specifies the latest Debian codename with the latest Netkit release version. debian:bullseye specifies the latest Debian Bullseye available, etc.

RELEASE_VERSION is where we release patches to the same FS or kernel version. For example, if we fix a bug in the 5.10.4 kernel, RELEASE_VERSION will increment. This is because we may fix multiple things at different times for the same kernel version, therefore relying on just the kernel version is not sufficient.

Each entry within the releaseinfo looks like this (the format allows us to parse in bash easily)
Kernel:

== KERNEL RELEASE ==
KERNEL_TYPE=linux
KERNEL_VERSION=5.10.4
RELEASE_VERSION=2
DOWNLOAD_LINK=https://netkit-jh.com/files/kernel/linux/5.10.4/v2.tar.bz2
SHA256_HASH=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
== END ==

Description of each parameter:

  • TYPE: Type of kernel - linux is the standard UML linux kernel, linux-hardened for the linux-hardened kernel
  • KERNEL_VERSION: The kernel version of the kernel.
  • RELEASE_VERSION: The release version for this TYPE:KERNEL_VERSION for Netkit.
  • DOWNLOAD_LINK: Link to the filesystem archive to download it from.
  • SHA256_HASH: SHA256 hash of the archive.

Filesystem:

== FILESYSTEM RELEASE ==
DISTRO=ubuntu
CODENAME=focal
RELEASE_VERSION=3
MIN_CORE=1.2.0
MAX_CORE=1.7.0
MIN_KERNEL=linux:5.10.4:v3,linux-hardened:5.10.4:v5
MAX_KERNEL=linux:5.11:v1,linux-hardened:5.11:v1
DOWNLOAD_LINK=https://netkit-jh.com/files/filesystem/ubuntu/focal/v3.tar.bz2
SHA256_HASH=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
== END ==

Description of each parameter:

  • DISTRO: Distribution of the filesystem (Ubuntu, Arch, Debian, etc.)
  • CODENAME: Codename for the filesystem (Bullseye, Jessie, Bionic, Focal, rolling (for arch))
  • RELEASE_VERSION: The release version for this DISTRO:CODENAME for Netkit.
  • MIN_CORE: Minimum version of the core toolset required to run this filesystem.
  • MAX_CORE: Maximum version of the core toolset allowed to run this filesystem.
  • MIN_KERNEL: Comma seperated list of the minimum versions of the kernel required to run this filesystem.
  • MAX_KERNEL: Comma seperated list of the maximum versions allowed to run this filesystem.
  • DOWNLOAD_LINK: Link to the filesystem archive to download it from.
  • SHA256_HASH: SHA256 hash of the archive.

When files are downloaded (using the tools described later on), they will end up looking like this within the install directory:

netkit-jh
├── fs
│   └── distros
│       ├── arch
│       │   └── rolling
│       │       └── v1
│       │           └── netkit-fs
│       └── ubuntu
│           └── focal
│               └── v3
│                   └── netkit-fs
├── fs-releaseinfo
├── kernel
│   ├── linux
│   │   ├── 5.10.4
│   │   │   ├── v3
│   │   │   │   └── netkit-kernel
│   │   │   └── v4
│   │   │       └── netkit-kernel
│   │   └── 5.11
│   │       └── v1
│   │           └── netkit-kernel
│   └── linux-hardened
│       └── 5.10.4
│           ├── v1
│           │   └── netkit-kernel
│           └── v2
│               └── netkit-kernel
└── kernel-releaseinfo

In order to manage the downloading of these filesystems and kernels, two new tools will be created. netkit-fs and netkit-kernel will use commands similar to apt.

netkit-fs [ install | update | upgrade | search ] and netkit-kernel [ install | update | upgrade | search ]

Description of each of the commands:
install [tag]
[tag] can be:
ubuntu or ubuntu:focal or ubuntu:focal:v3
or
linux or linux:5.10.4 or linux:5.10.4:v4
depending on exactly which version you want. For most people, they would want to do netkit-fs install debian and netkit-kernel install linux.

upgrade [tag]
Upgrade will download and install the latest version of the release related to the tag. For example, if ubuntu was specified, ubuntu:latest:latest will be installed. If ubuntu:focal was specified, the latest version of Ubuntu Focal will be installed.

update [tag]
Similar to apt update, the latest releaseinfo files will be retrieved. This will then allow users to search for newer releases.

search [tag]
This will allow users to search for releases related to [tag]. For example, netkit-fs search ubuntu will show all Ubuntu relases. Note, this command parses the downloaded releaseinfos (just like apt) and therefore will recommend users do netkit-fs/kernel update before running this command.

@TechSupportJosh
Copy link
Collaborator Author

netkit-fs list [tag] / netkit-kernel list [tag]
List currently installed filesystems/kernels, related to tag if they specify a tag.

@TechSupportJosh
Copy link
Collaborator Author

TechSupportJosh commented Jan 13, 2021

Added metadata files to each release as well as symlinks to latest, which will be used when not specifying a specific version. The latest symlinks will be updated when installing a new fs/kernel. If the one referenced by latest is older than the one currently being installed, the latest symlink will be removed and recreated.

multidist
├── fs
│   └── distros
│       ├── arch
│       │   ├── latest -> rolling
│       │   └── rolling
│       │       ├── latest -> v1
│       │       └── v1
│       │           ├── fs-metadata
│       │           └── netkit-fs
│       └── ubuntu
│           ├── focal
│           │   ├── latest -> v3
│           │   └── v3
│           │       ├── fs-metadata
│           │       └── netkit-fs
│           └── latest -> focal
├── fs-releaseinfo
├── kernel
│   ├── linux
│   │   ├── 5.10.4
│   │   │   ├── latest -> v4
│   │   │   ├── v3
│   │   │   │   ├── kernel-metadata
│   │   │   │   └── netkit-kernel
│   │   │   └── v4
│   │   │       ├── kernel-metadata
│   │   │       └── netkit-kernel
│   │   ├── 5.11
│   │   │   ├── latest -> v1
│   │   │   └── v1
│   │   │       ├── kernel-metadata
│   │   │       └── netkit-kernel
│   │   └── latest -> 5.11
│   └── linux-hardened
│       ├── 5.10.4
│       │   ├── latest -> v2
│       │   ├── v1
│       │   │   ├── kernel-metadata
│       │   │   └── netkit-kernel
│       │   └── v2
│       │       ├── kernel-metadata
│       │       └── netkit-kernel
│       └── latest -> 5.10.4
└── kernel-releaseinfo

@TechSupportJosh
Copy link
Collaborator Author

Installed filesystems / kernels will be listed under installed-fs / installed-kernel. It will feature a somewhat similar format to releaseinfo:

=== ENTRY ===
TAG=ubuntu:focal:v3
DIRECTORY=/home/netkit-jh/fs/distros/ubuntu/focal/v3
=== END ===

This then allows us to do uninstall commands, by deleting the DIRECTORY tag, possibly updating latest -> and delete the entry. This will also allow us to keep track of fs/kernels installed using local files, rather than retrieving them from our file server (e.g. for development, something like netkit-fs install debian:dev:v1 /home/josh/netkit-jh-build/...

@TechSupportJosh
Copy link
Collaborator Author

Now we're using python for netkit-fs/kernel, releaseinfo will look something like this:

{
    "arch": {
        "rolling": {
            "v1": {
                "min_core": "1.2.0",
                "max_core": "1.7.0",
                "min_kernel": ["linux:5.10.4:v3", "linux-hardened:5.10.4:v6"],
                "max_kernel": ["linux:5.11:v1", "linux-hardened:5.11:v1"],
                "download_url": "https://meme.com/arch/rolling/v1/fs.tar.bz2",
                "sha256_hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
            }
        }
    },
    "debian": {
        "bullseye": {
            "v1": {
                "min_core": "1.2.0",
                "max_core": "1.7.0",
                "min_kernel": ["linux:5.10.4:v3", "linux-hardened:5.10.4:v6"],
                "max_kernel": ["linux:5.11:v1", "linux-hardened:5.11:v1"],
                "download_url": "https://meme.com/debian/bullseye/v1/fs.tar.bz2",
                "sha256_hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
            },
            "v2": {
                "min_core": "1.2.0",
                "min_kernel": ["linux:5.10.4:v3", "linux-hardened:5.10.4:v6"],
                "download_url": "https://meme.com/debian/bullseye/v2/fs.tar.bz2",
                "sha256_hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
            }
        },
        "jessie": {
            "v1": {
                "min_core": "1.2.0",
                "min_kernel": ["linux:5.10.4:v3", "linux-hardened:5.10.4:v6"],
                "download_url": "https://meme.com/debian/jessie/v1/fs.tar.bz2",
                "sha256_hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
            }
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request in progress This issue is currently being worked on.
Projects
None yet
Development

No branches or pull requests

2 participants