├── .github ├── FUNDING.yml ├── debian.png └── ubuntu.png ├── LICENSE.md ├── README.md ├── docs ├── Makefile ├── README.md ├── machinespawn.1 ├── machinespawn.1.md └── pandoc-man.mk └── machinespawn /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: flexiondotorg 4 | patreon: wimpysworld 5 | custom: https://wimpysworld.io/tip -------------------------------------------------------------------------------- /.github/debian.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wimpysworld/machinespawn/26f599c2bf4cd1bfdf695bef98abd3eecd3b7106/.github/debian.png -------------------------------------------------------------------------------- /.github/ubuntu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wimpysworld/machinespawn/26f599c2bf4cd1bfdf695bef98abd3eecd3b7106/.github/ubuntu.png -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2022 Martin Wimpress 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 6 | machinespawn 7 |

8 | 9 | # This project is discontinued ☠️ 10 | 11 | **machinespwn was an interesting learning experience, but if you're looking for something similar that is feature complete, then I recommend the excellent [Distrobox](https://distrobox.it) with [Podman](https://podman.io/).** 12 | 13 | ----- 14 | 15 |

Quickly stand up systemd-nspawn containers 16 |
17 | Made with 💝 for & 18 |

19 | 20 | # Introduction 21 | 22 | A nifty and performant way to quickly create, stand up or manage [`systemd-nspawn`](https://www.freedesktop.org/software/systemd/man/systemd-nspawn.html) containers, `machinespawn` uses [`debootstrap`](https://wiki.debian.org/Debootstrap) and [`machinectl`](https://www.freedesktop.org/software/systemd/man/machinectl.html) and [`systemd-nspawn`](https://www.freedesktop.org/software/systemd/man/systemd-nspawn.html) to build run and remove minimal OS images. It is useful for that, and also as a stage to quickly build custom container or ISO images. 23 | 24 | This project is currently a work-in-progress 🚧 and under active development so treat as alpha software and approach with caution 🛑 However `machinespawn` is already key part of the [Ubuntu Butterfly 🦋](https://github.com/butterfly-garden) [build process](https://github.com/butterfly-garden/image-build). 25 | 26 | ## Participate 27 | 28 | We have a Discord for this project: [![Discord](https://img.shields.io/discord/712850672223125565?color=0C306A&label=WimpysWorld%20Discord&logo=Discord&logoColor=ffffff&style=flat-square)](https://discord.gg/sNmz3uw) 29 | 30 | To see it in action, or to watch it becoming, you can watch these videos where I go from an idea to a working full-featured prototype of `machinespawn`. 31 | 32 | [![machinespawn! 🐧 Dev tooling from concept to production 🧑‍💻](https://img.youtube.com/vi/-bQQ6QlXpJQ/0.jpg)](https://www.youtube.com/watch?v=-bQQ6QlXpJQ) 33 | 34 | I live stream the development of `machinespawn` and other project on [Wimpy's World Twitch channel](https://twitch.tv/WimpysWorld). 35 | 36 | ## Requirements 37 | 38 | This script relies on utilities, many of which are typically already installed on most Debian or Ubuntu systems. The following will ensure you have all you need: 39 | 40 | ```bash 41 | sudo apt-get install debootstrap binutils iproute2 systemd-container wget 42 | ``` 43 | 44 | ### Caching Proxy *(optional)* 45 | 46 | If `apt-cacher-ng` is installed on the host `machinespawn` will automatically detect its presence and use it for container bootstrapping and executing commands inside the container with `run`. Install and configure `apt-cache-ng` as follows: 47 | 48 | ```bash 49 | sudo apt-get install apt-cacher-ng 50 | ``` 51 | 52 | Create `/etc/apt-cacher-ng/zz_debconf.conf` with the following in it: 53 | 54 | ``` 55 | PassThroughPattern: .* 56 | ``` 57 | 58 | Once the above `PassThroughPattern` is set, `apt-cacher-ng` will proxy but not cache objects stored on SSL/TLS repositories. 59 | 60 | ## Supported distros 61 | 62 | Currently the following distros are supported: 63 | 64 | * Debian Releases 65 | * 8 (jessie) 66 | * 9 (stretch) 67 | * 10 (buster) 68 | * 11 (bullseye) 69 | * 12 (bookworm) 70 | 71 | * Ubuntu Releases 72 | * 16.04 (xenial) 73 | * 18.04 (bionic) 74 | * 20.04 (focal) 75 | * 22.04 (jammy) 76 | * 22.10 (kinetic) 77 | 78 | ### Architecture Support 79 | 80 | Containers can be built for the host architecture or cross-bootstrapped for the following machine architectures: 81 | 82 | * amd64 83 | * i386 84 | * armhf 85 | * arm64 86 | 87 | # Usage 88 | 89 | `machinespawn` currently needs to be run as root via `sudo` 90 | 91 | ```bash 92 | sudo machinespawn [command] 93 | ``` 94 | 95 | ## Commands 96 | 97 | ### `bootstrap` 98 | 99 | Build a machine from scratch. 100 | 101 | The first build of a machine type and architecture may be quite heavy on time and resource usage, but intelligent caching, together with detection and use of local package caching proxies, should make this as efficient as possible and significantly reduce subsequent builds or re-builds. 102 | 103 | The following bootstrap a container called 'bob' using Ubuntu 22.04 *(Jammy Jellyfish)* as the base. 104 | 105 | ```bash 106 | sudo machinespawn ubuntu-22.04 bob 107 | ``` 108 | 109 | Here's an example that would bootstrap a Debian 11 container called 'fred': 110 | 111 | ```bash 112 | sudo machinespawn debian-11 fred 113 | ``` 114 | 115 | ### `list` 116 | 117 | List the existing images (by default these will be found in `/var/lib/machines/`) 118 | 119 | ### `run` 120 | 121 | Execute commands inside the container or start an interactive shell. 122 | 123 | ```bash 124 | sudo machinespawn run bob /usr/bin/bash 125 | ``` 126 | 127 | ### `clean-cache` 128 | 129 | Remove cached content from `/var/cache/machinespawn`. This will release space taken by downloaded packages at the expense of needing to re-download if required. 130 | 131 | ### `pull-tar` 132 | 133 | ```bash 134 | machinespawn pull-tar 135 | ``` 136 | 137 | Downloads a .tar container image from the specified URL, and makes it available under the specified local machine name. The URL must be of type "http://" or "https://", and must refer to a .tar, .tar.gz, .tar.xz or .tar.bz2 archive file 138 | 139 | ```bash 140 | sudo macheinespawn pull-tar https://download.fedoraproject.org/pub/fedora/linux/releases/36/Cloud/x86_64/images/Fedora-Cloud-Base-36-1.5.x86_64.raw.xz FedoraCloudBase36 141 | ``` 142 | 143 | ### `remove` 144 | 145 | Completely remove a machine from `/var/lib/machines/` 146 | 147 | ## Reference 148 | 149 | * [debbootstrap](https://wiki.debian.org/Debootstrap) 150 | * [machinectl](https://www.freedesktop.org/software/systemd/man/machinectl.html) 151 | * [systemd-nspawn](https://www.freedesktop.org/software/systemd/man/systemd-nspawn.html) 152 | 153 | ## TODOs 154 | 155 | These important features are not *yet* implemented here. 156 | - [x] Publish in GitHub 157 | - [ ] Add support for other distros 158 | - container_pull_tar() should accept a distro argument or a tarball URL 159 | - [ ] Add support for starting/stopping 160 | - [ ] Add support for enabling/disabling 161 | - [ ] Add supporting for container booting 162 | - [ ] Add support for debootstrap variants 163 | - [ ] Check the required tools are installed 164 | - [ ] User provisioning 165 | - [ ] Home directory mounting 166 | - [ ] Bind sockets, audio, display servers and authority 167 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | include pandoc-man.mk 2 | 3 | ifeq ($(PREFIX),) 4 | PREFIX := /usr/local 5 | endif 6 | 7 | datarootdir := $(PREFIX)/share 8 | datadir := $(datarootdir) 9 | mandir := $(datarootdir)/man 10 | bindir := $(PREFIX)/bin 11 | 12 | all: machinespawn.1 13 | 14 | clean: 15 | rm *.1 16 | 17 | install_docs: all 18 | install -d $(DESTDIR)$(mandir)/man1 19 | install -m 644 machinespawn.1 $(DESTDIR)$(mandir)/man1 20 | 21 | # install -m 644 quickgui.1 $(DESTDIR)$(mandir)/man1 22 | 23 | install_bins: 24 | install -d $(DESTDIR)$(bindir) 25 | install -m 755 ../machinespawn $(DESTDIR)$(bindir) 26 | 27 | install: install_bins install_docs 28 | 29 | uninstall:: 30 | rm -f $(DESTDIR)$(mandir)/man1/machinespawn.1 31 | rm -f $(DESTDIR)$(bindir)/machinespawn 32 | 33 | 34 | .PHONY: all 35 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | ../README.md -------------------------------------------------------------------------------- /docs/machinespawn.1: -------------------------------------------------------------------------------- 1 | .\" Automatically generated by Pandoc 2.19.2 2 | .\" 3 | .\" Define V font for inline verbatim, using C font in formats 4 | .\" that render this, and otherwise B font. 5 | .ie "\f[CB]x\f[]"x" \{\ 6 | . ftr V B 7 | . ftr VI BI 8 | . ftr VB B 9 | . ftr VBI BI 10 | .\} 11 | .el \{\ 12 | . ftr V CR 13 | . ftr VI CI 14 | . ftr VB CB 15 | . ftr VBI CBI 16 | .\} 17 | .TH "MACHINESPAWN" "1" "November 17, 2022" "machinespawn" "machinespawn Manual" 18 | .hy 19 | .SH Machinespawn 20 | .PP 21 | Quickly stand up systemd_nspawn containers 22 | .SS Introduction 23 | .PP 24 | A nifty and performant way to quickly create, stand up or manage 25 | \f[V]systemd-nspawn\f[R] (https://www.freedesktop.org/software/systemd/man/systemd-nspawn.html) 26 | containers, \f[V]machinespawn\f[R] uses 27 | \f[V]debootstrap\f[R] (https://wiki.debian.org/Debootstrap) and 28 | \f[V]machinectl\f[R] (https://www.freedesktop.org/software/systemd/man/machinectl.html) 29 | and 30 | \f[V]systemd-nspawn\f[R] (https://www.freedesktop.org/software/systemd/man/systemd-nspawn.html) 31 | to build run and remove minimal OS images. 32 | It is useful for that, and also as a stage to quickly build custom 33 | container or ISO images. 34 | .PP 35 | This project is currently a work-in-progress \[u1F6A7] and under active 36 | development so treat as alpha software and approach with caution 37 | \[u1F6D1] However \f[V]machinespawn\f[R] is already key part of the 38 | Ubuntu Butterfly \[u1F98B] (https://github.com/butterfly-garden) build 39 | process (https://github.com/butterfly-garden/image-build). 40 | .SS Participate 41 | .PP 42 | We have a Discord for this project: 43 | [IMAGE: Discord (https://img.shields.io/discord/712850672223125565?color=0C306A&label=WimpysWorld%20Discord&logo=Discord&logoColor=ffffff&style=flat-square)] (https://discord.gg/sNmz3uw) 44 | .PP 45 | To see it in action, or to watch it becoming, you can watch these videos 46 | where I go from an idea to a working full-featured prototype of 47 | \f[V]machinespawn\f[R]. 48 | .PP 49 | [IMAGE: machinespawn! 50 | \[u1F427] Dev tooling from concept to production 51 | \[u1F9D1]\[u200D]\[u1F4BB] (https://img.youtube.com/vi/-bQQ6QlXpJQ/0.jpg)] (https://www.youtube.com/watch?v=-bQQ6QlXpJQ) 52 | .PP 53 | I live stream the development of \f[V]machinespawn\f[R] and other 54 | project on Wimpy\[cq]s World Twitch 55 | channel (https://twitch.tv/WimpysWorld). 56 | .SS Requirements 57 | .PP 58 | This script relies on utilities, many of which are typically already 59 | installed on most Debian or Ubuntu systems. 60 | The following will ensure you have all you need: 61 | .IP 62 | .nf 63 | \f[C] 64 | sudo apt-get install debootstrap binutils iproute2 systemd-container wget 65 | \f[R] 66 | .fi 67 | .SS Caching Proxy \f[I](optional)\f[R] 68 | .PP 69 | If \f[V]apt-cacher-ng\f[R] is installed on the host 70 | \f[V]machinespawn\f[R] will automatically detect its presence and use it 71 | for container bootstrapping and executing commands inside the container 72 | with \f[V]run\f[R]. 73 | Install and configure \f[V]apt-cache-ng\f[R] as follows: 74 | .IP 75 | .nf 76 | \f[C] 77 | sudo apt-get install apt-cacher-ng 78 | \f[R] 79 | .fi 80 | .PP 81 | Create \f[V]/etc/apt-cacher-ng/zz_debconf.conf\f[R] with the following 82 | in it: 83 | .IP 84 | .nf 85 | \f[C] 86 | PassThroughPattern: .* 87 | \f[R] 88 | .fi 89 | .PP 90 | Once the above \f[V]PassThroughPattern\f[R] is set, 91 | \f[V]apt-cacher-ng\f[R] will proxy but not cache objects stored on 92 | SSL/TLS repositories. 93 | .SS Supported distros 94 | .PP 95 | Currently the following distros are supported: 96 | .IP \[bu] 2 97 | Debian Releases 98 | .RS 2 99 | .IP \[bu] 2 100 | 8 (jessie) 101 | .IP \[bu] 2 102 | 9 (stretch) 103 | .IP \[bu] 2 104 | 10 (buster) 105 | .IP \[bu] 2 106 | 11 (bullseye) 107 | .IP \[bu] 2 108 | 12 (bookworm) 109 | .RE 110 | .IP \[bu] 2 111 | Ubuntu Releases 112 | .RS 2 113 | .IP \[bu] 2 114 | 16.04 (xenial) 115 | .IP \[bu] 2 116 | 18.04 (bionic) 117 | .IP \[bu] 2 118 | 20.04 (focal) 119 | .IP \[bu] 2 120 | 22.04 (jammy) 121 | .IP \[bu] 2 122 | 22.10 (kinetic) 123 | .RE 124 | .SS Architecture Support 125 | .PP 126 | Containers can be built for the host architecture or cross-bootstrapped 127 | for the following machine architectures: 128 | .IP \[bu] 2 129 | amd64 130 | .IP \[bu] 2 131 | i386 132 | .IP \[bu] 2 133 | armhf 134 | .IP \[bu] 2 135 | arm64 136 | .SH Usage 137 | .PP 138 | \f[V]machinespawn\f[R] currently needs to be run as root via 139 | \f[V]sudo\f[R] 140 | .IP 141 | .nf 142 | \f[C] 143 | sudo machinespawn [command] 144 | \f[R] 145 | .fi 146 | .SS Commands 147 | .SS \f[V]bootstrap\f[R] 148 | .PP 149 | Build a machine from scratch. 150 | .PP 151 | The first build of a machine type and architecture may be quite heavy on 152 | time and resource usage, but intelligent caching, together with 153 | detection and use of local package caching proxies, should make this as 154 | efficient as possible and significantly reduce subsequent builds or 155 | re-builds. 156 | .PP 157 | The following bootstrap a container called `bob' using Ubuntu 22.04 158 | \f[I](Jammy Jellyfish)\f[R] as the base. 159 | .IP 160 | .nf 161 | \f[C] 162 | sudo machinespawn ubuntu-22.04 bob 163 | \f[R] 164 | .fi 165 | .PP 166 | Here\[cq]s an example that would bootstrap a Debian 11 container called 167 | `fred': 168 | .IP 169 | .nf 170 | \f[C] 171 | sudo machinespawn debian-11 fred 172 | \f[R] 173 | .fi 174 | .SS \f[V]list\f[R] 175 | .PP 176 | List the existing images (by default these will be found in 177 | \f[V]/var/lib/machines/\f[R]) 178 | .SS \f[V]run\f[R] 179 | .PP 180 | Execute commands inside the container or start an interactive shell. 181 | .IP 182 | .nf 183 | \f[C] 184 | sudo machinespawn run bob /usr/bin/bash 185 | \f[R] 186 | .fi 187 | .SS \f[V]clean-cache\f[R] 188 | .PP 189 | Remove cached content from \f[V]/var/cache/machinespawn\f[R]. 190 | This will release space taken by downloaded packages at the expense of 191 | needing to re-download if required. 192 | .SS \f[V]pull-tar\f[R] 193 | .IP 194 | .nf 195 | \f[C] 196 | machinespawn pull-tar 197 | \f[R] 198 | .fi 199 | .PP 200 | Downloads a .tar container image from the specified URL, and makes it 201 | available under the specified local machine name. 202 | The URL must be of type \[lq]http://\[rq] or \[lq]https://\[rq], and 203 | must refer to a .tar, .tar.gz, .tar.xz or .tar.bz2 archive file 204 | .IP 205 | .nf 206 | \f[C] 207 | sudo macheinespawn pull-tar https://download.fedoraproject.org/pub/fedora/linux/releases/36/Cloud/x86_64/images/Fedora-Cloud-Base-36-1.5.x86_64.raw.xz FedoraCloudBase36 208 | \f[R] 209 | .fi 210 | .SS \f[V]remove\f[R] 211 | .PP 212 | Completely remove a machine from \f[V]/var/lib/machines/\f[R] 213 | .SS Reference 214 | .IP \[bu] 2 215 | debbootstrap (https://wiki.debian.org/Debootstrap) 216 | .IP \[bu] 2 217 | machinectl (https://www.freedesktop.org/software/systemd/man/machinectl.html) 218 | .IP \[bu] 2 219 | systemd-nspawn (https://www.freedesktop.org/software/systemd/man/systemd-nspawn.html) 220 | .SH AUTHORS 221 | Martin Wimpress. 222 | -------------------------------------------------------------------------------- /docs/machinespawn.1.md: -------------------------------------------------------------------------------- 1 | --- 2 | author: Martin Wimpress 3 | date: November 17, 2022 4 | footer: machinespawn 5 | header: machinespawn Manual 6 | section: 1 7 | title: MACHINESPAWN 8 | --- 9 | 10 | 11 | # Machinespawn 12 | 13 | Quickly stand up systemd_nspawn containers 14 | 15 | ## Introduction 16 | 17 | A nifty and performant way to quickly create, stand up or manage [`systemd-nspawn`](https://www.freedesktop.org/software/systemd/man/systemd-nspawn.html) containers, `machinespawn` uses [`debootstrap`](https://wiki.debian.org/Debootstrap) and [`machinectl`](https://www.freedesktop.org/software/systemd/man/machinectl.html) and [`systemd-nspawn`](https://www.freedesktop.org/software/systemd/man/systemd-nspawn.html) to build run and remove minimal OS images. It is useful for that, and also as a stage to quickly build custom container or ISO images. 18 | 19 | This project is currently a work-in-progress 🚧 and under active development so treat as alpha software and approach with caution 🛑 However `machinespawn` is already key part of the [Ubuntu Butterfly 🦋](https://github.com/butterfly-garden) [build process](https://github.com/butterfly-garden/image-build). 20 | 21 | ## Participate 22 | 23 | We have a Discord for this project: [![Discord](https://img.shields.io/discord/712850672223125565?color=0C306A&label=WimpysWorld%20Discord&logo=Discord&logoColor=ffffff&style=flat-square)](https://discord.gg/sNmz3uw) 24 | 25 | To see it in action, or to watch it becoming, you can watch these videos where I go from an idea to a working full-featured prototype of `machinespawn`. 26 | 27 | [![machinespawn! 🐧 Dev tooling from concept to production 🧑‍💻](https://img.youtube.com/vi/-bQQ6QlXpJQ/0.jpg)](https://www.youtube.com/watch?v=-bQQ6QlXpJQ) 28 | 29 | I live stream the development of `machinespawn` and other project on [Wimpy's World Twitch channel](https://twitch.tv/WimpysWorld). 30 | 31 | ## Requirements 32 | 33 | This script relies on utilities, many of which are typically already installed on most Debian or Ubuntu systems. The following will ensure you have all you need: 34 | 35 | ```bash 36 | sudo apt-get install debootstrap binutils iproute2 systemd-container wget 37 | ``` 38 | 39 | ### Caching Proxy *(optional)* 40 | 41 | If `apt-cacher-ng` is installed on the host `machinespawn` will automatically detect its presence and use it for container bootstrapping and executing commands inside the container with `run`. Install and configure `apt-cache-ng` as follows: 42 | 43 | ```bash 44 | sudo apt-get install apt-cacher-ng 45 | ``` 46 | 47 | Create `/etc/apt-cacher-ng/zz_debconf.conf` with the following in it: 48 | 49 | ``` 50 | PassThroughPattern: .* 51 | ``` 52 | 53 | Once the above `PassThroughPattern` is set, `apt-cacher-ng` will proxy but not cache objects stored on SSL/TLS repositories. 54 | 55 | ## Supported distros 56 | 57 | Currently the following distros are supported: 58 | 59 | * Debian Releases 60 | * 8 (jessie) 61 | * 9 (stretch) 62 | * 10 (buster) 63 | * 11 (bullseye) 64 | * 12 (bookworm) 65 | 66 | * Ubuntu Releases 67 | * 16.04 (xenial) 68 | * 18.04 (bionic) 69 | * 20.04 (focal) 70 | * 22.04 (jammy) 71 | * 22.10 (kinetic) 72 | 73 | ### Architecture Support 74 | 75 | Containers can be built for the host architecture or cross-bootstrapped for the following machine architectures: 76 | 77 | * amd64 78 | * i386 79 | * armhf 80 | * arm64 81 | 82 | # Usage 83 | 84 | `machinespawn` currently needs to be run as root via `sudo` 85 | 86 | ```bash 87 | sudo machinespawn [command] 88 | ``` 89 | 90 | ## Commands 91 | 92 | ### `bootstrap` 93 | 94 | Build a machine from scratch. 95 | 96 | The first build of a machine type and architecture may be quite heavy on time and resource usage, but intelligent caching, together with detection and use of local package caching proxies, should make this as efficient as possible and significantly reduce subsequent builds or re-builds. 97 | 98 | The following bootstrap a container called 'bob' using Ubuntu 22.04 *(Jammy Jellyfish)* as the base. 99 | 100 | ```bash 101 | sudo machinespawn ubuntu-22.04 bob 102 | ``` 103 | 104 | Here's an example that would bootstrap a Debian 11 container called 'fred': 105 | 106 | ```bash 107 | sudo machinespawn debian-11 fred 108 | ``` 109 | 110 | ### `list` 111 | 112 | List the existing images (by default these will be found in `/var/lib/machines/`) 113 | 114 | ### `run` 115 | 116 | Execute commands inside the container or start an interactive shell. 117 | 118 | ```bash 119 | sudo machinespawn run bob /usr/bin/bash 120 | ``` 121 | 122 | ### `clean-cache` 123 | 124 | Remove cached content from `/var/cache/machinespawn`. This will release space taken by downloaded packages at the expense of needing to re-download if required. 125 | 126 | ### `pull-tar` 127 | 128 | ```bash 129 | machinespawn pull-tar 130 | ``` 131 | 132 | Downloads a .tar container image from the specified URL, and makes it available under the specified local machine name. The URL must be of type "http://" or "https://", and must refer to a .tar, .tar.gz, .tar.xz or .tar.bz2 archive file 133 | 134 | ```bash 135 | sudo macheinespawn pull-tar https://download.fedoraproject.org/pub/fedora/linux/releases/36/Cloud/x86_64/images/Fedora-Cloud-Base-36-1.5.x86_64.raw.xz FedoraCloudBase36 136 | ``` 137 | 138 | ### `remove` 139 | 140 | Completely remove a machine from `/var/lib/machines/` 141 | 142 | ## Reference 143 | 144 | * [debbootstrap](https://wiki.debian.org/Debootstrap) 145 | * [machinectl](https://www.freedesktop.org/software/systemd/man/machinectl.html) 146 | * [systemd-nspawn](https://www.freedesktop.org/software/systemd/man/systemd-nspawn.html) 147 | -------------------------------------------------------------------------------- /docs/pandoc-man.mk: -------------------------------------------------------------------------------- 1 | PANDOC ?= pandoc 2 | 3 | MANSECTION ?= 1 4 | 5 | MANPAGE.md = $(PANDOC) --standalone $(PANDOCFLAGS) --to man 6 | 7 | %.$(MANSECTION): %.$(MANSECTION).md 8 | $(MANPAGE.md) $< -o $@ -------------------------------------------------------------------------------- /machinespawn: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # TODO 4 | # - Migrate to mmdebstrap and possibly qemu-user 5 | # - Add support for other distros 6 | # - container_pull_tar() should accept a distro argument or a tarball URL 7 | # - Fedora, from Det_Conan_Kudo: 8 | # Formula: https://download.fedoraproject.org/pub/fedora/linux/releases/$releasever/Container/$basearch/images/ 9 | # For dev releases: https://download.fedoraproject.org/pub/fedora/linux/development/$releasever/Container/$basearch/images/ 10 | # $releasever can be a release version (35, 36, 37) or "rawhide" 11 | # $basearch can be "x86_64", "aarch64" 12 | # you're going to have to be "clever" about figuring out the filename 13 | # You can also use the releases.json code you wrote for quickget to get the container images 14 | # https://npmccallum.gitlab.io/post/cross-architecture-roots-with-dnf/ 15 | # https://wiki.mageia.org/en/Using_DNF#Setting_up_a_container_for_a_non-native_architecture 16 | # - Add support for starting/stopping 17 | # - Add support for enabling/disabling 18 | # - Add supporting for container booting 19 | # - Add support for debootstrap variants 20 | # - Check the required tools are installed 21 | # - User provisioning 22 | # - Home directory mounting 23 | # - Bind sockets, audio, display servers and authority 24 | 25 | if [ -z "${SUDO_USER}" ]; then 26 | echo "ERROR! You must use sudo to run this script: sudo ./$(basename "${0}")" 27 | exit 1 28 | fi 29 | 30 | readonly MACHINECTL_VER=$(machinectl --version | head -n1 | awk '{ print $2 }') 31 | readonly MACHINE_DIR="/var/lib/machines" 32 | readonly MACHINESPAWN_CACHE="/var/cache/machinespawn" 33 | readonly BOOTSTRAP_CACHE="${MACHINESPAWN_CACHE}/bootstrap" 34 | readonly PULLTAR_CACHE="${MACHINESPAWN_CACHE}/pull-tar" 35 | mkdir -p "${BOOTSTRAP_CACHE}" 2>/dev/null || true 36 | mkdir -p "${PULLTAR_CACHE}" 2>/dev/null || true 37 | 38 | function download_file() { 39 | local URL="${1}" 40 | local FILE="${URL##*/}" 41 | local NAME="${2}" 42 | 43 | if ! wget --quiet --show-progress --progress=bar:force:noscroll "${URL}" -O "${BOOTSTRAP_CACHE}/${FILE}"; then 44 | echo "Failed to download ${URL}. Deleting ${BOOTSTRAP_CACHE}/${FILE}..." 45 | rm "${BOOTSTRAP_CACHE}/${FILE}" 2>/dev/null 46 | exit 1 47 | fi 48 | } 49 | 50 | function container_bootstrap() { 51 | local DISTRO_FULL="${1}" 52 | local NAME="${2}" 53 | local ARCH="" 54 | local ARCHIVE="" 55 | local COMPONENTS="" 56 | local REPO="" 57 | local DISTRO_NAME=$(echo "${DISTRO_FULL}" | cut -d'-' -f1) 58 | local DISTRO_VERSION=$(echo "${DISTRO_FULL}" | cut -d'-' -f2) 59 | local DISTRO_RELEASE="" 60 | 61 | # TODO: Default to the host architecture 62 | if [ -n "${3}" ]; then 63 | ARCH="${3}" 64 | else 65 | ARCH="amd64" 66 | fi 67 | 68 | case "${ARCH}" in 69 | amd64|i386|armhf|arm64) true;; 70 | *) echo "ERROR! Unsupported architecture: ${ARCH}"; exit 1;; 71 | esac 72 | 73 | #TODO: Gate i386 on Ubuntu 18.04 and later 74 | 75 | case "${DISTRO_NAME}" in 76 | debian) ARCHIVE="deb.debian.org/debian/" 77 | COMPONENTS="main,contrib,non-free" 78 | case "${DISTRO_VERSION}" in 79 | 8) DISTRO_RELEASE="jessie";; 80 | 9) DISTRO_RELEASE="stretch";; 81 | 10) DISTRO_RELEASE="buster";; 82 | 11) DISTRO_RELEASE="bullseye";; 83 | 12) DISTRO_RELEASE="bookworm";; 84 | *) echo "ERROR! Unsupported Debian version: ${DISTRO_VERSION}"; 85 | exit 1;; 86 | esac 87 | ;; 88 | ubuntu) case "${ARCH}" in 89 | amd64|i386) ARCHIVE="archive.ubuntu.com/ubuntu/";; 90 | *) ARCHIVE="ports.ubuntu.com/";; 91 | esac 92 | COMPONENTS="main,restricted,universe,multiverse" 93 | case "${DISTRO_VERSION}" in 94 | 16.04) DISTRO_RELEASE="xenial";; 95 | 18.04) DISTRO_RELEASE="bionic";; 96 | 20.04) DISTRO_RELEASE="focal";; 97 | 22.04) DISTRO_RELEASE="jammy";; 98 | 22.10) DISTRO_RELEASE="kinetic";; 99 | *) echo "ERROR! Unsupported Ubuntu version: ${DISTRO_VERSION}"; 100 | exit 1;; 101 | esac 102 | ;; 103 | *) echo "ERROR! Unknown distro: ${DISTRO_NAME}" 104 | exit 1;; 105 | esac 106 | 107 | local R="${BOOTSTRAP_CACHE}/${DISTRO_FULL}-${ARCH}" 108 | if [ ! -d "${R}" ]; then 109 | apt-get -y install debootstrap systemd-container debian-archive-keyring ubuntu-keyring 110 | 111 | if pidof apt-cacher-ng; then 112 | REPO="http://localhost:3142/${ARCHIVE}" 113 | else 114 | REPO="http://${ARCHIVE}" 115 | fi 116 | 117 | debootstrap \ 118 | --arch="${ARCH}" \ 119 | --components="${COMPONENTS}" \ 120 | --include=nano,systemd-container \ 121 | "${DISTRO_RELEASE}" "${R}" "${REPO}" 122 | 123 | # Make sure the container has a machine-id 124 | systemd-machine-id-setup --root "${R}" --print 125 | echo "127.0.0.1 localhost ${NAME}" > "${R}/etc/hosts" 126 | 127 | # Set locale to C.UTF-8 by default. 128 | # https://git.launchpad.net/livecd-rootfs/tree/live-build/auto/build#n159 129 | echo "LANG=C.UTF-8" > "${R}/etc/default/locale" 130 | 131 | case "${DISTRO_NAME}" in 132 | debian) echo "deb http://${ARCHIVE} ${DISTRO_RELEASE} ${COMPONENTS//,/ }" > "${R}/etc/apt/sources.list";; 133 | ubuntu) echo "deb http://${ARCHIVE} ${DISTRO_RELEASE} ${COMPONENTS//,/ } 134 | deb http://${ARCHIVE} ${DISTRO_RELEASE}-updates ${COMPONENTS//,/ } 135 | deb http://${ARCHIVE} ${DISTRO_RELEASE}-backports ${COMPONENTS//,/ } 136 | deb http://${ARCHIVE} ${DISTRO_RELEASE}-security ${COMPONENTS//,/ }" > "${R}/etc/apt/sources.list";; 137 | esac 138 | else 139 | echo "WARNING! ${R} already exists!" 140 | fi 141 | machinectl import-fs "${R}" "${NAME}" 142 | } 143 | 144 | function container_pull_tar() { 145 | local URL="${1}" 146 | local NAME="${2}" 147 | 148 | # Work around systemd bug 149 | # - https://bugs.launchpad.net/ubuntu/+source/systemd/+bug/1977630 150 | case "${MACHINECTL_VER}" in 151 | 249) download_file "${URL}" 152 | machinectl import-tar "${PULLTAR_CACHE}/${URL##*/}" "${NAME}";; 153 | *) machinectl pull-tar "${URL}" "${NAME}" --verify=no;; 154 | esac 155 | } 156 | 157 | function container_remove() { 158 | local NAME="${1}" 159 | machinectl remove "${NAME}" 160 | } 161 | 162 | function container_list() { 163 | machinectl list-images 164 | } 165 | 166 | function container_clean_bootstrap() { 167 | local NAME="${1}" 168 | if [ -n "${NAME}" ] && [ -d "${BOOTSTRAP_CACHE}/${NAME}" ]; then 169 | rm -rf "${BOOTSTRAP_CACHE}/${NAME}" 170 | fi 171 | } 172 | 173 | function container_run() { 174 | local APT_CACHE_IP="" 175 | local CMD="/bin/bash" 176 | local R="${MACHINE_DIR}/${1}" 177 | 178 | if [ ! -d "${R}" ]; then 179 | echo "ERROR! Container ${R} does not exist!" 180 | exit 1 181 | fi 182 | 183 | # Strip the container name from arguments 184 | if [ -n "${2}" ]; then 185 | shift 186 | fi 187 | 188 | APT_CACHE_IP=$(ip route get 1.1.1.1 | head -n 1 | cut -d' ' -f 7) 189 | 190 | if pidof -q apt-cacher-ng && [ -d "${R}/etc/apt/apt.conf.d" ]; then 191 | echo "Acquire::http { Proxy \"http://${APT_CACHE_IP}:3142\"; }" > "${R}/etc/apt/apt.conf.d/90cache" 192 | fi 193 | 194 | echo "nameserver 1.1.1.1" > "/tmp/resolv.conf" 195 | systemd-nspawn \ 196 | --bind-ro="/tmp/resolv.conf":/etc/resolv.conf \ 197 | --chdir=/root \ 198 | --directory "${R}" \ 199 | --hostname="${NAME}" \ 200 | --machine="${NAME}" \ 201 | --resolv-conf=off \ 202 | "${@}" 203 | 204 | if [ -e "${R}/etc/apt/apt.conf.d/90cache" ]; then 205 | rm -f "${R}/etc/apt/apt.conf.d/90cache" 206 | fi 207 | } 208 | 209 | function usage() { 210 | echo "Usage: $(basename "${0}") [command]" 211 | exit 212 | } 213 | 214 | case "${1}" in 215 | bootstrap) 216 | if [ -z "${2}" ] || [ -z "${3}" ]; then 217 | echo "ERROR! You must specify a distro-release and container name!" 218 | exit 1 219 | else 220 | container_bootstrap "${2}" "${3}" "${4}" 221 | fi;; 222 | clean-bootstrap) 223 | if [ -z "${2}" ]; then 224 | echo "ERROR! You must specify a bootstrap cache!" 225 | exit 1 226 | else 227 | container_clean_bootstrap "${2}" 228 | fi;; 229 | list|list-images) 230 | container_list;; 231 | pull-tar) 232 | if [ -z "${2}" ] || [ -z "${3}" ]; then 233 | echo "ERROR! You must specify a distro tarball URL and container name!" 234 | exit 1 235 | else 236 | container_pull_tar "${2}" "${3}" 237 | fi;; 238 | remove) 239 | if [ -z "${2}" ]; then 240 | echo "ERROR! You must specify a container name!" 241 | exit 1 242 | else 243 | container_remove "${2}" 244 | fi;; 245 | run) 246 | if [ -z "${2}" ]; then 247 | echo "ERROR! You must specify a container name!" 248 | exit 1 249 | else 250 | # Strip the script name from arguments 251 | shift 252 | # Get the container name from arguments 253 | NAME="${1}" 254 | 255 | # Strip the container name from arguments 256 | shift 257 | container_run "${NAME}" "${@}" 258 | fi;; 259 | *) echo "ERROR! You must specify an action: bootstrap, clean-cache, pull-tar, remove, run" 260 | usage 261 | exit 1;; 262 | esac 263 | --------------------------------------------------------------------------------