├── .editorconfig ├── LICENSE ├── README.md ├── bin ├── config ├── runner └── test ├── builders ├── almalinux │ ├── config.sh │ └── setup.sh ├── devuan │ ├── config.sh │ └── setup.sh ├── fedora │ ├── config.sh │ └── setup.sh ├── nixos │ ├── config.sh │ └── setup.sh ├── opensuse-leap │ ├── config.sh │ └── setup.sh ├── opensuse-tumbleweed │ ├── config.sh │ └── setup.sh └── ubuntu │ ├── config.sh │ └── setup.sh ├── images ├── almalinux-8 │ ├── build.sh │ └── config.sh ├── almalinux-9 │ ├── build.sh │ └── config.sh ├── alpine-3.14 ├── alpine-3.15 ├── alpine-3.16 ├── alpine-3.17 ├── alpine │ ├── abstract │ ├── build.sh │ ├── cgroups-mount.initd │ ├── config.sh │ └── fetch-keys.sh ├── arch │ ├── build.sh │ └── config.sh ├── centos-7 │ ├── build.sh │ └── config.sh ├── centos-8-stream │ ├── build.sh │ └── config.sh ├── centos-8 │ ├── build.sh │ └── config.sh ├── centos-9-stream │ ├── build.sh │ └── config.sh ├── debian-10 │ ├── build.sh │ └── config.sh ├── debian-11 │ ├── build.sh │ └── config.sh ├── debian-9 │ ├── build.sh │ └── config.sh ├── debian-testing │ ├── build.sh │ └── config.sh ├── debian-unstable │ ├── build.sh │ └── config.sh ├── devuan-3.0 │ ├── build.sh │ ├── cgroups-mount.initscript │ └── config.sh ├── devuan-4 │ ├── build.sh │ ├── cgroups-mount.initscript │ └── config.sh ├── fedora-35 │ ├── build.sh │ └── config.sh ├── fedora-36 │ ├── build.sh │ └── config.sh ├── fedora-37 │ ├── build.sh │ └── config.sh ├── fedora-38 │ ├── build.sh │ └── config.sh ├── gentoo-musl │ ├── build.sh │ └── config.sh ├── gentoo-openrc │ ├── build.sh │ └── config.sh ├── gentoo-systemd │ ├── build.sh │ └── config.sh ├── nixos-22.11 │ ├── build.sh │ └── config.sh ├── nixos-unstable │ ├── build.sh │ └── config.sh ├── opensuse-leap-15.2 │ ├── build.sh │ └── config.sh ├── opensuse-leap-15.3 │ ├── build.sh │ └── config.sh ├── opensuse-leap-15.4 │ ├── build.sh │ └── config.sh ├── opensuse-tumbleweed │ ├── build.sh │ └── config.sh ├── rocky-8 │ ├── build.sh │ └── config.sh ├── rocky-9 │ ├── build.sh │ └── config.sh ├── slackware-15.0 │ ├── build.sh │ ├── cgroups.sh │ └── config.sh ├── slackware-current │ ├── build.sh │ ├── cgroups.sh │ └── config.sh ├── ubuntu-16.04 │ ├── build.sh │ └── config.sh ├── ubuntu-18.04 │ ├── build.sh │ └── config.sh ├── ubuntu-20.04 │ ├── build.sh │ └── config.sh ├── ubuntu-22.04 │ ├── build.sh │ └── config.sh ├── void-glibc │ ├── build.sh │ └── config.sh ├── void-musl │ ├── build.sh │ └── config.sh └── void │ ├── abstract │ └── cgroups.sh ├── include ├── alpine.sh ├── common.sh ├── debian.sh ├── devuan.sh ├── gentoo.sh ├── nixos.sh ├── opensuse.sh ├── redhat-family.sh └── void.sh ├── shell-test.nix └── tests ├── dns_resolver.sh ├── hostname.sh ├── packages.sh ├── passwd_started.sh ├── passwd_stopped.sh ├── ssh_key.sh ├── ssh_password.sh ├── start.sh ├── stop.sh ├── veth_bridge.sh └── veth_routed.sh /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | 8 | [*.sh] 9 | indent_size = 4 10 | indent_style = tab 11 | trim_trailing_whitespace = true 12 | 13 | [bin/*] 14 | indent_size = 4 15 | indent_style = tab 16 | trim_trailing_whitespace = true 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 vpsFree.cz o.s. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | vpsAdminOS Image Build Scripts 2 | ============================== 3 | 4 | ## Deprecation notice 5 | 6 | This repository has been merged into vpsAdminOS: 7 | 8 | https://github.com/vpsfreecz/vpsadminos 9 | 10 | Further development will take place there. 11 | 12 | ## About 13 | 14 | This is a collection of scripts used to build and test container images, which 15 | are then used by [vpsAdminOS](http://vpsadminos.org) when creating new containers. 16 | Container image is a tarball with configuration and filesystems, see the 17 | [specification](https://vpsadminos.org/specifications/container-image/). More 18 | information about container images can be found in the 19 | [documentation](https://vpsadminos.org/container-images/usage/). 20 | 21 | ## Building images 22 | Images can be built within vpsAdminOS using `osctl-image`. `osctl-image` needs 23 | the build scripts in its current working directory. 24 | 25 | ```shell 26 | git clone git@github.com:vpsfreecz/vpsadminos-image-build-scripts.git 27 | cd vpsadminos-image-build-scripts 28 | ``` 29 | 30 | Usage: 31 | 32 | ```shell 33 | osctl-image --help 34 | NAME 35 | osctl-image - Build, test and deploy vpsAdminOS images 36 | 37 | SYNOPSIS 38 | osctl-image [global options] command [command options] [arguments...] 39 | 40 | VERSION 41 | 19.03.0 42 | 43 | GLOBAL OPTIONS 44 | --help - Show this message 45 | --version - Display the program version 46 | 47 | COMMANDS 48 | build - Build image 49 | ct - Manage build and test containers 50 | deploy - Build image, test it and deploy to repository 51 | help - Shows a list of commands or help for one command 52 | instantiate - Build the image and use it in a container 53 | ls - List available images 54 | test - Test image 55 | ``` 56 | 57 | To get a list of available images, use: 58 | 59 | ```shell 60 | osctl-image ls 61 | ``` 62 | 63 | `osctl-image` requires a dedicated ZFS dataset which is used for building 64 | images. The dataset should not have any data or subdatasets that you care about. 65 | 66 | ```shell 67 | zfs create tank/image-builds 68 | ``` 69 | 70 | To build an image, use command `osclt-image build`, e.g.: 71 | 72 | ```shell 73 | osctl-image build --build-dataset tank/image-builds alpine-3.9 74 | ``` 75 | 76 | Tests can be run as: 77 | 78 | ```shell 79 | osctl-image test --build-dataset tank/image-builds alpine-3.9 80 | ``` 81 | 82 | Images can be also tested manually in container. Use command 83 | `osctl-image instantiate` to create one: 84 | 85 | ```shell 86 | osctl-image instantiate --build-dataset tank/image-builds alpine-3.9 87 | ``` 88 | 89 | Managed containers can be listed using command `osctl-image ct ls` and cleaned 90 | up using `osctl-image ct del`. See 91 | [man osctl-image(8)](https://man.vpsadminos.org/osctl-image/man8/osctl-image.8.html) 92 | for more information. 93 | 94 | ## Contributing build scripts 95 | Target images are represented by directories in [images/](images/). Every 96 | image directory has to contain two files: `config.sh` and `build.sh`. 97 | `config.sh` is used to set variables such as distribution name, version and so 98 | on, see below. This information is used by `osctl-image`. `build.sh` 99 | is called to actually build the image. 100 | 101 | Shared code can be placed into [include/](include/), follow the existing naming 102 | scheme. 103 | 104 | ### How does it work 105 | The image build script needs to prepare the distribution's root filesystem 106 | in directory stored in variable `$INSTALL`. The script can download arbitrary 107 | assets into directory `$DOWNLOAD`. When the script finishes, the `$INSTALL` 108 | directory should contain the root filesystem, i.e. directories like `bin`, `usr`, 109 | `var`, `home` and so on. 110 | 111 | The build script can generate configuration script, that will be executed 112 | as chrooted within the `$INSTALL` directory. Function `configure-append` is used 113 | to append chunks of the configuration script and `run-configure` will chroot 114 | to the `$INSTALL` directory and run it. This is where you can use the 115 | distribution's package manager and other programs. 116 | 117 | For example, to create a Debian image, you would use `debootstrap` to download 118 | the base root file system, then use the configuration script to install additional 119 | packages and configure the services. 120 | 121 | ### Image name and variables 122 | The image has to define the following variables in `config.sh`: 123 | 124 | - `BUILDER` - name of a builder that the image has to be built in, see below 125 | 126 | Additional variables are optional: 127 | 128 | - `DISTNAME`, e.g. `debian`, `ubuntu` 129 | - `RELVER`, e.g. `9` for Debian or `16.04` for Ubuntu 130 | - `ARCH` (defaults to `x86_64`) 131 | - `VENDOR` (defaults to `vpsadminos`) 132 | - `VARIANT` (defaults to `minimal`) 133 | 134 | If not set, `osctl-image` tries to extract the values from the image name, 135 | which should be in the following form: 136 | 137 | [-RELVER[-ARCH[-VENDOR[-VARIANT]]]] 138 | 139 | ### Builders 140 | Images are built in builders, which are vpsAdminOS containers. Builders 141 | are defined in directory [builders/](builders/) by two files: `config.sh` 142 | and `setup.sh`. 143 | 144 | `config.sh` is similar to image configs, it specifies what distribution 145 | and version should the builder be created from. Builders are simply containers 146 | created from pre-existing images available in vpsAdminOS repository 147 | at , or whatever repository you have 148 | configured on your system. 149 | 150 | `setup.sh` is run within the builder container after it is created. This script 151 | should installed whatever packages are needed to build images that use this 152 | builder. 153 | -------------------------------------------------------------------------------- /bin/config: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # This is internal builder, do not use this directly! 3 | # Use osctl-images from vpsAdminOS to build the images. 4 | 5 | BASEDIR=$(realpath `dirname ${BASH_SOURCE[0]}`/..) 6 | 7 | function usage { 8 | echo "Usage:" 9 | echo " $0 builder|image|test [command arguments...]" 10 | } 11 | 12 | function builder_usage { 13 | echo "Usage:" 14 | echo " $0 builder list" 15 | echo " $0 builder show " 16 | } 17 | 18 | function do_builder { 19 | if [ $# -lt 1 ] ; then 20 | builder_usage 21 | exit 1 22 | fi 23 | 24 | local action="$1" 25 | 26 | case "$action" in 27 | list) 28 | ls -1 "$BASEDIR/builders" 29 | ;; 30 | show) 31 | local name="$2" 32 | local dir="$BASEDIR/builders/$name" 33 | 34 | if [ "$name" == "" ] ; then 35 | builder_usage 36 | exit 1 37 | elif [ ! -d "$dir" ] ; then 38 | echo "Builder '$name' not found" 39 | builder_usage 40 | exit 1 41 | fi 42 | 43 | DISTNAME= 44 | RELVER= 45 | ARCH= 46 | VENDOR= 47 | VARIANT= 48 | . "$dir/config.sh" 49 | echo "DISTNAME=$DISTNAME" 50 | echo "RELVER=$RELVER" 51 | echo "ARCH=$ARCH" 52 | echo "VENDOR=$VENDOR" 53 | echo "VARIANT=$VARIANT" 54 | ;; 55 | *) 56 | builder_usage 57 | exit 1 58 | ;; 59 | esac 60 | } 61 | 62 | function image_usage { 63 | echo "Usage:" 64 | echo " $0 image list" 65 | echo " $0 image show " 66 | } 67 | 68 | function do_image { 69 | if [ $# -lt 1 ] ; then 70 | image_usage 71 | exit 1 72 | fi 73 | 74 | local action="$1" 75 | 76 | case "$action" in 77 | list) 78 | find "$BASEDIR/images/" ! -path "$BASEDIR/images/" -type d -or -type l \ 79 | | while read dir 80 | do 81 | [ ! -h "$dir" ] && [ -f "$dir"/abstract ] && continue 82 | basename "$dir" 83 | done 84 | ;; 85 | show) 86 | local name="$2" 87 | local dir="$BASEDIR/images/$name" 88 | 89 | if [ "$name" == "" ] ; then 90 | image_usage 91 | exit 1 92 | elif [ ! -d "$dir" ] ; then 93 | echo "Image '$name' not found" 94 | image_usage 95 | exit 1 96 | fi 97 | 98 | BUILDER= 99 | DISTNAME= 100 | RELVER= 101 | ARCH= 102 | VENDOR= 103 | VARIANT= 104 | IFS=- read DISTNAME RELVER ARCH VENDOR VARIANT <<< "$name" 105 | [ "$ARCH" == "" ] && ARCH=x86_64 106 | . "$dir/config.sh" 107 | echo "BUILDER=$BUILDER" 108 | echo "DISTNAME=$DISTNAME" 109 | echo "RELVER=$RELVER" 110 | echo "ARCH=$ARCH" 111 | echo "VENDOR=$VENDOR" 112 | echo "VARIANT=$VARIANT" 113 | ;; 114 | *) 115 | image_usage 116 | exit 1 117 | ;; 118 | esac 119 | } 120 | 121 | function test_usage { 122 | echo "Usage:" 123 | echo " $0 test list" 124 | } 125 | 126 | function do_test { 127 | if [ $# -lt 1 ] ; then 128 | test_usage 129 | exit 1 130 | fi 131 | 132 | local action="$1" 133 | 134 | case "$action" in 135 | list) 136 | find "$BASEDIR/tests" -name "*.sh" | while read file ; do 137 | basename "$file" | sed 's/\.sh$//g' 138 | done 139 | ;; 140 | *) 141 | test_usage 142 | exit 1 143 | ;; 144 | esac 145 | } 146 | 147 | function main { 148 | if [ $# -lt 1 ] ; then 149 | usage 150 | exit 1 151 | fi 152 | 153 | local command="$1" 154 | shift 1 155 | 156 | case "$command" in 157 | builder) 158 | do_builder $@ ;; 159 | image) 160 | do_image $@ ;; 161 | test) 162 | do_test $@ ;; 163 | *) 164 | usage 165 | exit 1 166 | ;; 167 | esac 168 | } 169 | 170 | main $@ 171 | -------------------------------------------------------------------------------- /bin/runner: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # This is internal builder, do not use this directly! 3 | # Use osctl-image from vpsAdminOS to build the images. 4 | 5 | set -x 6 | 7 | BASEDIR=$(realpath `dirname ${BASH_SOURCE[0]}`/..) 8 | 9 | function usage { 10 | echo "Usage:" 11 | echo " $0 builder|image [command arguments...]" 12 | } 13 | 14 | function builder_usage { 15 | echo "Usage:" 16 | echo " $0 builder setup " 17 | } 18 | 19 | function do_builder { 20 | if [ $# -lt 1 ] ; then 21 | builder_usage 22 | exit 1 23 | fi 24 | 25 | local action="$1" 26 | 27 | case "$action" in 28 | setup) 29 | local name="$2" 30 | local dir="$BASEDIR/builders/$name" 31 | 32 | if [ "$name" == "" ] ; then 33 | builder_usage 34 | exit 1 35 | elif [ ! -d "$dir" ] ; then 36 | echo "Builder '$name' not found" 37 | builder_usage 38 | exit 1 39 | fi 40 | 41 | . "$dir/setup.sh" 42 | ;; 43 | *) 44 | builder_usage 45 | exit 1 46 | ;; 47 | esac 48 | } 49 | 50 | function image_usage { 51 | echo "Usage:" 52 | echo " $0 image build " 53 | } 54 | 55 | function do_image { 56 | if [ $# -lt 1 ] ; then 57 | image_usage 58 | exit 1 59 | fi 60 | 61 | local action="$1" 62 | 63 | case "$action" in 64 | build) 65 | shift 1 66 | build_image $@ 67 | ;; 68 | *) 69 | image_usage 70 | exit 1 71 | ;; 72 | esac 73 | } 74 | 75 | function build_image { 76 | if [ $# != 4 ] ; then 77 | image_usage 78 | exit 1 79 | fi 80 | 81 | BUILD_ID="$1" 82 | DOWNLOAD="$2" 83 | INSTALL="$3" 84 | IMAGE="$4" 85 | CONFIGFILE="$INSTALL/container.yml" 86 | 87 | INCLUDE="$BASEDIR/include" 88 | IMAGEDIR="$BASEDIR/images/$IMAGE" 89 | CONFIGURE="$INSTALL/tmp/configure.sh" 90 | 91 | DISTNAME= 92 | RELVER= 93 | ARCH= 94 | VENDOR= 95 | VARIANT= 96 | 97 | IFS=- read DISTNAME RELVER ARCH VENDOR VARIANT <<< "$IMAGE" 98 | 99 | [ "$ARCH" == "" ] && ARCH=x86_64 100 | 101 | cd "$DOWNLOAD" 102 | 103 | . "$BASEDIR/include/common.sh" 104 | set-initcmd /sbin/init 105 | . "$BASEDIR/images/$IMAGE/build.sh" 106 | 107 | write_image_config 108 | } 109 | 110 | function write_image_config { 111 | cat <> "$CONFIGFILE" 112 | init_cmd: 113 | $(echo -e $INITCMD) 114 | EOF 115 | } 116 | 117 | function main { 118 | if [ $# -lt 1 ] ; then 119 | usage 120 | exit 1 121 | fi 122 | 123 | local command="$1" 124 | shift 1 125 | 126 | case "$command" in 127 | builder) 128 | do_builder $@ ;; 129 | image) 130 | do_image $@ ;; 131 | *) 132 | usage 133 | exit 1 134 | ;; 135 | esac 136 | } 137 | 138 | main $@ 139 | -------------------------------------------------------------------------------- /bin/test: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # This is internal builder, do not use this directly! 3 | # Use osctl-image from vpsAdminOS to build the images. 4 | 5 | BASEDIR=$(realpath `dirname ${BASH_SOURCE[0]}`/..) 6 | 7 | function usage { 8 | echo "Usage:" 9 | echo " $0 image [command arguments...]" 10 | } 11 | 12 | function image_usage { 13 | echo "Usage:" 14 | echo " $0 image run " 15 | } 16 | 17 | function do_image { 18 | if [ $# -lt 1 ] ; then 19 | image_usage 20 | exit 1 21 | fi 22 | 23 | local action="$1" 24 | 25 | case "$action" in 26 | run) 27 | shift 1 28 | test_image $@ 29 | ;; 30 | *) 31 | image_usage 32 | exit 1 33 | ;; 34 | esac 35 | } 36 | 37 | function test_image { 38 | if [ $# != 3 ] ; then 39 | image_usage 40 | exit 1 41 | fi 42 | 43 | IMAGE="$1" 44 | TEST="$2" 45 | CTID="$3" 46 | 47 | INCLUDE="$BASEDIR/include" 48 | 49 | . "$BASEDIR/include/common.sh" 50 | 51 | BUILDER= 52 | DISTNAME= 53 | RELVER= 54 | ARCH= 55 | VENDOR= 56 | VARIANT= 57 | IFS=- read DISTNAME RELVER ARCH VENDOR VARIANT <<< "$IMAGE" 58 | [ "$ARCH" == "" ] && ARCH=x86_64 59 | . "$BASEDIR/images/$IMAGE/config.sh" 60 | 61 | . "$BASEDIR/tests/$TEST.sh" 62 | } 63 | 64 | function main { 65 | if [ $# -lt 1 ] ; then 66 | usage 67 | exit 1 68 | fi 69 | 70 | local command="$1" 71 | shift 1 72 | 73 | case "$command" in 74 | image) 75 | do_image $@ ;; 76 | *) 77 | usage 78 | exit 1 79 | ;; 80 | esac 81 | } 82 | 83 | main $@ 84 | -------------------------------------------------------------------------------- /builders/almalinux/config.sh: -------------------------------------------------------------------------------- 1 | DISTNAME=almalinux 2 | RELVER=8 3 | -------------------------------------------------------------------------------- /builders/almalinux/setup.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | dnf -y update 3 | dnf -y install curl openssl patch wget 4 | -------------------------------------------------------------------------------- /builders/devuan/config.sh: -------------------------------------------------------------------------------- 1 | DISTNAME=devuan 2 | RELVER=4 3 | -------------------------------------------------------------------------------- /builders/devuan/setup.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | apt-get update 3 | apt-get -y install curl debootstrap 4 | -------------------------------------------------------------------------------- /builders/fedora/config.sh: -------------------------------------------------------------------------------- 1 | DISTNAME=fedora 2 | RELVER=33 3 | -------------------------------------------------------------------------------- /builders/fedora/setup.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | dnf -y update 3 | dnf -y install curl debootstrap git openssl patch wget 4 | -------------------------------------------------------------------------------- /builders/nixos/config.sh: -------------------------------------------------------------------------------- 1 | DISTNAME=nixos 2 | RELVER=unstable 3 | -------------------------------------------------------------------------------- /builders/nixos/setup.sh: -------------------------------------------------------------------------------- 1 | cat < /etc/nixos/configuration.nix 2 | { config, pkgs, ... }: 3 | { 4 | imports = [ 5 | 6 | ./vpsadminos.nix 7 | ]; 8 | 9 | environment.systemPackages = with pkgs; [ 10 | git 11 | gnumake 12 | ]; 13 | 14 | time.timeZone = "Europe/Amsterdam"; 15 | system.stateVersion = "21.05"; 16 | } 17 | EOF 18 | 19 | # Set NIX_PATH and other stuff 20 | . /etc/profile 21 | 22 | # Configure the system 23 | nixos-rebuild switch 24 | -------------------------------------------------------------------------------- /builders/opensuse-leap/config.sh: -------------------------------------------------------------------------------- 1 | DISTNAME=opensuse 2 | RELVER=leap-15.2 3 | -------------------------------------------------------------------------------- /builders/opensuse-leap/setup.sh: -------------------------------------------------------------------------------- 1 | : 2 | -------------------------------------------------------------------------------- /builders/opensuse-tumbleweed/config.sh: -------------------------------------------------------------------------------- 1 | DISTNAME=opensuse 2 | RELVER=latest-tumbleweed 3 | -------------------------------------------------------------------------------- /builders/opensuse-tumbleweed/setup.sh: -------------------------------------------------------------------------------- 1 | : 2 | -------------------------------------------------------------------------------- /builders/ubuntu/config.sh: -------------------------------------------------------------------------------- 1 | DISTNAME=ubuntu 2 | RELVER=20.04 3 | -------------------------------------------------------------------------------- /builders/ubuntu/setup.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | apt-get -y update 3 | apt-get -y install curl debootstrap patch wget 4 | -------------------------------------------------------------------------------- /images/almalinux-8/build.sh: -------------------------------------------------------------------------------- 1 | . "$IMAGEDIR/config.sh" 2 | POINTVER=8.7 3 | RELEASE=https://repo.almalinux.org/almalinux/${POINTVER}/BaseOS/x86_64/os/Packages/almalinux-release-${POINTVER}-2.el8.x86_64.rpm 4 | BASEURL=https://repo.almalinux.org/almalinux/${POINTVER}/BaseOS/x86_64/os/ 5 | 6 | # CentOS 8 does not seem to have an updates repo, so this variable is used to 7 | # add AppStream repository just for the installation process. 8 | UPDATES=https://repo.almalinux.org/almalinux/${POINTVER}/AppStream/x86_64/os/ 9 | 10 | GROUPNAME='core' 11 | EXTRAPKGS='vim man' 12 | 13 | . $INCLUDE/redhat-family.sh 14 | 15 | bootstrap 16 | configure-common 17 | configure-redhat-common 18 | configure-rhel-8 19 | run-configure 20 | -------------------------------------------------------------------------------- /images/almalinux-8/config.sh: -------------------------------------------------------------------------------- 1 | BUILDER=almalinux 2 | -------------------------------------------------------------------------------- /images/almalinux-9/build.sh: -------------------------------------------------------------------------------- 1 | . "$IMAGEDIR/config.sh" 2 | POINTVER=9.1 3 | RELEASE=https://repo.almalinux.org/almalinux/${POINTVER}/BaseOS/x86_64/os/Packages/almalinux-release-${POINTVER}-1.9.el9.x86_64.rpm 4 | BASEURL=https://repo.almalinux.org/almalinux/${POINTVER}/BaseOS/x86_64/os/ 5 | 6 | # CentOS 8 does not seem to have an updates repo, so this variable is used to 7 | # add AppStream repository just for the installation process. 8 | UPDATES=https://repo.almalinux.org/almalinux/${POINTVER}/AppStream/x86_64/os/ 9 | 10 | GROUPNAME='core' 11 | EXTRAPKGS='almalinux-repos vim man' 12 | 13 | . $INCLUDE/redhat-family.sh 14 | 15 | bootstrap 16 | configure-common 17 | configure-redhat-common 18 | configure-rhel-9 19 | run-configure 20 | set-initcmd "/sbin/init" "systemd.unified_cgroup_hierarchy=0" 21 | -------------------------------------------------------------------------------- /images/almalinux-9/config.sh: -------------------------------------------------------------------------------- 1 | BUILDER=fedora 2 | -------------------------------------------------------------------------------- /images/alpine-3.14: -------------------------------------------------------------------------------- 1 | alpine -------------------------------------------------------------------------------- /images/alpine-3.15: -------------------------------------------------------------------------------- 1 | alpine -------------------------------------------------------------------------------- /images/alpine-3.16: -------------------------------------------------------------------------------- 1 | alpine -------------------------------------------------------------------------------- /images/alpine-3.17: -------------------------------------------------------------------------------- 1 | alpine -------------------------------------------------------------------------------- /images/alpine/abstract: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vpsfreecz/vpsadminos-image-build-scripts/dcc1b1553c8b96e8f7033062e1e3402ea7a69e8d/images/alpine/abstract -------------------------------------------------------------------------------- /images/alpine/build.sh: -------------------------------------------------------------------------------- 1 | . "$IMAGEDIR"/config.sh 2 | . "$INCLUDE"/alpine.sh 3 | -------------------------------------------------------------------------------- /images/alpine/cgroups-mount.initd: -------------------------------------------------------------------------------- 1 | #!/sbin/openrc-run 2 | 3 | description="Mount cgroups inside LXC container." 4 | 5 | hybrid_cgroups="blkio 6 | cpu,cpuacct 7 | cpuset 8 | devices 9 | freezer 10 | hugetlb 11 | memory 12 | net_cls,net_prio 13 | perf_event 14 | pids 15 | rdma" 16 | hybrid_named_cgroups="systemd" 17 | mount_opts="nodev,noexec,nosuid" 18 | 19 | depend() { 20 | keyword lxc 21 | need sysfs 22 | } 23 | 24 | cgroup_mode() { 25 | if grep -x "^[[:digit:]]:cpuset:/" /proc/1/cgroup > /dev/null ; then 26 | echo "hybrid" 27 | else 28 | echo "unified" 29 | fi 30 | } 31 | 32 | setup_hybrid() { 33 | ebegin "Mounting cgroups in a hybrid layout" 34 | 35 | local retval=0 36 | local name 37 | 38 | if ! mount -t tmpfs -o "$mount_opts" tmpfs /sys/fs/cgroup ; then 39 | echo "Unable to mount /sys/fs/cgroup" 40 | eend 1 41 | return 1 42 | fi 43 | 44 | for name in $hybrid_cgroups; do 45 | mountinfo -q "/sys/fs/cgroup/$name" && continue 46 | 47 | mkdir -p "/sys/fs/cgroup/$name" 48 | mount -n -t cgroup -o "$mount_opts,$name" \ 49 | cgroup "/sys/fs/cgroup/$name" || retval=1 50 | done 51 | 52 | for name in $hybrid_named_cgroups; do 53 | mountinfo -q "/sys/fs/cgroup/$name" && continue 54 | 55 | mkdir -p "/sys/fs/cgroup/$name" 56 | mount -n -t cgroup -o "none,$mount_opts,name=$name" \ 57 | cgroup "/sys/fs/cgroup/$name" || retval=1 58 | done 59 | 60 | mkdir -p /sys/fs/cgroup/unified 61 | mount -n -t cgroup2 -o "$mount_opts" cgroup2 /sys/fs/cgroup/unified || retval=1 62 | 63 | if ! mountinfo -q /sys/fs/cgroup/openrc ; then 64 | rm -rf /sys/fs/cgroup/openrc 65 | ln -sf /sys/fs/cgroup/systemd /sys/fs/cgroup/openrc 66 | fi 67 | 68 | mount -o remount,ro tmpfs /sys/fs/cgroup 69 | 70 | eend $retval 71 | } 72 | 73 | setup_unified() { 74 | ebegin "Mounting cgroups in a unified layout" 75 | 76 | local retval=0 77 | 78 | mkdir /sys/fs/cgroup/init.scope 79 | echo 1 > /sys/fs/cgroup/init.scope/cgroup.procs 80 | 81 | eend $retval 82 | } 83 | 84 | start() { 85 | [ -e /proc/cgroups ] || return 0 86 | 87 | local mode=$(cgroup_mode) 88 | 89 | case "$mode" in 90 | hybrid) setup_hybrid ;; 91 | unified) setup_unified ;; 92 | *) echo "Unknown cgroup mode '$mode'" ;; 93 | esac 94 | } 95 | -------------------------------------------------------------------------------- /images/alpine/config.sh: -------------------------------------------------------------------------------- 1 | BUILDER=fedora 2 | -------------------------------------------------------------------------------- /images/alpine/fetch-keys.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Used to update keys in $APK_KEYS_SHA256 3 | git clone --depth 1 git://git.alpinelinux.org/aports 4 | pushd aports/main/alpine-keys 5 | for key in $(ls *.pub) ; do 6 | echo -e "\t$(sha256sum $key)" 7 | done 8 | popd 9 | -------------------------------------------------------------------------------- /images/arch/build.sh: -------------------------------------------------------------------------------- 1 | . "$IMAGEDIR"/config.sh 2 | BASEURL=https://mirror.vpsfree.cz/archlinux/iso/latest 3 | 4 | require_cmd curl 5 | 6 | bootstrap-arch() { 7 | # Find out the bootstrap archive's name from checksum list 8 | rx='archlinux-bootstrap-\d+\.\d+\.\d+-x86_64\.tar\.gz' 9 | curl "$BASEURL/sha256sums.txt" | grep -P "$rx" > "$DOWNLOAD/sha256sums.txt" 10 | bfile=$(grep -oP "$rx" "$DOWNLOAD/sha256sums.txt") 11 | 12 | # Download the bootstrap archive and verify checksum 13 | curl -o "$DOWNLOAD/$bfile" "$BASEURL/$bfile" 14 | if ! (cd "$DOWNLOAD" ; sha256sum -c sha256sums.txt) ; then 15 | echo "Bootstrap checksum wrong! Quitting." 16 | exit 1 17 | fi 18 | 19 | # Extract 20 | tar -xzf "$DOWNLOAD/$bfile" --preserve-permissions --preserve-order --numeric-owner \ 21 | -C "$INSTALL" 22 | 23 | # Bootstrap the base system to $INSTALL/root.x86_64/mnt 24 | local BOOTSTRAP="$INSTALL/root.x86_64" 25 | local SETUP="/install.sh" 26 | 27 | sed -i 's/CheckSpace/#CheckSpace/' "$BOOTSTRAP/etc/pacman.conf" 28 | sed -ri 's/^#(.*vpsfree\.cz.*)$/\1/' "$BOOTSTRAP/etc/pacman.d/mirrorlist" 29 | echo nameserver 8.8.8.8 > "$BOOTSTRAP/etc/resolv.conf" 30 | 31 | # pacstrap tries to mount /dev as devtmpfs, which is not possible in 32 | # an unprivileged container. We have to mount it as tmpfs and mknod 33 | # devices and create directories before mounting devpts and shm. 34 | cat <<'EOF' | patch "$BOOTSTRAP/bin/pacstrap" 35 | 101,103c101,109 36 | < chroot_add_mount udev "$1/dev" -t devtmpfs -o mode=0755,nosuid && 37 | < chroot_add_mount devpts "$1/dev/pts" -t devpts -o mode=0620,gid=5,nosuid,noexec && 38 | < chroot_add_mount shm "$1/dev/shm" -t tmpfs -o mode=1777,nosuid,nodev && 39 | --- 40 | > chroot_add_mount udev "$1/dev" -t tmpfs -o mode=0755,nosuid && 41 | > mknod "$1/dev/null" c 1 3 && 42 | > mknod "$1/dev/zero" c 1 5 && 43 | > mknod "$1/dev/full" c 1 7 && 44 | > mknod "$1/dev/random" c 1 8 && 45 | > mknod "$1/dev/urandom" c 1 9 && 46 | > mknod "$1/dev/tty" c 5 0 && 47 | > mkdir "$1/dev/pts" && chroot_add_mount devpts "$1/dev/pts" -t devpts -o mode=0620,gid=5,nosuid,noexec && 48 | > mkdir "$1/dev/shm" && chroot_add_mount shm "$1/dev/shm" -t tmpfs -o mode=1777,nosuid,nodev && 49 | EOF 50 | 51 | cat < "$BOOTSTRAP/$SETUP" 52 | #!/bin/bash 53 | 54 | mknod /dev/random c 1 8 55 | mknod /dev/urandom c 1 9 56 | 57 | pacman-key --init 58 | pacman-key --populate archlinux 59 | 60 | pacstrap -G /mnt base openssh dhcpcd inetutils vim 61 | 62 | gpg-connect-agent --homedir /etc/pacman.d/gnupg "SCD KILLSCD" "SCD BYE" /bye 63 | gpg-connect-agent --homedir /etc/pacman.d/gnupg killagent /bye 64 | EOF 65 | 66 | chmod +x "$BOOTSTRAP/$SETUP" 67 | do-chroot "$BOOTSTRAP" "$SETUP" 68 | 69 | # Replace bootstrap with the base system 70 | mv "$BOOTSTRAP"/mnt/* "$INSTALL/" 71 | rm -rf "$BOOTSTRAP" 72 | } 73 | 74 | configure-arch() { 75 | configure-append < /etc/resolv.conf 77 | $(cat /etc/resolv.conf) 78 | EOT 79 | 80 | cat >> /etc/fstab < /etc/systemd/system/systemd-udev-trigger.service.d/vpsadminos.conf 103 | [Service] 104 | ExecStart= 105 | ExecStart=-udevadm trigger --subsystem-match=net --action=add 106 | EOT 107 | 108 | mkdir -p /var/log/journal 109 | usermod -L root 110 | 111 | echo > /etc/resolv.conf 112 | 113 | EOF 114 | } 115 | 116 | bootstrap-arch 117 | configure-arch 118 | run-configure 119 | set-initcmd "/sbin/init" "systemd.unified_cgroup_hierarchy=0" 120 | -------------------------------------------------------------------------------- /images/arch/config.sh: -------------------------------------------------------------------------------- 1 | BUILDER=fedora 2 | RELVER=$(date +%Y%m%d) 3 | -------------------------------------------------------------------------------- /images/centos-7/build.sh: -------------------------------------------------------------------------------- 1 | . "$IMAGEDIR/config.sh" 2 | POINTVER=7.9 3 | BUILD=2009 4 | RELEASE=http://mirror.centos.org/centos/${POINTVER}.${BUILD}/os/x86_64/Packages/centos-release-${POINTVER//./-}.${BUILD}.0.el7.centos.x86_64.rpm 5 | BASEURL=http://mirror.centos.org/centos/${POINTVER}.${BUILD}/os/x86_64 6 | UPDATES=http://mirror.centos.org/centos/${POINTVER}.${BUILD}/updates/x86_64/ 7 | GROUPNAME='core' 8 | EXTRAPKGS='vim man' 9 | 10 | . $INCLUDE/redhat-family.sh 11 | 12 | bootstrap 13 | configure-common 14 | 15 | configure-redhat-common 16 | 17 | configure-append <8 does not seem to have an updates repo, so this variable is used to 7 | # add AppStream repository just for the installation process. 8 | UPDATES=http://mirror.stream.centos.org/9-stream/AppStream/x86_64/os/ 9 | 10 | GROUPNAME='core' 11 | EXTRAPKGS='centos-stream-repos vim man' 12 | 13 | . $INCLUDE/redhat-family.sh 14 | 15 | bootstrap 16 | configure-common 17 | configure-redhat-common 18 | configure-rhel-9 19 | run-configure 20 | set-initcmd "/sbin/init" "systemd.unified_cgroup_hierarchy=0" 21 | -------------------------------------------------------------------------------- /images/centos-9-stream/config.sh: -------------------------------------------------------------------------------- 1 | BUILDER=fedora 2 | RELVER=9-stream-$(date +%Y%m%d) 3 | ARCH=x86_64 4 | -------------------------------------------------------------------------------- /images/debian-10/build.sh: -------------------------------------------------------------------------------- 1 | . "$IMAGEDIR/config.sh" 2 | RELNAME=buster 3 | BASEURL=http://ftp.cz.debian.org/debian 4 | 5 | . "$INCLUDE/debian.sh" 6 | 7 | bootstrap 8 | 9 | configure-common 10 | configure-debian 11 | 12 | cat > "$INSTALL/etc/apt/sources.list" < "$INSTALL/etc/apt/sources.list" < $INSTALL/etc/apt/sources.list < "$INSTALL/etc/apt/sources.list" < "$INSTALL/etc/apt/sources.list" < $INSTALL/etc/apt/sources.list < /dev/null ; then 19 | echo "hybrid" 20 | else 21 | echo "unified" 22 | fi 23 | } 24 | 25 | cgroup_setup_hybrid() { 26 | log_begin_msg "Mounting cgroups in a hybrid layout" 27 | 28 | local retval=0 29 | local name 30 | local hybrid_cgroups="blkio 31 | cpu,cpuacct 32 | cpuset 33 | devices 34 | freezer 35 | hugetlb 36 | memory 37 | net_cls,net_prio 38 | perf_event 39 | pids 40 | rdma" 41 | local hybrid_named="systemd" 42 | local mount_opts="nodev,noexec,nosuid" 43 | 44 | if ! mount -t tmpfs -o "$mount_opts" tmpfs /sys/fs/cgroup ; then 45 | log_action_msg "Unable to mount /sys/fs/cgroup" 46 | return 1 47 | fi 48 | 49 | for name in $hybrid_cgroups; do 50 | mkdir "/sys/fs/cgroup/$name" 51 | mount -n -t cgroup -o "$mount_opts,$name" \ 52 | cgroup "/sys/fs/cgroup/$name" || retval=1 53 | done 54 | 55 | for name in $hybrid_named; do 56 | mkdir "/sys/fs/cgroup/$name" 57 | mount -n -t cgroup -o "none,$mount_opts,name=$name" \ 58 | cgroup "/sys/fs/cgroup/$name" || retval=1 59 | done 60 | 61 | mkdir /sys/fs/cgroup/unified 62 | mount -n -t cgroup2 -o "$mount_opts" cgroup2 /sys/fs/cgroup/unified || retval=1 63 | 64 | ln -sfn systemd /sys/fs/cgroup/elogind 65 | 66 | mount -o remount,ro tmpfs /sys/fs/cgroup 67 | 68 | log_end_msg $retval 69 | } 70 | 71 | cgroup_setup_unified() { 72 | log_begin_msg "Mounting cgroups in a unified layout" 73 | 74 | mkdir /sys/fs/cgroup/init.scope 75 | echo 1 > /sys/fs/cgroup/init.scope/cgroup.procs 76 | 77 | log_end_msg 0 78 | } 79 | 80 | cgroup_setup() { 81 | local mode=$(cgroup_mode) 82 | 83 | case "$mode" in 84 | hybrid) cgroup_setup_hybrid ;; 85 | unified) cgroup_setup_unified ;; 86 | *) 87 | log_action_msg "Unknown cgroup mode '$mode'" 88 | return 1 89 | ;; 90 | esac 91 | } 92 | 93 | case "$1" in 94 | start) 95 | cgroup_setup 96 | ;; 97 | 98 | status) 99 | if mountpoint -q /sys/fs/cgroup; then 100 | log_success_msg 'cgroups hierarchy is mounted' 101 | exit 0 102 | else 103 | log_failure_msg 'cgroups hierarchy is not mounted' 104 | exit 1 105 | fi 106 | ;; 107 | 108 | *) 109 | echo "Usage: $0 {start|status}" 110 | exit 1 111 | ;; 112 | esac 113 | 114 | exit 0 115 | -------------------------------------------------------------------------------- /images/devuan-3.0/config.sh: -------------------------------------------------------------------------------- 1 | BUILDER=devuan 2 | -------------------------------------------------------------------------------- /images/devuan-4/build.sh: -------------------------------------------------------------------------------- 1 | . "$IMAGEDIR/config.sh" 2 | RELNAME=chimaera 3 | BASEURL=http://deb.devuan.org/merged 4 | 5 | . $INCLUDE/devuan.sh 6 | 7 | bootstrap 8 | 9 | cat > $INSTALL/etc/apt/sources.list < /dev/null ; then 19 | echo "hybrid" 20 | else 21 | echo "unified" 22 | fi 23 | } 24 | 25 | cgroup_setup_hybrid() { 26 | log_begin_msg "Mounting cgroups in a hybrid layout" 27 | 28 | local retval=0 29 | local name 30 | local hybrid_cgroups="blkio 31 | cpu,cpuacct 32 | cpuset 33 | devices 34 | freezer 35 | hugetlb 36 | memory 37 | net_cls,net_prio 38 | perf_event 39 | pids 40 | rdma" 41 | local hybrid_named="systemd" 42 | local mount_opts="nodev,noexec,nosuid" 43 | 44 | if ! mount -t tmpfs -o "$mount_opts" tmpfs /sys/fs/cgroup ; then 45 | log_action_msg "Unable to mount /sys/fs/cgroup" 46 | return 1 47 | fi 48 | 49 | for name in $hybrid_cgroups; do 50 | mkdir "/sys/fs/cgroup/$name" 51 | mount -n -t cgroup -o "$mount_opts,$name" \ 52 | cgroup "/sys/fs/cgroup/$name" || retval=1 53 | done 54 | 55 | for name in $hybrid_named; do 56 | mkdir "/sys/fs/cgroup/$name" 57 | mount -n -t cgroup -o "none,$mount_opts,name=$name" \ 58 | cgroup "/sys/fs/cgroup/$name" || retval=1 59 | done 60 | 61 | mkdir /sys/fs/cgroup/unified 62 | mount -n -t cgroup2 -o "$mount_opts" cgroup2 /sys/fs/cgroup/unified || retval=1 63 | 64 | ln -sfn systemd /sys/fs/cgroup/elogind 65 | 66 | mount -o remount,ro tmpfs /sys/fs/cgroup 67 | 68 | log_end_msg $retval 69 | } 70 | 71 | cgroup_setup_unified() { 72 | log_begin_msg "Mounting cgroups in a unified layout" 73 | 74 | mkdir /sys/fs/cgroup/init.scope 75 | echo 1 > /sys/fs/cgroup/init.scope/cgroup.procs 76 | 77 | log_end_msg 0 78 | } 79 | 80 | cgroup_setup() { 81 | local mode=$(cgroup_mode) 82 | 83 | case "$mode" in 84 | hybrid) cgroup_setup_hybrid ;; 85 | unified) cgroup_setup_unified ;; 86 | *) 87 | log_action_msg "Unknown cgroup mode '$mode'" 88 | return 1 89 | ;; 90 | esac 91 | } 92 | 93 | case "$1" in 94 | start) 95 | cgroup_setup 96 | ;; 97 | 98 | status) 99 | if mountpoint -q /sys/fs/cgroup; then 100 | log_success_msg 'cgroups hierarchy is mounted' 101 | exit 0 102 | else 103 | log_failure_msg 'cgroups hierarchy is not mounted' 104 | exit 1 105 | fi 106 | ;; 107 | 108 | *) 109 | echo "Usage: $0 {start|status}" 110 | exit 1 111 | ;; 112 | esac 113 | 114 | exit 0 115 | -------------------------------------------------------------------------------- /images/devuan-4/config.sh: -------------------------------------------------------------------------------- 1 | BUILDER=devuan 2 | -------------------------------------------------------------------------------- /images/fedora-35/build.sh: -------------------------------------------------------------------------------- 1 | . "$IMAGEDIR/config.sh" 2 | BASEURL=http://ftp.fi.muni.cz/pub/linux/fedora/linux/releases/$RELVER/Everything/x86_64/os 3 | RELEASE="$BASEURL/Packages/f/fedora-release-server-$RELVER-33.noarch.rpm" 4 | GROUPNAME="minimal install" 5 | EXTRAPKGS="vim man fedora-gpg-keys" 6 | REMOVEPKGS="plymouth" 7 | 8 | . $INCLUDE/redhat-family.sh 9 | 10 | bootstrap 11 | configure-common 12 | 13 | configure-redhat-common 14 | configure-fedora 15 | configure-fedora-nm-initscripts 16 | run-configure 17 | 18 | set-initcmd "/sbin/init" "systemd.unified_cgroup_hierarchy=0" 19 | -------------------------------------------------------------------------------- /images/fedora-35/config.sh: -------------------------------------------------------------------------------- 1 | BUILDER=fedora 2 | -------------------------------------------------------------------------------- /images/fedora-36/build.sh: -------------------------------------------------------------------------------- 1 | . "$IMAGEDIR/config.sh" 2 | BASEURL=http://ftp.fi.muni.cz/pub/linux/fedora/linux/releases/$RELVER/Everything/x86_64/os 3 | RELEASE="$BASEURL/Packages/f/fedora-release-server-$RELVER-17.noarch.rpm 4 | $BASEURL/Packages/f/fedora-release-$RELVER-17.noarch.rpm 5 | $BASEURL/Packages/f/fedora-release-common-$RELVER-17.noarch.rpm 6 | $BASEURL/Packages/f/fedora-release-identity-basic-$RELVER-17.noarch.rpm" 7 | GROUPNAME="minimal install" 8 | EXTRAPKGS="vim man fedora-gpg-keys" 9 | REMOVEPKGS="plymouth" 10 | 11 | . $INCLUDE/redhat-family.sh 12 | 13 | bootstrap 14 | configure-common 15 | 16 | configure-redhat-common 17 | configure-fedora 18 | configure-fedora-nm-keyfiles 19 | run-configure 20 | 21 | set-initcmd "/sbin/init" "systemd.unified_cgroup_hierarchy=0" 22 | -------------------------------------------------------------------------------- /images/fedora-36/config.sh: -------------------------------------------------------------------------------- 1 | BUILDER=fedora 2 | -------------------------------------------------------------------------------- /images/fedora-37/build.sh: -------------------------------------------------------------------------------- 1 | . "$IMAGEDIR/config.sh" 2 | BASEURL=http://ftp.fi.muni.cz/pub/linux/fedora/linux/releases/$RELVER/Everything/x86_64/os 3 | RELEASE="$BASEURL/Packages/f/fedora-release-server-$RELVER-14.noarch.rpm 4 | $BASEURL/Packages/f/fedora-release-$RELVER-14.noarch.rpm 5 | $BASEURL/Packages/f/fedora-release-common-$RELVER-14.noarch.rpm 6 | $BASEURL/Packages/f/fedora-release-identity-basic-$RELVER-14.noarch.rpm" 7 | GROUPNAME="minimal install" 8 | EXTRAPKGS="vim man fedora-gpg-keys glibc-langpack-en" 9 | REMOVEPKGS="plymouth" 10 | 11 | . $INCLUDE/redhat-family.sh 12 | 13 | bootstrap 14 | configure-common 15 | 16 | configure-redhat-common 17 | configure-fedora 18 | configure-fedora-nm-keyfiles 19 | run-configure 20 | 21 | set-initcmd "/sbin/init" "systemd.unified_cgroup_hierarchy=0" 22 | -------------------------------------------------------------------------------- /images/fedora-37/config.sh: -------------------------------------------------------------------------------- 1 | BUILDER=fedora 2 | -------------------------------------------------------------------------------- /images/fedora-38/build.sh: -------------------------------------------------------------------------------- 1 | . "$IMAGEDIR/config.sh" 2 | BASEURL=http://ftp.fi.muni.cz/pub/linux/fedora/linux/releases/$RELVER/Everything/x86_64/os 3 | RELEASE="$BASEURL/Packages/f/fedora-release-server-$RELVER-34.noarch.rpm 4 | $BASEURL/Packages/f/fedora-release-$RELVER-34.noarch.rpm 5 | $BASEURL/Packages/f/fedora-release-common-$RELVER-34.noarch.rpm 6 | $BASEURL/Packages/f/fedora-release-identity-basic-$RELVER-34.noarch.rpm" 7 | GROUPNAME="minimal install" 8 | EXTRAPKGS="vim man fedora-gpg-keys glibc-langpack-en" 9 | REMOVEPKGS="plymouth" 10 | 11 | . $INCLUDE/redhat-family.sh 12 | 13 | bootstrap 14 | configure-common 15 | 16 | configure-redhat-common 17 | configure-fedora 18 | configure-fedora-nm-keyfiles 19 | run-configure 20 | 21 | set-initcmd "/sbin/init" "systemd.unified_cgroup_hierarchy=0" 22 | -------------------------------------------------------------------------------- /images/fedora-38/config.sh: -------------------------------------------------------------------------------- 1 | BUILDER=fedora 2 | -------------------------------------------------------------------------------- /images/gentoo-musl/build.sh: -------------------------------------------------------------------------------- 1 | VARIANT=musl 2 | . "$IMAGEDIR/config.sh" 3 | . "$INCLUDE/gentoo.sh" 4 | 5 | fetch 6 | extract 7 | configure-gentoo-begin 8 | 9 | configure-append <> /etc/inittab <> /etc/inittab < /etc/systemd/system/systemd-udev-trigger.service.d/vpsadminos.conf 16 | [Service] 17 | ExecStart= 18 | ExecStart=-udevadm trigger --subsystem-match=net --action=add 19 | EOT 20 | EOF 21 | 22 | configure-gentoo-end 23 | run-configure 24 | 25 | set-initcmd "/sbin/init" "systemd.unified_cgroup_hierarchy=0" 26 | -------------------------------------------------------------------------------- /images/gentoo-systemd/config.sh: -------------------------------------------------------------------------------- 1 | BUILDER=fedora 2 | DISTNAME=gentoo 3 | RELVER=systemd-$(date +%Y%m%d) 4 | -------------------------------------------------------------------------------- /images/nixos-22.11/build.sh: -------------------------------------------------------------------------------- 1 | . "$IMAGEDIR/config.sh" 2 | . "$INCLUDE/nixos.sh" 3 | 4 | CHANNEL=nixos-22.11 5 | build-nixos 6 | -------------------------------------------------------------------------------- /images/nixos-22.11/config.sh: -------------------------------------------------------------------------------- 1 | BUILDER=nixos 2 | -------------------------------------------------------------------------------- /images/nixos-unstable/build.sh: -------------------------------------------------------------------------------- 1 | . "$IMAGEDIR/config.sh" 2 | . "$INCLUDE/nixos.sh" 3 | 4 | CHANNEL=nixos-unstable 5 | build-nixos 6 | -------------------------------------------------------------------------------- /images/nixos-unstable/config.sh: -------------------------------------------------------------------------------- 1 | BUILDER=nixos 2 | RELVER=unstable-$(date +%Y%m%d) 3 | -------------------------------------------------------------------------------- /images/opensuse-leap-15.2/build.sh: -------------------------------------------------------------------------------- 1 | . "$IMAGEDIR/config.sh" 2 | . "$INCLUDE/opensuse.sh" 3 | 4 | bootstrap 5 | configure-common 6 | 7 | configure-opensuse 8 | 9 | run-configure 10 | -------------------------------------------------------------------------------- /images/opensuse-leap-15.2/config.sh: -------------------------------------------------------------------------------- 1 | BUILDER=opensuse-leap 2 | SPIN=leap 3 | SPINVER=15.2 4 | RELVER=$SPIN-$SPINVER 5 | ARCH=x86_64 6 | -------------------------------------------------------------------------------- /images/opensuse-leap-15.3/build.sh: -------------------------------------------------------------------------------- 1 | . "$IMAGEDIR/config.sh" 2 | . "$INCLUDE/opensuse.sh" 3 | 4 | bootstrap 5 | configure-common 6 | 7 | configure-opensuse 8 | 9 | run-configure 10 | -------------------------------------------------------------------------------- /images/opensuse-leap-15.3/config.sh: -------------------------------------------------------------------------------- 1 | BUILDER=opensuse-leap 2 | SPIN=leap 3 | SPINVER=15.3 4 | RELVER=$SPIN-$SPINVER 5 | ARCH=x86_64 6 | -------------------------------------------------------------------------------- /images/opensuse-leap-15.4/build.sh: -------------------------------------------------------------------------------- 1 | . "$IMAGEDIR/config.sh" 2 | . "$INCLUDE/opensuse.sh" 3 | 4 | bootstrap 5 | configure-common 6 | 7 | configure-opensuse 8 | 9 | run-configure 10 | -------------------------------------------------------------------------------- /images/opensuse-leap-15.4/config.sh: -------------------------------------------------------------------------------- 1 | BUILDER=opensuse-leap 2 | SPIN=leap 3 | SPINVER=15.4 4 | RELVER=$SPIN-$SPINVER 5 | ARCH=x86_64 6 | -------------------------------------------------------------------------------- /images/opensuse-tumbleweed/build.sh: -------------------------------------------------------------------------------- 1 | . "$IMAGEDIR/config.sh" 2 | . "$INCLUDE/opensuse.sh" 3 | 4 | bootstrap 5 | configure-common 6 | 7 | configure-opensuse 8 | 9 | run-configure 10 | set-initcmd "/sbin/init" "systemd.unified_cgroup_hierarchy=0" 11 | -------------------------------------------------------------------------------- /images/opensuse-tumbleweed/config.sh: -------------------------------------------------------------------------------- 1 | BUILDER=opensuse-tumbleweed 2 | SPIN=tumbleweed 3 | SPINVER=$(date +%Y%m%d) 4 | RELVER=$SPIN-$SPINVER 5 | ARCH=x86_64 6 | -------------------------------------------------------------------------------- /images/rocky-8/build.sh: -------------------------------------------------------------------------------- 1 | . "$IMAGEDIR/config.sh" 2 | POINTVER=8.7 3 | RELEASE=https://download.rockylinux.org/pub/rocky/${POINTVER}/BaseOS/x86_64/os/Packages/r/rocky-release-${POINTVER}-1.2.el8.noarch.rpm 4 | BASEURL=https://download.rockylinux.org/pub/rocky/${POINTVER}/BaseOS/x86_64/os/ 5 | 6 | # CentOS 8 does not seem to have an updates repo, so this variable is used to 7 | # add AppStream repository just for the installation process. 8 | UPDATES=https://download.rockylinux.org/pub/rocky/${POINTVER}/AppStream/x86_64/os/ 9 | 10 | GROUPNAME='core' 11 | EXTRAPKGS='rocky-gpg-keys rocky-repos vim man' 12 | 13 | . $INCLUDE/redhat-family.sh 14 | 15 | bootstrap 16 | configure-common 17 | configure-redhat-common 18 | configure-rhel-8 19 | run-configure 20 | -------------------------------------------------------------------------------- /images/rocky-8/config.sh: -------------------------------------------------------------------------------- 1 | BUILDER=almalinux 2 | -------------------------------------------------------------------------------- /images/rocky-9/build.sh: -------------------------------------------------------------------------------- 1 | . "$IMAGEDIR/config.sh" 2 | POINTVER=9.1 3 | RELEASE=https://download.rockylinux.org/pub/rocky/${POINTVER}/BaseOS/x86_64/os/Packages/r/rocky-release-${POINTVER}-1.11.el9.noarch.rpm 4 | BASEURL=https://download.rockylinux.org/pub/rocky/${POINTVER}/BaseOS/x86_64/os/ 5 | 6 | # CentOS 8 does not seem to have an updates repo, so this variable is used to 7 | # add AppStream repository just for the installation process. 8 | UPDATES=https://download.rockylinux.org/pub/rocky/${POINTVER}/AppStream/x86_64/os/ 9 | 10 | GROUPNAME='core' 11 | EXTRAPKGS='rocky-gpg-keys rocky-repos vim man' 12 | 13 | . $INCLUDE/redhat-family.sh 14 | 15 | bootstrap 16 | configure-common 17 | configure-redhat-common 18 | configure-rhel-9 19 | run-configure 20 | set-initcmd "/sbin/init" "systemd.unified_cgroup_hierarchy=0" 21 | -------------------------------------------------------------------------------- /images/rocky-9/config.sh: -------------------------------------------------------------------------------- 1 | BUILDER=fedora 2 | -------------------------------------------------------------------------------- /images/slackware-15.0/build.sh: -------------------------------------------------------------------------------- 1 | # Slackware 15.0 2 | # 3 | # 1. Download FILELIST.txt and CHECKSUMS.md5 from remote repository, use these 4 | # to download installed packages 5 | # 2. Install pkgtools to the $DOWNLOAD directory (not in the new rootfs) 6 | # 3. Use the installpkg from pkgtools to install the base system within 7 | # the rootfs 8 | # 4. Chroot, setup slackpkg, upgrade the system and install extra packages, 9 | # additional configuration and patching 10 | # 11 | # We bring in our own script to mount cgroups, see /etc/rc.d/rc.vpsadminos.cgroups. 12 | # 13 | # /etc/rc.d/rc.M (multi-user runlevel) starts the original /etc/rc.d/rc.inet1 14 | # script that brings up the loopback. It has been patched to start our custom 15 | # script /etc/rc.d/rc.venet. This script can start/stop/restart the venet0 16 | # interface. It executes /etc/rc.d/rc.venet.start on start and 17 | # /etc/rc.d/rc.venet.stop on stop. 18 | # 19 | # These scripts are responsible for configuring the interface and are generated 20 | # by osctld. rc.venet.{start,stop} scripts configure the interface using 21 | # /sbin/ip commands (needs package iproute2). The contents of these files is 22 | # rewritten on VPS start and on osctl ct netif ip add/del commands. 23 | 24 | . "$IMAGEDIR/config.sh" 25 | BASEURL=https://mirrors.slackware.com/slackware/ 26 | LOCAL_REPO="$DOWNLOAD/repo" 27 | LOCAL_ROOT="$DOWNLOAD/root" 28 | INSTALLPKG= 29 | PKGLIST="$DOWNLOAD/pkglist.txt" 30 | PKGS=" 31 | aaa_base 32 | aaa_elflibs 33 | aaa_glibc-solibs 34 | aaa_libraries 35 | aaa_terminfo 36 | acl 37 | attr 38 | bash 39 | bin 40 | bzip2 41 | ca-certificates 42 | coreutils 43 | cpio 44 | cracklib 45 | dcron 46 | devs 47 | dialog 48 | diffutils 49 | dhcpcd 50 | e2fsprogs 51 | elfutils 52 | elogind 53 | etc 54 | eudev 55 | file 56 | findutils 57 | gawk 58 | genpower 59 | glibc-zoneinfo 60 | gmp 61 | gnupg 62 | gnutls 63 | gpm 64 | grep 65 | groff 66 | gzip 67 | hostname 68 | iproute2 69 | iputils 70 | keyutils 71 | krb5 72 | less 73 | libcap 74 | libmpc 75 | libffi 76 | libidn2 77 | libmnl 78 | libnsl 79 | libpsl 80 | libpwquality 81 | libseccomp 82 | libsigsegv 83 | libsodium 84 | libtermcap 85 | libtirpc 86 | libunistring 87 | libusb 88 | libusb-compat 89 | logrotate 90 | man 91 | man-pages 92 | mpfr 93 | nano 94 | ncurses 95 | net-tools 96 | nettle 97 | network-scripts 98 | openssh 99 | n/openssl 100 | a/openssl-solibs 101 | pam 102 | p11-kit 103 | pcre 104 | pcre2 105 | perl 106 | pkgtools 107 | procps 108 | python 109 | readline 110 | sed 111 | shadow 112 | slackpkg 113 | sysklogd 114 | sysvinit 115 | sysvinit-scripts 116 | tar 117 | util-linux 118 | vim 119 | wget 120 | which 121 | xz 122 | zlib 123 | " 124 | 125 | require_cmd wget 126 | 127 | download_index() { 128 | mkdir -p "$LOCAL_REPO" 129 | wget -O "$LOCAL_REPO/FILELIST.txt" $BASEURL/slackware64-$RELVER/FILELIST.TXT 130 | wget -O "$LOCAL_REPO/CHECKSUMS.md5" $BASEURL/slackware64-$RELVER/CHECKSUMS.md5 131 | } 132 | 133 | download_pkg() { 134 | if [[ "$1" == *"/"* ]] ; then 135 | local pkg=`find "$LOCAL_REPO" -type f -wholename "*/$1-*.t?z" | head -n1` 136 | else 137 | local pkg=`find "$LOCAL_REPO" -type f -name "$1-*.t?z" | head -n1` 138 | fi 139 | 140 | if [ "$pkg" != "" ] ; then 141 | echo $pkg 142 | exit 143 | fi 144 | 145 | if [[ "$1" == *"/"* ]] ; then 146 | local path=`grep -P "./slackware64/$1\-.+\.t.z$" "$LOCAL_REPO/FILELIST.txt" | awk '{ print $8; }' | head -n1` 147 | else 148 | local path=`grep -P "./slackware64/[^/]+/$1\-.+\.t.z$" "$LOCAL_REPO/FILELIST.txt" | awk '{ print $8; }' | head -n1` 149 | fi 150 | 151 | if [ "$path" == "" ] ; then 152 | warn "Package '$1' not found" 153 | exit 1 154 | fi 155 | 156 | mkdir -p "$LOCAL_REPO/$(dirname $path)" 157 | wget -O "$LOCAL_REPO/$path" $BASEURL/slackware64-$RELVER/$path 158 | 159 | if ! (cd "$LOCAL_REPO" ; grep "$path$" CHECKSUMS.md5 | md5sum -c > /dev/null) 160 | then 161 | warn "$1 checksum invalid" 162 | exit 1 163 | fi 164 | 165 | echo "$LOCAL_REPO/$path" 166 | } 167 | 168 | setup_pkgtools() { 169 | mkdir -p "$LOCAL_ROOT" 170 | 171 | local pkg="`download_pkg pkgtools`" 172 | [ "$?" != "0" ] && exit 1 173 | 174 | tar -xJf "$pkg" -C "$LOCAL_ROOT" 175 | INSTALLPKG="$LOCAL_ROOT/sbin/installpkg" 176 | } 177 | 178 | install_pkg() { 179 | local pkg=`download_pkg $1` 180 | [ "$?" != "0" ] && exit 1 181 | 182 | $INSTALLPKG --terse --root "$INSTALL" $pkg 183 | } 184 | 185 | download_pkg_to_list() { 186 | local pkg="`download_pkg $1`" 187 | [ "$?" != "0" ] && exit 1 188 | 189 | flock "$PKGLIST" bash -c "echo $pkg >> \"$PKGLIST\"" 190 | } 191 | 192 | install_pkg_from_list() { 193 | $INSTALLPKG --terse --root "$INSTALL" $1 194 | } 195 | 196 | 197 | download_index || exit 1 198 | 199 | # Install pkgtools outside the rootfs 200 | setup_pkgtools || exit 1 201 | 202 | # Download all packages 203 | export BASEURL LOCAL_REPO PKGLIST RELVER 204 | export -f download_pkg_to_list download_pkg 205 | 206 | touch "$PKGLIST" 207 | 208 | for pkg in $PKGS ; do 209 | echo $pkg 210 | done | xargs -n 1 -P $(nproc) -I {} bash -c 'download_pkg_to_list "$@"' _ {} 211 | 212 | # Install all packages in the rootfs 213 | for pkg in $(cat "$PKGLIST") ; do 214 | echo "Installing $pkg" 215 | install_pkg_from_list $pkg 216 | 217 | if [ "$?" != "0" ] ; then 218 | warn "Unable to install '$pkg'" 219 | exit 1 220 | fi 221 | done 222 | 223 | cp "$IMAGEDIR"/cgroups.sh "$INSTALL"/etc/rc.d/rc.vpsadminos.cgroups 224 | 225 | configure-common 226 | configure-append < /etc/resolv.conf 237 | 238 | /usr/sbin/update-ca-certificates --fresh 239 | 240 | # Setup slackpkg 241 | sed -i -r 's/^# (https:\/\/mirrors.slackware.com\/slackware\/slackware64-$RELVER\/)$/\1/' /etc/slackpkg/mirrors 242 | slackpkg -batch=on -default_answer=y update gpg 243 | slackpkg -batch=on -default_answer=y update 244 | slackpkg -batch=on -default_answer=y upgrade slackpkg 245 | slackpkg -batch=on -default_answer=y upgrade aaa_glibc-solibs 246 | 247 | # Use new configuration files, O as overwrite 248 | echo O | slackpkg -batch=on new-config 249 | 250 | # Reconfigure mirror 251 | sed -i -r 's/^# (https:\/\/mirrors.slackware.com\/slackware\/slackware64-$RELVER\/)$/\1/' /etc/slackpkg/mirrors 252 | 253 | slackpkg -batch=on -default_answer=y update 254 | slackpkg -batch=on -default_answer=y upgrade-all 255 | 256 | # Use new configuration files, O as overwrite 257 | echo O | slackpkg -batch=on new-config 258 | 259 | # Delete old configuration files 260 | find /etc -name "*.orig" -delete 261 | 262 | echo > /etc/fstab 263 | 264 | # Remote console 265 | sed -i '/^c1:/c\c1:12345:respawn:\/sbin\/agetty --noclear 38400 console linux' /etc/inittab 266 | sed -i -r 's/^(c[2-6]:)/#\1/g' /etc/inittab 267 | 268 | # Power 269 | sed -i 's|pf::powerfail:/sbin/genpowerfail start|pf::powerwait:/sbin/halt|' /etc/inittab 270 | 271 | # Configure SSH 272 | sed -i 's/^#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config 273 | 274 | # Mount /run 275 | sed -i \ 276 | 's|if \[ -d /run -a -z "\$container" \]; then|# Mount /run on vpsAdminOS\nif \[ -d /run \]; then|' \ 277 | /etc/rc.d/rc.S 278 | 279 | # Custom cgroup setup script 280 | sed -i \ 281 | '/^# Mount Control Groups filesystem interface:/a if \[ -x /etc/rc.d/rc.vpsadminos.cgroups \] ; then\n\ 282 | \/etc\/rc.d\/rc.vpsadminos.cgroups start\n\ 283 | fi\n' \ 284 | /etc/rc.d/rc.S 285 | chmod +x /etc/rc.d/rc.vpsadminos.cgroups 286 | 287 | # Custom network setup script 288 | sed -i '/^# Start networking daemons:$/i \ 289 | # Setup osctl network\n\ 290 | if \[ -x \/etc\/rc.d\/rc.venet \] ; then\n\ 291 | \/etc\/rc.d\/rc.venet start\n\ 292 | fi\n\ 293 | 294 | ' /etc/rc.d/rc.M 295 | 296 | cat < /etc/rc.d/rc.venet 297 | #!/bin/sh 298 | case "\\\$1" in 299 | start|stop) 300 | [ -f "/etc/rc.d/rc.venet.\\\$1" ] && . "/etc/rc.d/rc.venet.\\\$1" 301 | ;; 302 | restart) 303 | if [ -f /etc/rc.d/rc.venet.start ] && [ -f /etc/rc.d/rc.venet.stop ] ; then 304 | . /etc/rc.d/rc.venet.stop 305 | . /etc/rc.d/rc.venet.start 306 | fi 307 | ;; 308 | *) 309 | echo "Usage: \\\$0 start|stop|restart" 310 | ;; 311 | esac 312 | 313 | EOT 314 | 315 | chmod +x /etc/rc.d/rc.venet 316 | 317 | if [ ! -f /sbin/modprobe ] ; then 318 | cat < /sbin/modprobe 319 | #!/bin/sh 320 | # This is a /sbin/modprobe shim provided by vpsAdminOS. This system is expected 321 | # to run as a container, which cannot load its own modules. 322 | exit 0 323 | EOT 324 | chmod +x /sbin/modprobe 325 | fi 326 | 327 | # Enable Ctrl-left-arrow and Ctrl-right-arrow navigation in bash 328 | cat <> /etc/inputrc 329 | 330 | # mappings for Ctrl-left-arrow and Ctrl-right-arrow for word moving 331 | "\e[1;5C": forward-word 332 | "\e[1;5D": backward-word 333 | "\e[5C": forward-word 334 | "\e[5D": backward-word 335 | "\e\e[C": forward-word 336 | "\e\e[D": backward-word 337 | EOT 338 | 339 | usermod -L root 340 | echo > /etc/resolv.conf 341 | EOF 342 | run-configure 343 | -------------------------------------------------------------------------------- /images/slackware-15.0/cgroups.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | cgroup_mode() { 4 | if grep -x "^[[:digit:]]:cpuset:/" /proc/1/cgroup > /dev/null ; then 5 | echo "hybrid" 6 | else 7 | echo "unified" 8 | fi 9 | } 10 | 11 | cgroup_setup_hybrid() { 12 | echo "Mounting cgroups in a hybrid layout" 13 | 14 | local retval=0 15 | local name 16 | local hybrid_cgroups="blkio 17 | cpu,cpuacct 18 | cpuset 19 | devices 20 | freezer 21 | hugetlb 22 | memory 23 | net_cls,net_prio 24 | perf_event 25 | pids 26 | rdma" 27 | local hybrid_named="systemd" 28 | local mount_opts="nodev,noexec,nosuid" 29 | 30 | if ! mount -t tmpfs -o "$mount_opts" tmpfs /sys/fs/cgroup ; then 31 | echo "Unable to mount /sys/fs/cgroup" 32 | return 1 33 | fi 34 | 35 | for name in $hybrid_cgroups; do 36 | mkdir "/sys/fs/cgroup/$name" 37 | mount -n -t cgroup -o "$mount_opts,$name" \ 38 | cgroup "/sys/fs/cgroup/$name" || retval=1 39 | done 40 | 41 | for name in $hybrid_named; do 42 | mkdir "/sys/fs/cgroup/$name" 43 | mount -n -t cgroup -o "none,$mount_opts,name=$name" \ 44 | cgroup "/sys/fs/cgroup/$name" || retval=1 45 | done 46 | 47 | mkdir /sys/fs/cgroup/unified 48 | mount -n -t cgroup2 -o "$mount_opts" cgroup2 /sys/fs/cgroup/unified || retval=1 49 | 50 | ln -s systemd /sys/fs/cgroup/elogind 51 | mount -o remount,ro tmpfs /sys/fs/cgroup 52 | 53 | return $retval 54 | } 55 | 56 | cgroup_setup_unified() { 57 | echo "Mounting cgroups in a unified layout" 58 | 59 | mkdir /sys/fs/cgroup/init.scope 60 | echo 1 > /sys/fs/cgroup/init.scope/cgroup.procs 61 | } 62 | 63 | case "$(cgroup_mode)" in 64 | hybrid) cgroup_setup_hybrid ;; 65 | unified) cgroup_setup_unified ;; 66 | *) echo "Unknown cgroup mode" ;; 67 | esac 68 | -------------------------------------------------------------------------------- /images/slackware-15.0/config.sh: -------------------------------------------------------------------------------- 1 | BUILDER=fedora 2 | -------------------------------------------------------------------------------- /images/slackware-current/build.sh: -------------------------------------------------------------------------------- 1 | # Slackware current 2 | # 3 | # 1. Download FILELIST.txt and CHECKSUMS.md5 from remote repository, use these 4 | # to download installed packages 5 | # 2. Install pkgtools to the $DOWNLOAD directory (not in the new rootfs) 6 | # 3. Use the installpkg from pkgtools to install the base system within 7 | # the rootfs 8 | # 4. Chroot, setup slackpkg, upgrade the system and install extra packages, 9 | # additional configuration and patching 10 | # 11 | # We bring in our own script to mount cgroups, see /etc/rc.d/rc.vpsadminos.cgroups. 12 | # 13 | # /etc/rc.d/rc.M (multi-user runlevel) starts the original /etc/rc.d/rc.inet1 14 | # script that brings up the loopback. It has been patched to start our custom 15 | # script /etc/rc.d/rc.venet. This script can start/stop/restart the venet0 16 | # interface. It executes /etc/rc.d/rc.venet.start on start and 17 | # /etc/rc.d/rc.venet.stop on stop. 18 | # 19 | # These scripts are responsible for configuring the interface and are generated 20 | # by osctld. rc.venet.{start,stop} scripts configure the interface using 21 | # /sbin/ip commands (needs package iproute2). The contents of these files is 22 | # rewritten on VPS start and on osctl ct netif ip add/del commands. 23 | 24 | . "$IMAGEDIR/config.sh" 25 | RELVER=current 26 | BASEURL=https://mirrors.slackware.com/slackware/ 27 | LOCAL_REPO="$DOWNLOAD/repo" 28 | LOCAL_ROOT="$DOWNLOAD/root" 29 | INSTALLPKG= 30 | PKGLIST="$DOWNLOAD/pkglist.txt" 31 | PKGS=" 32 | aaa_base 33 | aaa_elflibs 34 | aaa_glibc-solibs 35 | aaa_libraries 36 | aaa_terminfo 37 | acl 38 | attr 39 | bash 40 | bin 41 | bzip2 42 | ca-certificates 43 | coreutils 44 | cpio 45 | cracklib 46 | dcron 47 | devs 48 | dialog 49 | diffutils 50 | dhcpcd 51 | e2fsprogs 52 | elfutils 53 | elogind 54 | etc 55 | eudev 56 | file 57 | findutils 58 | gawk 59 | genpower 60 | glibc-zoneinfo 61 | gmp 62 | gnupg 63 | gnutls 64 | gpm 65 | grep 66 | groff 67 | gzip 68 | hostname 69 | iproute2 70 | iputils 71 | keyutils 72 | krb5 73 | less 74 | libcap 75 | libmpc 76 | libffi 77 | libidn2 78 | libmnl 79 | libnsl 80 | libpsl 81 | libpwquality 82 | libseccomp 83 | libsigsegv 84 | libsodium 85 | libtermcap 86 | libtirpc 87 | libunistring 88 | libusb 89 | libusb-compat 90 | logrotate 91 | man 92 | man-pages 93 | mpfr 94 | nano 95 | ncurses 96 | net-tools 97 | nettle 98 | network-scripts 99 | openssh 100 | n/openssl 101 | a/openssl-solibs 102 | pam 103 | p11-kit 104 | pcre 105 | pcre2 106 | perl 107 | pkgtools 108 | procps 109 | python 110 | readline 111 | sed 112 | shadow 113 | slackpkg 114 | sysklogd 115 | sysvinit 116 | sysvinit-scripts 117 | tar 118 | util-linux 119 | vim 120 | wget 121 | which 122 | xz 123 | zlib 124 | " 125 | 126 | require_cmd wget 127 | 128 | download_index() { 129 | mkdir -p "$LOCAL_REPO" 130 | wget -O "$LOCAL_REPO/FILELIST.txt" $BASEURL/slackware64-$RELVER/FILELIST.TXT 131 | wget -O "$LOCAL_REPO/CHECKSUMS.md5" $BASEURL/slackware64-$RELVER/CHECKSUMS.md5 132 | } 133 | 134 | download_pkg() { 135 | if [[ "$1" == *"/"* ]] ; then 136 | local pkg=`find "$LOCAL_REPO" -type f -wholename "*/$1-*.t?z" | head -n1` 137 | else 138 | local pkg=`find "$LOCAL_REPO" -type f -name "$1-*.t?z" | head -n1` 139 | fi 140 | 141 | if [ "$pkg" != "" ] ; then 142 | echo $pkg 143 | exit 144 | fi 145 | 146 | if [[ "$1" == *"/"* ]] ; then 147 | local path=`grep -P "./slackware64/$1\-.+\.t.z$" "$LOCAL_REPO/FILELIST.txt" | awk '{ print $8; }' | head -n1` 148 | else 149 | local path=`grep -P "./slackware64/[^/]+/$1\-.+\.t.z$" "$LOCAL_REPO/FILELIST.txt" | awk '{ print $8; }' | head -n1` 150 | fi 151 | 152 | if [ "$path" == "" ] ; then 153 | warn "Package '$1' not found" 154 | exit 1 155 | fi 156 | 157 | mkdir -p "$LOCAL_REPO/$(dirname $path)" 158 | wget -O "$LOCAL_REPO/$path" $BASEURL/slackware64-$RELVER/$path 159 | 160 | if ! (cd "$LOCAL_REPO" ; grep "$path$" CHECKSUMS.md5 | md5sum -c > /dev/null) 161 | then 162 | warn "$1 checksum invalid" 163 | exit 1 164 | fi 165 | 166 | echo "$LOCAL_REPO/$path" 167 | } 168 | 169 | setup_pkgtools() { 170 | mkdir -p "$LOCAL_ROOT" 171 | 172 | local pkg="`download_pkg pkgtools`" 173 | [ "$?" != "0" ] && exit 1 174 | 175 | tar -xJf "$pkg" -C "$LOCAL_ROOT" 176 | INSTALLPKG="$LOCAL_ROOT/sbin/installpkg" 177 | } 178 | 179 | install_pkg() { 180 | local pkg=`download_pkg $1` 181 | [ "$?" != "0" ] && exit 1 182 | 183 | $INSTALLPKG --terse --root "$INSTALL" $pkg 184 | } 185 | 186 | download_pkg_to_list() { 187 | local pkg="`download_pkg $1`" 188 | [ "$?" != "0" ] && exit 1 189 | 190 | flock "$PKGLIST" bash -c "echo $pkg >> \"$PKGLIST\"" 191 | } 192 | 193 | install_pkg_from_list() { 194 | $INSTALLPKG --terse --root "$INSTALL" $1 195 | } 196 | 197 | 198 | download_index || exit 1 199 | 200 | # Install pkgtools outside the rootfs 201 | setup_pkgtools || exit 1 202 | 203 | # Download all packages 204 | export BASEURL LOCAL_REPO PKGLIST RELVER 205 | export -f download_pkg_to_list download_pkg 206 | 207 | touch "$PKGLIST" 208 | 209 | for pkg in $PKGS ; do 210 | echo $pkg 211 | done | xargs -n 1 -P $(nproc) -I {} bash -c 'download_pkg_to_list "$@"' _ {} 212 | 213 | # Install all packages in the rootfs 214 | for pkg in $(cat "$PKGLIST") ; do 215 | echo "Installing $pkg" 216 | install_pkg_from_list $pkg 217 | 218 | if [ "$?" != "0" ] ; then 219 | warn "Unable to install '$pkg'" 220 | exit 1 221 | fi 222 | done 223 | 224 | cp "$IMAGEDIR"/cgroups.sh "$INSTALL"/etc/rc.d/rc.vpsadminos.cgroups 225 | 226 | configure-common 227 | configure-append < /etc/resolv.conf 238 | 239 | /usr/sbin/update-ca-certificates --fresh 240 | 241 | # Setup slackpkg 242 | # This is to subdue warnings about using the current branch 243 | (. /etc/slackpkg/slackpkg.conf && touch \$WORKDIR/current) 244 | sed -i -r 's/^# (https:\/\/mirrors.slackware.com\/slackware\/slackware64-$RELVER\/)$/\1/' /etc/slackpkg/mirrors 245 | slackpkg -batch=on -default_answer=y update gpg 246 | slackpkg -batch=on -default_answer=y update 247 | slackpkg -batch=on -default_answer=y upgrade slackpkg 248 | slackpkg -batch=on -default_answer=y upgrade aaa_glibc-solibs 249 | 250 | # Use new configuration files, O as overwrite 251 | echo O | slackpkg -batch=on new-config 252 | 253 | # Reconfigure mirror 254 | sed -i -r 's/^# (https:\/\/mirrors.slackware.com\/slackware\/slackware64-$RELVER\/)$/\1/' /etc/slackpkg/mirrors 255 | 256 | slackpkg -batch=on -default_answer=y update 257 | slackpkg -batch=on -default_answer=y upgrade-all 258 | 259 | # Use new configuration files, O as overwrite 260 | echo O | slackpkg -batch=on new-config 261 | 262 | # Delete old configuration files 263 | find /etc -name "*.orig" -delete 264 | 265 | echo > /etc/fstab 266 | 267 | # Remote console 268 | sed -i '/^c1:/c\c1:12345:respawn:\/sbin\/agetty --noclear 38400 console linux' /etc/inittab 269 | sed -i -r 's/^(c[2-6]:)/#\1/g' /etc/inittab 270 | 271 | # Power 272 | sed -i 's|pf::powerfail:/sbin/genpowerfail start|pf::powerwait:/sbin/halt|' /etc/inittab 273 | 274 | # Configure SSH 275 | sed -i 's/^#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config 276 | 277 | # Mount /run 278 | sed -i \ 279 | 's|if \[ -d /run -a -z "\$container" \]; then|# Mount /run on vpsAdminOS\nif \[ -d /run \]; then|' \ 280 | /etc/rc.d/rc.S 281 | 282 | # Custom cgroup setup script 283 | sed -i \ 284 | '/^# Mount Control Groups filesystem interface:/a if \[ -x /etc/rc.d/rc.vpsadminos.cgroups \] ; then\n\ 285 | \/etc\/rc.d\/rc.vpsadminos.cgroups start\n\ 286 | fi\n' \ 287 | /etc/rc.d/rc.S 288 | chmod +x /etc/rc.d/rc.vpsadminos.cgroups 289 | 290 | # Custom network setup script 291 | sed -i '/^# Start networking daemons:$/i \ 292 | # Setup osctl network\n\ 293 | if \[ -x \/etc\/rc.d\/rc.venet \] ; then\n\ 294 | \/etc\/rc.d\/rc.venet start\n\ 295 | fi\n\ 296 | 297 | ' /etc/rc.d/rc.M 298 | 299 | cat < /etc/rc.d/rc.venet 300 | #!/bin/sh 301 | case "\\\$1" in 302 | start|stop) 303 | [ -f "/etc/rc.d/rc.venet.\\\$1" ] && . "/etc/rc.d/rc.venet.\\\$1" 304 | ;; 305 | restart) 306 | if [ -f /etc/rc.d/rc.venet.start ] && [ -f /etc/rc.d/rc.venet.stop ] ; then 307 | . /etc/rc.d/rc.venet.stop 308 | . /etc/rc.d/rc.venet.start 309 | fi 310 | ;; 311 | *) 312 | echo "Usage: \\\$0 start|stop|restart" 313 | ;; 314 | esac 315 | 316 | EOT 317 | 318 | chmod +x /etc/rc.d/rc.venet 319 | 320 | if [ ! -f /sbin/modprobe ] ; then 321 | cat < /sbin/modprobe 322 | #!/bin/sh 323 | # This is a /sbin/modprobe shim provided by vpsAdminOS. This system is expected 324 | # to run as a container, which cannot load its own modules. 325 | exit 0 326 | EOT 327 | chmod +x /sbin/modprobe 328 | fi 329 | 330 | # Enable Ctrl-left-arrow and Ctrl-right-arrow navigation in bash 331 | cat <> /etc/inputrc 332 | 333 | # mappings for Ctrl-left-arrow and Ctrl-right-arrow for word moving 334 | "\e[1;5C": forward-word 335 | "\e[1;5D": backward-word 336 | "\e[5C": forward-word 337 | "\e[5D": backward-word 338 | "\e\e[C": forward-word 339 | "\e\e[D": backward-word 340 | EOT 341 | 342 | usermod -L root 343 | echo > /etc/resolv.conf 344 | EOF 345 | run-configure 346 | -------------------------------------------------------------------------------- /images/slackware-current/cgroups.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | cgroup_mode() { 4 | if grep -x "^[[:digit:]]:cpuset:/" /proc/1/cgroup > /dev/null ; then 5 | echo "hybrid" 6 | else 7 | echo "unified" 8 | fi 9 | } 10 | 11 | cgroup_setup_hybrid() { 12 | echo "Mounting cgroups in a hybrid layout" 13 | 14 | local retval=0 15 | local name 16 | local hybrid_cgroups="blkio 17 | cpu,cpuacct 18 | cpuset 19 | devices 20 | freezer 21 | hugetlb 22 | memory 23 | net_cls,net_prio 24 | perf_event 25 | pids 26 | rdma" 27 | local hybrid_named="systemd" 28 | local mount_opts="nodev,noexec,nosuid" 29 | 30 | if ! mount -t tmpfs -o "$mount_opts" tmpfs /sys/fs/cgroup ; then 31 | echo "Unable to mount /sys/fs/cgroup" 32 | return 1 33 | fi 34 | 35 | for name in $hybrid_cgroups; do 36 | mkdir "/sys/fs/cgroup/$name" 37 | mount -n -t cgroup -o "$mount_opts,$name" \ 38 | cgroup "/sys/fs/cgroup/$name" || retval=1 39 | done 40 | 41 | for name in $hybrid_named; do 42 | mkdir "/sys/fs/cgroup/$name" 43 | mount -n -t cgroup -o "none,$mount_opts,name=$name" \ 44 | cgroup "/sys/fs/cgroup/$name" || retval=1 45 | done 46 | 47 | mkdir /sys/fs/cgroup/unified 48 | mount -n -t cgroup2 -o "$mount_opts" cgroup2 /sys/fs/cgroup/unified || retval=1 49 | 50 | ln -s systemd /sys/fs/cgroup/elogind 51 | mount -o remount,ro tmpfs /sys/fs/cgroup 52 | 53 | return $retval 54 | } 55 | 56 | cgroup_setup_unified() { 57 | echo "Mounting cgroups in a unified layout" 58 | 59 | mkdir /sys/fs/cgroup/init.scope 60 | echo 1 > /sys/fs/cgroup/init.scope/cgroup.procs 61 | } 62 | 63 | case "$(cgroup_mode)" in 64 | hybrid) cgroup_setup_hybrid ;; 65 | unified) cgroup_setup_unified ;; 66 | *) echo "Unknown cgroup mode" ;; 67 | esac 68 | -------------------------------------------------------------------------------- /images/slackware-current/config.sh: -------------------------------------------------------------------------------- 1 | BUILDER=fedora 2 | RELVER=current-$(date +%Y%m%d) 3 | -------------------------------------------------------------------------------- /images/ubuntu-16.04/build.sh: -------------------------------------------------------------------------------- 1 | . "$IMAGEDIR/config.sh" 2 | RELNAME=xenial 3 | BASEURL=http://cz.archive.ubuntu.com/ubuntu/ 4 | 5 | . $INCLUDE/debian.sh 6 | 7 | bootstrap 8 | configure-common 9 | 10 | cat > $INSTALL/etc/apt/sources.list < $INSTALL/etc/apt/sources.list < $INSTALL/etc/apt/sources.list < $INSTALL/etc/apt/sources.list < /dev/null ; then 3 | echo "hybrid" 4 | else 5 | echo "unified" 6 | fi 7 | } 8 | 9 | cgroup_setup_hybrid() { 10 | msg "Mounting cgroups in a hybrid layout" 11 | 12 | local retval=0 13 | local name 14 | local hybrid_cgroups="blkio 15 | cpu,cpuacct 16 | cpuset 17 | devices 18 | freezer 19 | hugetlb 20 | memory 21 | net_cls,net_prio 22 | perf_event 23 | pids 24 | rdma" 25 | local hybrid_named="systemd" 26 | local mount_opts="nodev,noexec,nosuid" 27 | 28 | if ! mount -t tmpfs -o "$mount_opts" tmpfs /sys/fs/cgroup ; then 29 | msg_warn "Unable to mount /sys/fs/cgroup" 30 | return 1 31 | fi 32 | 33 | for name in $hybrid_cgroups; do 34 | mkdir "/sys/fs/cgroup/$name" 35 | mount -n -t cgroup -o "$mount_opts,$name" \ 36 | cgroup "/sys/fs/cgroup/$name" || retval=1 37 | done 38 | 39 | for name in $hybrid_named; do 40 | mkdir "/sys/fs/cgroup/$name" 41 | mount -n -t cgroup -o "none,$mount_opts,name=$name" \ 42 | cgroup "/sys/fs/cgroup/$name" || retval=1 43 | done 44 | 45 | mkdir /sys/fs/cgroup/unified 46 | mount -n -t cgroup2 -o "$mount_opts" cgroup2 /sys/fs/cgroup/unified || retval=1 47 | 48 | mount -o remount,ro tmpfs /sys/fs/cgroup 49 | 50 | return $retval 51 | } 52 | 53 | cgroup_setup_unified() { 54 | msg "Mounting cgroups in a unified layout" 55 | 56 | mkdir /sys/fs/cgroup/init.scope 57 | echo 1 > /sys/fs/cgroup/init.scope/cgroup.procs 58 | } 59 | 60 | case "$(cgroup_mode)" in 61 | hybrid) cgroup_setup_hybrid ;; 62 | unified) cgroup_setup_unified ;; 63 | *) msg_warn "Unknown cgroup mode" ;; 64 | esac 65 | -------------------------------------------------------------------------------- /include/alpine.sh: -------------------------------------------------------------------------------- 1 | require_cmd git openssl wget 2 | 3 | readonly RELVER=${RELVER:=3.5} 4 | readonly ARCH=${ARCH:=x86_64} 5 | 6 | readonly DISTNAME='alpine' 7 | # Don't use https:// for this script, it doesn't work for an unknown reason. 8 | readonly BASEURL="http://dl-cdn.alpinelinux.org/alpine/v$RELVER" 9 | 10 | readonly APORTS_URI="git://git.alpinelinux.org/aports" 11 | readonly APORTS_DIR="$DOWNLOAD/aports" 12 | readonly APK="$DOWNLOAD/apk.static" 13 | readonly APK_KEYS_DIR="$DOWNLOAD/keys" 14 | readonly APK_KEYS_SHA256="\ 15 | 9c102bcc376af1498d549b77bdbfa815ae86faa1d2d82f040e616b18ef2df2d4 alpine-devel@lists.alpinelinux.org-4a6a0840.rsa.pub 16 | ebf31683b56410ecc4c00acd9f6e2839e237a3b62b5ae7ef686705c7ba0396a9 alpine-devel@lists.alpinelinux.org-5243ef4b.rsa.pub 17 | 1bb2a846c0ea4ca9d0e7862f970863857fc33c32f5506098c636a62a726a847b alpine-devel@lists.alpinelinux.org-524d27bb.rsa.pub 18 | 12f899e55a7691225603d6fb3324940fc51cd7f133e7ead788663c2b7eecb00c alpine-devel@lists.alpinelinux.org-5261cecb.rsa.pub 19 | 73867d92083f2f8ab899a26ccda7ef63dfaa0032a938620eda605558958a8041 alpine-devel@lists.alpinelinux.org-58199dcc.rsa.pub 20 | 9a4cd858d9710963848e6d5f555325dc199d1c952b01cf6e64da2c15deedbd97 alpine-devel@lists.alpinelinux.org-58cbb476.rsa.pub 21 | 780b3ed41786772cbc7b68136546fa3f897f28a23b30c72dde6225319c44cfff alpine-devel@lists.alpinelinux.org-58e4f17d.rsa.pub 22 | 59c01c57b446633249f67c04b115dd6787f4378f183dff2bbf65406df93f176d alpine-devel@lists.alpinelinux.org-5e69ca50.rsa.pub 23 | db0b49163f07ffba64a5ca198bcf1688610b0bd1f0d8d5afeaf78559d73f2278 alpine-devel@lists.alpinelinux.org-60ac2099.rsa.pub 24 | 207e4696d3c05f7cb05966aee557307151f1f00217af4143c1bcaf33b8df733f alpine-devel@lists.alpinelinux.org-6165ee59.rsa.pub 25 | 128d34d4aec39b0daedea8163cd8dc24dff36fd3d848630ab97eeb1d3084bbb3 alpine-devel@lists.alpinelinux.org-61666e3f.rsa.pub 26 | 10877cce0a935e46ad88cb79e174a2491680508eccda08e92bf04fb9bf37fbc1 alpine-devel@lists.alpinelinux.org-616a9724.rsa.pub 27 | 4a095a9daca86da496a3cd9adcd95ee2197fdbeb84638656d469f05a4d740751 alpine-devel@lists.alpinelinux.org-616abc23.rsa.pub 28 | 0caf5662fde45616d88cfd7021b7bda269a2fcaf311e51c48945a967a609ec0b alpine-devel@lists.alpinelinux.org-616ac3bc.rsa.pub 29 | ebe717d228555aa58133c202314a451f81e71f174781fd7ff8d8970d6cfa60da alpine-devel@lists.alpinelinux.org-616adfeb.rsa.pub 30 | d11f6b21c61b4274e182eb888883a8ba8acdbf820dcc7a6d82a7d9fc2fd2836d alpine-devel@lists.alpinelinux.org-616ae350.rsa.pub 31 | 40a216cbd163f22e5f16a9e0929de7cde221b9cbae8e36aa368b1e128afe0a31 alpine-devel@lists.alpinelinux.org-616db30d.rsa.pub" 32 | # 33 | readonly RC_SERVICES="\ 34 | mdev sysinit 35 | cgroups-mount boot 36 | bootmisc boot 37 | syslog boot 38 | networking default 39 | sshd default" 40 | 41 | readonly EXTRAPKGS='openssh' 42 | readonly TIMEZONE='Europe/Prague' 43 | 44 | 45 | die() { 46 | local retval=$1; shift 47 | printf 'ERROR: %s\n' "$@" 1>&2 48 | exit $retval 49 | } 50 | 51 | fetch() { 52 | if [ "${DEBUG:-}" = 'yes' ]; then 53 | wget -T 10 -O - $@ 54 | else 55 | wget -T 10 -O - -q $@ 56 | fi 57 | } 58 | 59 | fetch-apk-keys() { 60 | local line keyname 61 | 62 | git clone --depth 1 "$APORTS_URI" "$APORTS_DIR" || die 2 "Failed to clone aports" 63 | mkdir -p "$APK_KEYS_DIR" 64 | cd "$APK_KEYS_DIR" 65 | 66 | echo "$APK_KEYS_SHA256" | while read -r line; do 67 | keyname="${line##* }" 68 | cp -p "$APORTS_DIR/main/alpine-keys/$keyname" "$keyname" \ 69 | || die 2 'Failed to copy key' 70 | echo "$line" | sha256sum -c - \ 71 | || die 2 'Failed to fetch or verify APK keys' 72 | done 73 | 74 | cd - >/dev/null 75 | } 76 | 77 | fetch-apk-static() { 78 | local pkg_name='apk-tools-static' 79 | 80 | local pkg_ver=$(fetch "$BASEURL/main/$ARCH/APKINDEX.tar.gz" \ 81 | | tar -xzO APKINDEX \ 82 | | sed -n "/P:${pkg_name}/,/^$/ s/V:\(.*\)$/\1/p") 83 | 84 | [ -n "$pkg_ver" ] || die 2 "Cannot find a version of $pkg_name in APKINDEX" 85 | 86 | fetch "$BASEURL/main/$ARCH/${pkg_name}-${pkg_ver}.apk" \ 87 | | tar -xz -C "$(dirname "$APK")" --strip-components=1 sbin/ 88 | 89 | [ -f "$APK" ] || die 2 "$APK not found" 90 | 91 | local keyname=$(echo "$APK".*.pub | sed 's/.*\.SIGN\.RSA\.//') 92 | openssl dgst -sha1 \ 93 | -verify "$APK_KEYS_DIR/$keyname" \ 94 | -signature "$APK.SIGN.RSA.$keyname" \ 95 | "$APK" || die 2 "Signature verification for $(basename "$APK") failed" 96 | 97 | "$APK" --version || die 3 "$(basename "$APK") --version failed" 98 | } 99 | 100 | install-base() { 101 | cd "$INSTALL" 102 | 103 | mkdir -p etc/apk 104 | echo "$BASEURL/main" > etc/apk/repositories 105 | echo "$BASEURL/community" >> etc/apk/repositories 106 | cp /etc/resolv.conf etc/ 107 | 108 | $APK --arch="$ARCH" --root=. --keys-dir="$APK_KEYS_DIR" \ 109 | --update-cache --initdb add alpine-base \ 110 | || die 3 'Failed to install APK packages' 111 | 112 | cp "$IMAGEDIR"/cgroups-mount.initd etc/init.d/cgroups-mount 113 | chmod +x etc/init.d/cgroups-mount 114 | 115 | cd - >/dev/null 116 | } 117 | 118 | 119 | #============================= Main ==============================# 120 | 121 | echo '==> Fetching and verifying APK keys...' 122 | fetch-apk-keys 123 | 124 | echo '==> Fetching apk-tools static binary...' 125 | fetch-apk-static 126 | 127 | echo "==> Installing Alpine Linux in $INSTALL..." 128 | install-base 129 | 130 | echo '==> Configuring Alpine Linux...' 131 | configure-append <> /etc/inittab <<_EOF_ 146 | # vpsAdmin console 147 | ::respawn:/sbin/getty 38400 console 148 | _EOF_ 149 | 150 | echo tty0 >> /etc/securetty 151 | 152 | sed -i \ 153 | -e 's/^#*rc_logger=.*/rc_logger="YES"/' \ 154 | -e 's/^#*rc_sys=.*/rc_sys="lxc"/' \ 155 | -e 's/^#*rc_controller_cgroups=.*/rc_controller_cgroups="NO"/' \ 156 | /etc/rc.conf 157 | 158 | echo "$RC_SERVICES" | while read svcname runlevel; do 159 | rc-update add \$svcname \$runlevel 160 | done 161 | 162 | # vpsAdmin doesn't set SSH key in new containers, so we must permit root login 163 | # using password... 164 | sed -i \ 165 | -e 's/^#*PasswordAuthentication .*/PasswordAuthentication yes/' \ 166 | -e 's/^#*PermitRootLogin .*/PermitRootLogin yes/' \ 167 | /etc/ssh/sshd_config 168 | EOF 169 | 170 | run-configure 171 | -------------------------------------------------------------------------------- /include/common.sh: -------------------------------------------------------------------------------- 1 | function require_cmd { 2 | for cmd in $@ ; do 3 | command -v "$cmd" > /dev/null 4 | [ $? == 0 ] && continue 5 | 6 | echo "$cmd not found in PATH" 7 | exit 1 8 | done 9 | } 10 | 11 | function warn { 12 | >&2 echo "$@" 13 | } 14 | 15 | function fail { 16 | warn "$@" 17 | exit 1 18 | } 19 | 20 | function mount-chroot { 21 | mkdir -p "$1/proc" "$1/sys" "$1/dev" 22 | mount -t proc proc "$1/proc" 23 | mount -t sysfs sys "$1/sys" 24 | mount --rbind /dev "$1/dev" 25 | mount --make-rslave "$1/dev" 26 | } 27 | 28 | function umount-chroot { 29 | umount -R "$1/dev" 30 | umount "$1/sys" 31 | umount "$1/proc" 32 | } 33 | 34 | function do-chroot { 35 | mount-chroot "$1" 36 | chroot "$1" "$2" 37 | umount-chroot "$1" 38 | } 39 | 40 | function configure-shebang { 41 | local shebang="$1" 42 | 43 | if [ -f "$CONFIGURE" ] ; then 44 | echo "$shebang" > "$CONFIGURE.shebang" 45 | cat "$CONFIGURE" >> "$CONFIGURE.shebang" 46 | mv "$CONFIGURE.shebang" "$CONFIGURE" 47 | else 48 | echo "$shebang" > "$CONFIGURE" 49 | fi 50 | } 51 | 52 | function configure-append { 53 | cat >> $CONFIGURE 54 | } 55 | 56 | function configure-common { 57 | configure-append < $INSTALL/etc/resolv.conf 8 | debootstrap --include locales --arch amd64 $RELNAME $INSTALL $BASEURL 9 | } 10 | 11 | function configure-debian-append { 12 | cat >> "$CONFIGURE_DEBIAN" 13 | } 14 | 15 | function configure-debian { 16 | configure-shebang "#!/bin/bash" 17 | configure-append <> /etc/locale.gen 25 | 26 | locale-gen en_US.UTF-8 27 | dpkg-reconfigure locales 28 | 29 | # dpkg-reconfigure locales will not se the default system locale by itself 30 | echo LANG=en_US.UTF-8 >> /etc/default/locale 31 | 32 | PATH=/tmp/:\$PATH apt-get update 33 | PATH=/tmp/:\$PATH apt-get upgrade -y 34 | PATH=/tmp/:\$PATH apt-get install -y vim openssh-server ca-certificates man net-tools ifupdown less 35 | 36 | # for snapd 37 | PATH=/tmp/:\$PATH apt-get install -y fuse squashfuse 38 | mkdir /lib/modules 39 | 40 | for pkg in ureadahead eject ntpdate resolvconf ; do 41 | PATH=/tmp/:\$PATH apt-get purge -y $pkg 42 | done 43 | usermod -L root 44 | rm -f /etc/ssh/ssh_host_* 45 | 46 | cat > /etc/systemd/system/sshd-keygen.service <<"KEYGENSVC" 47 | [Unit] 48 | Description=OpenSSH Server Key Generation 49 | ConditionPathExistsGlob=!/etc/ssh/ssh_host_* 50 | Before=ssh.service 51 | 52 | [Service] 53 | Type=oneshot 54 | ExecStart=/usr/bin/ssh-keygen -A 55 | 56 | [Install] 57 | WantedBy=multi-user.target 58 | KEYGENSVC 59 | 60 | ln -s /etc/systemd/system/sshd-keygen.service /etc/systemd/system/multi-user.target.wants/sshd-keygen.service 61 | 62 | $([ -f "$CONFIGURE_DEBIAN" ] && cat "$CONFIGURE_DEBIAN") 63 | 64 | > /etc/resolv.conf 65 | rm -f /etc/hostname 66 | 67 | apt-get clean 68 | for f in \$fakefiles; do 69 | rm -f /tmp/\$f 70 | done 71 | 72 | sed -i 's/#DefaultTimeoutStartSec=90s/DefaultTimeoutStartSec=900s/' /etc/systemd/system.conf 73 | 74 | mkdir -p /var/log/journal 75 | 76 | systemctl mask journald-audit.socket 77 | systemctl mask systemd-journald-audit.socket 78 | systemctl mask sys-kernel-debug.mount 79 | 80 | mkdir -p /etc/systemd/system/systemd-udev-trigger.service.d 81 | cat < /etc/systemd/system/systemd-udev-trigger.service.d/vpsadminos.conf 82 | [Service] 83 | ExecStart= 84 | ExecStart=-udevadm trigger --subsystem-match=net --action=add 85 | EOT 86 | EOF 87 | } 88 | -------------------------------------------------------------------------------- /include/devuan.sh: -------------------------------------------------------------------------------- 1 | require_cmd debootstrap 2 | 3 | CONFIGURE_DEVUAN="$CONFIGURE.devuan" 4 | 5 | function bootstrap { 6 | mkdir $INSTALL/etc 7 | echo nameserver 8.8.8.8 > $INSTALL/etc/resolv.conf 8 | debootstrap --include locales --arch amd64 $RELNAME $INSTALL $BASEURL 9 | } 10 | 11 | function configure-devuan-append { 12 | cat >> "$CONFIGURE_DEVUAN" 13 | } 14 | 15 | function configure-devuan { 16 | configure-shebang "#!/bin/bash" 17 | configure-append <> /etc/locale.gen 25 | 26 | locale-gen en_US.UTF-8 27 | dpkg-reconfigure locales 28 | 29 | # dpkg-reconfigure locales will not se the default system locale by itself 30 | echo LANG=en_US.UTF-8 >> /etc/default/locale 31 | 32 | PATH=/tmp/:\$PATH apt-get update 33 | PATH=/tmp/:\$PATH apt-get upgrade -y 34 | PATH=/tmp/:\$PATH apt-get install -y vim openssh-server ca-certificates man net-tools ifupdown less 35 | 36 | # for snapd 37 | PATH=/tmp/:\$PATH apt-get install -y fuse squashfuse 38 | mkdir /lib/modules 39 | 40 | for pkg in ureadahead eject ntpdate resolvconf ; do 41 | PATH=/tmp/:\$PATH apt-get purge -y $pkg 42 | done 43 | usermod -L root 44 | rm -f /etc/ssh/ssh_host_* 45 | 46 | cat > /etc/init.d/generate_ssh_keys <<"GENSSH" 47 | #!/bin/sh 48 | 49 | ### BEGIN INIT INFO 50 | # Provides: host-ssh-keys 51 | # Required-Start: \$local_fs 52 | # Required-Stop: \$local_fs 53 | # Default-Start: S 54 | # Default-Stop: 55 | # Short-Description: Generate SSH host keys on first boot. 56 | ### END INIT INFO 57 | 58 | . /lib/lsb/init-functions 59 | 60 | set -e 61 | 62 | case "\$1" in 63 | start) 64 | log_begin_msg 'Generating SSH host keys' 65 | ssh-keygen -q -f /etc/ssh/ssh_host_rsa_key -t rsa -N '' 66 | ssh-keygen -q -f /etc/ssh/ssh_host_dsa_key -t dsa -N '' 67 | ssh-keygen -q -f /etc/ssh/ssh_host_ecdsa_key -t ecdsa -N '' 68 | ssh-keygen -q -f /etc/ssh/ssh_host_ed25519_key -t ed25519 -N '' 69 | update-rc.d generate_ssh_keys remove 70 | rm -f /etc/init.d/generate_ssh_keys 71 | log_end_msg \$? 72 | ;; 73 | *) 74 | log_failure_msg "operation '\$2' not supported" 75 | exit 1 76 | ;; 77 | esac 78 | 79 | exit 0 80 | GENSSH 81 | 82 | chmod a+x /etc/init.d/generate_ssh_keys 83 | update-rc.d generate_ssh_keys defaults 84 | 85 | sed -i 's|pf::powerwait:/etc/init.d/powerfail start|pf::powerwait:/sbin/halt|' /etc/inittab 86 | sed -ri 's/^([^#].*getty.*)$/#\1/' /etc/inittab 87 | 88 | cat >> /etc/inittab < /etc/resolv.conf 99 | rm -f /etc/hostname 100 | 101 | apt-get clean 102 | for f in \$fakefiles; do 103 | rm -f /tmp/\$f 104 | done 105 | EOF 106 | } 107 | -------------------------------------------------------------------------------- /include/gentoo.sh: -------------------------------------------------------------------------------- 1 | BASEURL=https://mirror.vpsfree.cz/gentoo 2 | 3 | require_cmd curl 4 | 5 | STAGE3_BASE_URL="${BASEURL}/releases/amd64/autobuilds" 6 | STAGE3_TARBALL_URL= 7 | STAGE3_TARBALL= 8 | 9 | fetch() { 10 | STAGE3_TARBALL_URL="${STAGE3_BASE_URL}/$(curl "${STAGE3_BASE_URL}/latest-stage3-amd64-${VARIANT}.txt" | grep -o -m 1 -P "^[\dTZ]+/stage3-amd64-${VARIANT}-[\dTZ]+.tar.xz")" 11 | STAGE3_TARBALL="$(basename $STAGE3_TARBALL_URL)" 12 | 13 | wget -P "$DOWNLOAD" ${STAGE3_TARBALL_URL}{.CONTENTS.gz,.DIGESTS,} 14 | 15 | if ! (cd "$DOWNLOAD"; sed -rn '/# SHA512/ {N;p}' "${STAGE3_TARBALL}".DIGESTS | sha512sum -c); 16 | then 17 | echo "Stage 3 checksum wrong! Quitting." 18 | exit 1 19 | fi 20 | } 21 | 22 | extract() { 23 | echo "Unpacking Stage3..." 24 | tar xJpf "${DOWNLOAD}/${STAGE3_TARBALL}" -C "$INSTALL" 25 | } 26 | 27 | configure-gentoo-begin() { 28 | cp /etc/resolv.conf "$INSTALL"/etc/ 29 | 30 | configure-append </etc/env.d/02locale 38 | echo 'GENTOO_MIRRORS="$BASEURL/ http://ftp.fi.muni.cz/pub/linux/gentoo/"' >> /etc/portage/make.conf 39 | echo "Europe/Prague" > /etc/timezone 40 | 41 | emerge-webrsync -v 42 | 43 | # Create a temporary make.conf 44 | cp -p /etc/portage/make.conf /etc/portage/make.conf.orig 45 | echo 'MAKEOPTS="-j$(nproc)"' >> /etc/portage/make.conf 46 | 47 | emerge --update --deep --newuse --with-bdeps=y --backtrack=120 @system @world 48 | emerge net-misc/dhcpcd sys-apps/iproute2 app-editors/vim 49 | EOF 50 | } 51 | 52 | configure-gentoo-end() { 53 | configure-append < /etc/resolv.conf 63 | 64 | rm -f /usr/portage/distfiles/* 65 | EOF 66 | } 67 | -------------------------------------------------------------------------------- /include/nixos.sh: -------------------------------------------------------------------------------- 1 | OS_BRANCH=staging 2 | 3 | function build-nixos { 4 | local vpsadminos= 5 | local nixpkgs= 6 | 7 | curl -L https://github.com/vpsfreecz/vpsadminos/archive/$OS_BRANCH.tar.gz \ 8 | | tar -xz \ 9 | || fail "unable to fetch vpsadminos" 10 | vpsadminos="$PWD/vpsadminos-$OS_BRANCH" 11 | 12 | curl -L https://nixos.org/channels/$CHANNEL/nixexprs.tar.xz \ 13 | | tar -xJ \ 14 | || fail "unable to fetch nixpkgs" 15 | nixpkgs=$(echo $PWD/nixos-*) 16 | 17 | export NIX_PATH="nixpkgs=$nixpkgs:vpsadminos=$vpsadminos" 18 | cd "$vpsadminos/os" 19 | make template || fail "failed to build the template" 20 | 21 | tar -xzf result/template/tarball/*.tar.gz -C "$INSTALL" 22 | } 23 | -------------------------------------------------------------------------------- /include/opensuse.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | require_cmd zypper 3 | 4 | if [ "$SPIN" == "leap" ]; then 5 | REPOSITORY=http://download.opensuse.org/distribution/leap/$SPINVER/repo/oss/ 6 | UPDATES=http://download.opensuse.org/update/leap/$SPINVER/oss/ 7 | elif [ "$SPIN" == "tumbleweed" ]; then 8 | REPOSITORY=http://download.opensuse.org/tumbleweed/repo/oss/ 9 | UPDATES=http://download.opensuse.org/update/tumbleweed/ 10 | else 11 | fail "unsupported spin" 12 | fi 13 | 14 | EXTRAPKGS='vim iproute2 iputils net-tools procps less psmisc timezone aaa_base-extras openssh curl ca-certificates ca-certificates-mozilla wicked' 15 | 16 | ZYPPER="zypper -v --root=$INSTALL --non-interactive --gpg-auto-import-keys " 17 | 18 | do_bootstrap() ( # new subshell 19 | set -e 20 | $ZYPPER addrepo --refresh -g $REPOSITORY openSUSE-oss 21 | $ZYPPER addrepo --refresh -g $UPDATES openSUSE-updates 22 | $ZYPPER refresh 23 | $ZYPPER install --no-recommends aaa_base shadow patterns-base-base patterns-base-sw_management $EXTRAPKGS 24 | ) 25 | 26 | function bootstrap { 27 | mount-chroot "$INSTALL" 28 | do_bootstrap 29 | rc=$? 30 | umount-chroot "$INSTALL" 31 | [ "$rc" != 0 ] && fail "bootstrap failed" 32 | } 33 | 34 | function configure-opensuse { 35 | configure-append < /etc/ssh/sshd_config.d/vpsadminos.conf 44 | PermitRootLogin yes 45 | PasswordAuthentication yes 46 | EOT 47 | fi 48 | 49 | systemctl mask systemd-modules-load.service 50 | echo console >> /etc/securetty 51 | sed -i 's/#DefaultTimeoutStartSec=90s/DefaultTimeoutStartSec=900s/' /etc/systemd/system.conf 52 | echo "%_netsharedpath /sys:/proc" >> /etc/rpm/macros.vpsadminos 53 | mkdir -p /var/log/journal 54 | 55 | mkdir -p /etc/systemd/system/systemd-udev-trigger.service.d 56 | cat < /etc/systemd/system/systemd-udev-trigger.service.d/vpsadminos.conf 57 | [Service] 58 | ExecStart= 59 | ExecStart=-udevadm trigger --subsystem-match=net --action=add 60 | EOT 61 | EOF 62 | } 63 | -------------------------------------------------------------------------------- /include/redhat-family.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | . $BASEDIR/include/common.sh 4 | 5 | if [ "$DISTNAME" == "fedora" ]; then 6 | require_cmd dnf 7 | 8 | YUM="dnf -c $DOWNLOAD/yum.conf --installroot=$INSTALL \ 9 | --disablerepo=* --enablerepo=install-$DISTNAME \ 10 | -y" 11 | YUM_GROUPINSTALL="$YUM group install" 12 | else 13 | require_cmd yum 14 | 15 | YUM="yum -c $DOWNLOAD/yum.conf --installroot=$INSTALL \ 16 | --disablerepo=* --enablerepo=install-$DISTNAME \ 17 | --enablerepo=install-$DISTNAME-updates -y" 18 | YUM_GROUPINSTALL="$YUM groupinstall" 19 | fi 20 | 21 | function bootstrap { 22 | mkdir -p ${INSTALL}/var/lib/rpm 23 | rpm --root $INSTALL --initdb 24 | 25 | nrpm=0 26 | for rpm in $RELEASE; do 27 | nrpm=$(( $nrpm + 1 )) 28 | echo "Downloading #${nrpm} $rpm" 29 | curl -o $DOWNLOAD/release${nrpm}.rpm $rpm || fail "unable to download $rpm" 30 | rpm --root $INSTALL --nodeps -ivh $DOWNLOAD/release${nrpm}.rpm \ 31 | || fail "unable to install $rpm" 32 | done 33 | 34 | cat > $DOWNLOAD/yum.conf << EOF 35 | [main] 36 | cachedir=$DOWNLOAD/var/cache/yum/\$basearch/\$releasever 37 | keepcache=0 38 | debuglevel=2 39 | logfile=$DOWNLOAD/var/log/yum.log 40 | exactarch=1 41 | obsoletes=1 42 | gpgcheck=1 43 | plugins=1 44 | installonly_limit=3 45 | 46 | [install-$DISTNAME] 47 | name=install-$DISTNAME 48 | enabled=1 49 | gpgcheck=0 50 | baseurl=$BASEURL 51 | 52 | [install-$DISTNAME-updates] 53 | name=install-$DISTNAME-updates 54 | enabled=1 55 | gpgcheck=0 56 | baseurl=$UPDATES 57 | EOF 58 | 59 | mkdir -p $DOWNLOAD/var/cache/yum 60 | mkdir -p $DOWNLOAD/var/log 61 | 62 | $YUM_GROUPINSTALL "$GROUPNAME" 63 | for rpm in $EXTRAPKGS; do 64 | $YUM install $rpm 65 | done 66 | 67 | for rpm in $REMOVEPKGS; do 68 | $YUM erase $rpm 69 | done 70 | $YUM clean all 71 | 72 | } 73 | 74 | function configure-redhat-common { 75 | configure-append < /etc/machine-id 85 | mkdir -p /var/log/journal 86 | systemctl mask var-lib-nfs-rpc_pipefs.mount 87 | systemctl mask rngd-wake-threshold.service 88 | systemctl mask systemd-journald-audit.socket 89 | 90 | mkdir -p /etc/systemd/system/systemd-udev-trigger.service.d 91 | cat < /etc/systemd/system/systemd-udev-trigger.service.d/vpsadminos.conf 92 | [Service] 93 | ExecStart= 94 | ExecStart=-udevadm trigger --subsystem-match=net --action=add 95 | EOT 96 | fi 97 | 98 | sed -i -e 's/^#PermitRootLogin\ prohibit-password/PermitRootLogin yes/g' /etc/ssh/sshd_config 99 | 100 | echo "%_netsharedpath /sys:/proc" >> /etc/rpm/macros.vpsadminos 101 | EOF 102 | } 103 | 104 | function configure-fedora { 105 | configure-append < /etc/resolv.conf 108 | dnf -y update 109 | dnf -y clean all 110 | > /etc/resolv.conf 111 | 112 | systemctl mask auditd.service 113 | systemctl mask systemd-journald-audit.socket 114 | systemctl mask proc-sys-fs-binfmt_misc.mount 115 | systemctl mask sys-kernel-debug.mount 116 | systemctl mask systemd-modules-load.service 117 | systemctl disable tcsd.service 118 | systemctl disable rdisc.service 119 | systemctl disable systemd-networkd.service 120 | systemctl disable systemd-resolved.service 121 | systemctl disable sssd.service 122 | systemctl enable sshd.service 123 | 124 | mkdir -p /etc/systemd/system/systemd-udev-trigger.service.d 125 | cat < /etc/systemd/system/systemd-udev-trigger.service.d/vpsadminos.conf 126 | [Service] 127 | ExecStart= 128 | ExecStart=-udevadm trigger --subsystem-match=net --action=add 129 | EOT 130 | 131 | sed -i -e 's/^#PermitRootLogin\ prohibit-password/PermitRootLogin yes/g' /etc/ssh/sshd_config 132 | EOF 133 | } 134 | 135 | function configure-fedora-nm-initscripts { 136 | configure-append < /etc/NetworkManager/conf.d/vpsadminos.conf 138 | [main] 139 | dns=none 140 | plugins+=ifcfg-rh 141 | rc-manager=file 142 | EOT 143 | EOF 144 | } 145 | 146 | function configure-fedora-nm-keyfiles { 147 | configure-append < /etc/NetworkManager/conf.d/vpsadminos.conf 149 | [main] 150 | dns=none 151 | rc-manager=file 152 | EOT 153 | EOF 154 | } 155 | 156 | function configure-rhel-8 { 157 | configure-append < /etc/NetworkManager/conf.d/vpsadminos.conf 166 | [main] 167 | dns=none 168 | plugins+=ifcfg-rh 169 | rc-manager=file 170 | EOT 171 | 172 | # TODO: This is a workaround for user@ services to hang on shutdown until 173 | # a two minute timeout is reached. It's enough to login as root over SSH and 174 | # reboot to trigger this issue. 175 | mkdir -p /etc/systemd/system/user@.service.d 176 | cat < /etc/systemd/system/user@.service.d/vpsadminos.conf 177 | [Service] 178 | TimeoutStopSec=15s 179 | EOT 180 | EOF 181 | } 182 | 183 | function configure-rhel-9 { 184 | configure-append < /etc/NetworkManager/conf.d/vpsadminos.conf 192 | [main] 193 | dns=none 194 | plugins+=ifcfg-rh 195 | rc-manager=file 196 | EOT 197 | EOF 198 | } 199 | -------------------------------------------------------------------------------- /include/void.sh: -------------------------------------------------------------------------------- 1 | require_cmd wget 2 | 3 | BASEURL=http://alpha.de.repo.voidlinux.org/live/current 4 | ROOTFS= 5 | 6 | fetch() { 7 | local name 8 | local rx 9 | 10 | if [ "$VARIANT" == "musl" ] ; then 11 | rx='void-x86_64-musl-ROOTFS-\d+.tar.xz' 12 | else 13 | rx='void-x86_64-ROOTFS-\d+.tar.xz' 14 | fi 15 | 16 | # Fetch checksums to find out latest release name 17 | wget -O - "$BASEURL/sha256sum.txt" | grep -P "$rx" > "$DOWNLOAD/sha256sum.txt" 18 | 19 | # Extract the name 20 | name=$(grep -o -P "$rx" "$DOWNLOAD/sha256sum.txt") 21 | 22 | # Download rootfs 23 | wget -P "$DOWNLOAD" "$BASEURL/$name" 24 | 25 | if ! (cd "$DOWNLOAD" ; sha256sum -c sha256sum.txt) ; then 26 | warn "Checksum does not match" 27 | exit 1 28 | fi 29 | 30 | ROOTFS="$DOWNLOAD/$name" 31 | } 32 | 33 | extract() { 34 | tar -xJf "$ROOTFS" -C "$INSTALL" 35 | } 36 | 37 | configure-void() { 38 | cp "$BASEDIR"/images/void/cgroups.sh "$INSTALL"/etc/runit/core-services/10-vpsadminos-cgroups.sh 39 | 40 | configure-append < /etc/resolv.conf 42 | xbps-install -Syu xbps 43 | xbps-install -Syu 44 | xbps-install -Syu 45 | xbps-install -Syu vim 46 | cp /etc/skel/.[^.]* /root/ 47 | usermod -s /bin/bash root 48 | usermod -L root 49 | sed -i 's/^#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config 50 | sed -i 's/^#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config 51 | ln -s /etc/sv/sshd /etc/runit/runsvdir/default/sshd 52 | rm -f /etc/runit/runsvdir/default/agetty-tty{1..6} 53 | rm -f /etc/runit/runsvdir/default/udevd 54 | ln -s /etc/sv/agetty-console /etc/runit/runsvdir/default/agetty-console 55 | echo > /etc/resolv.conf 56 | EOF 57 | } 58 | 59 | generate-void() { 60 | fetch 61 | extract 62 | configure-shebang "#!/bin/bash" 63 | configure-common 64 | configure-void 65 | run-configure 66 | } 67 | -------------------------------------------------------------------------------- /shell-test.nix: -------------------------------------------------------------------------------- 1 | # Used for test runs 2 | let 3 | pkgs = import {}; 4 | stdenv = pkgs.stdenv; 5 | 6 | in stdenv.mkDerivation rec { 7 | name = "vpsadminos-image-build-scripts"; 8 | 9 | buildInputs = with pkgs; [ 10 | netcat 11 | sshpass 12 | ]; 13 | 14 | # shellHook needs to be unset in case osctl-image is run from its own 15 | # nix-shell. osctl-image sets up ruby and bundler in its shellHook, it is 16 | # inherited by nested nix-shells and breaks them. 17 | shellHook = ""; 18 | } 19 | -------------------------------------------------------------------------------- /tests/dns_resolver.sh: -------------------------------------------------------------------------------- 1 | function can_set { 2 | local ns=$@ 3 | osctl ct set dns-resolver $CTID $ns 4 | } 5 | 6 | function has_nameserver { 7 | local ns="$1" 8 | osctl ct exec $CTID cat /etc/resolv.conf | grep -qx "nameserver $ns" 9 | if [ "$?" != "0" ] ; then 10 | echo "nameserver '$ns' not found in /etc/resolv.conf" 11 | return 1 12 | fi 13 | } 14 | 15 | function has_not_nameserver { 16 | local ns="$1" 17 | osctl ct exec $CTID cat /etc/resolv.conf | grep -qx "nameserver $ns" 18 | if [ "$?" == "0" ] ; then 19 | echo "nameserver '$ns' found in /etc/resolv.conf" 20 | return 1 21 | fi 22 | } 23 | 24 | if [ "$DISTNAME" == "nixos" ] ; then 25 | # DNS resolvers on NixOS cannot be changed from the outside using osctl 26 | exit 0 27 | fi 28 | 29 | osctl ct stop $CTID 30 | can_set "1.1.1.1" || fail "unable to set dns resolvers when stopped" 31 | osctl ct start $CTID 32 | has_nameserver "1.1.1.1" || fail "dns resolver isn't set after start" 33 | sleep 30 # make sure that nothing from inside the vps will override it 34 | has_nameserver "1.1.1.1" || fail "dns resolver lost after start" 35 | 36 | can_set "8.8.8.8" || fail "unable to set dns resolver when started" 37 | has_nameserver "8.8.8.8" || fail "dns resolver isn't set at runtime" 38 | has_not_nameserver "1.1.1.1" || fail "replaced dns resolver wasn't removed" 39 | osctl ct restart $CTID || fail "unable to restart" 40 | has_nameserver "8.8.8.8" || fail "dns resolvers aren't persisted" 41 | 42 | can_set 1.1.1.1 8.8.8.8 || fail "unable to set multiple dns resolvers" 43 | has_nameserver "1.1.1.1" || fail "dns resolver 1.1.1.1 not found" 44 | has_nameserver "8.8.8.8" || fail "dns resolver 8.8.8.8 not found" 45 | -------------------------------------------------------------------------------- /tests/hostname.sh: -------------------------------------------------------------------------------- 1 | function can_set { 2 | local hostname="$1" 3 | osctl ct set hostname $CTID "$hostname" 4 | } 5 | 6 | function hostname_is { 7 | local hostname="$1" 8 | local real="$(osctl ct exec $CTID hostname)" 9 | if [ "$hostname" != "$real" ] ; then 10 | echo "hostname mismatch: expected '$hostname', is '$real'" 11 | return 1 12 | fi 13 | } 14 | 15 | if [ "$DISTNAME" == "nixos" ] ; then 16 | # Hostname on NixOS cannot be changed from the outside using osctl 17 | exit 0 18 | fi 19 | 20 | osctl ct stop $CTID 21 | can_set "superhost" || fail "unable to set hostname when stopped" 22 | osctl ct start $CTID 23 | hostname_is "superhost" || fail "hostname isn't set after start" 24 | can_set "megahost" || fail "unable to set hostname when started" 25 | hostname_is "megahost" || fail "hostname isn't set at runtime" 26 | osctl ct restart $CTID || fail "unable to restart" 27 | hostname_is "megahost" || fail "hostname isn't persisted" 28 | -------------------------------------------------------------------------------- /tests/packages.sh: -------------------------------------------------------------------------------- 1 | function check_package_list { 2 | local ret=`osctl ct exec -r $CTID $@` 3 | [ "$?" != 0 ] && fail "unable to get package list" 4 | [ "$ret" == "" ] && fail "empty package list" 5 | return 0 6 | } 7 | 8 | case "$DISTNAME" in 9 | almalinux|centos|fedora|rocky) 10 | check_package_list rpm -qa 11 | ;; 12 | alpine) 13 | check_package_list apk list --installed 14 | ;; 15 | arch) 16 | check_package_list pacman -Q 17 | ;; 18 | debian|devuan|ubuntu) 19 | check_package_list dpkg-query --list 20 | ;; 21 | opensuse) 22 | check_package_list rpm -qa 23 | ;; 24 | void) 25 | check_package_list xbps-query -l 26 | ;; 27 | *) 28 | echo "No package test for ${DISTNAME}-${RELVER}" 29 | ;; 30 | esac 31 | -------------------------------------------------------------------------------- /tests/passwd_started.sh: -------------------------------------------------------------------------------- 1 | osctl ct start $CTID || fail "unable to start container" 2 | 3 | # On NixOS, we have to wait a bit for the start menu to pass, because 4 | # we need the initial system activation to take place before the password 5 | # can be set. 6 | [ "$DISTNAME" == "nixos" ] && sleep 10 7 | 8 | osctl ct passwd $CTID root suCHS3crET || fail "unable to set password" 9 | -------------------------------------------------------------------------------- /tests/passwd_stopped.sh: -------------------------------------------------------------------------------- 1 | # NixOS does not have /etc until the first start 2 | if [ "$DISTNAME" == "nixos" ] ; then 3 | osctl ct start $CTID || fail "unable to start" 4 | sleep 10 5 | osctl ct stop $CTID || fail "unable to stop" 6 | fi 7 | osctl ct passwd $CTID root suCHS3crET || fail "unable to set password" 8 | -------------------------------------------------------------------------------- /tests/ssh_key.sh: -------------------------------------------------------------------------------- 1 | IPADDR="$OSCTL_IMAGE_TEST_IPV4_ADDRESS" 2 | PRIVATE_KEY="-----BEGIN OPENSSH PRIVATE KEY----- 3 | b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAaAAAABNlY2RzYS 4 | 1zaGEyLW5pc3RwMjU2AAAACG5pc3RwMjU2AAAAQQQLZ1lnTtm8gtZwEVZv/vdALqVOTPFh 5 | NxfhZ/Oc6FtN9DNprhyhLfjeJruj+CgM3WG7MUsafrofHkNobNK6bwhCAAAAqG6w9rNusP 6 | azAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBAtnWWdO2byC1nAR 7 | Vm/+90AupU5M8WE3F+Fn85zoW030M2muHKEt+N4mu6P4KAzdYbsxSxp+uh8eQ2hs0rpvCE 8 | IAAAAhALZTz6hRZCvnFXdUEhV9wICapfciz/MGy7Ohx3uRPYuiAAAADGFpdGhlckBvcmlv 9 | bgECAw== 10 | -----END OPENSSH PRIVATE KEY-----" 11 | PUBLIC_KEY="ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBAtnWWdO2byC1nARVm/+90AupU5M8WE3F+Fn85zoW030M2muHKEt+N4mu6P4KAzdYbsxSxp+uh8eQ2hs0rpvCEI= template@test" 12 | 13 | function test_network { 14 | ping -c 1 $IPADDR > /dev/null 2>&1 15 | } 16 | 17 | function install_script { 18 | cat < /root/.ssh/authorized_keys 22 | EOF 23 | } 24 | 25 | function install_key { 26 | osctl ct runscript $CTID <(install_script) 27 | } 28 | 29 | function reject_nokey { 30 | ssh -o StrictHostKeyChecking=no \ 31 | -o UserKnownHostsFile=/dev/null \ 32 | -o BatchMode=yes \ 33 | root@$IPADDR hostname 34 | [ $? != 0 ] 35 | } 36 | 37 | function accept_key { 38 | local identity=$(mktemp) 39 | local rc= 40 | 41 | echo "$PRIVATE_KEY" > "$identity" 42 | ssh -o StrictHostKeyChecking=no \ 43 | -o UserKnownHostsFile=/dev/null \ 44 | -o BatchMode=yes \ 45 | -i "$identity" \ 46 | root@$IPADDR hostname 47 | rc=$? 48 | rm -f "$identity" 49 | return $rc 50 | } 51 | 52 | function test_ssh { 53 | install_key || fail "failed to install public key" 54 | reject_nokey || fail "accepted invalid key" 55 | accept_key || fail "rejected valid key" 56 | } 57 | 58 | function wait_for_ssh { 59 | for k in {1..30} ; do 60 | nc -z $IPADDR 22 && return 61 | sleep 1 62 | done 63 | 64 | return 1 65 | } 66 | 67 | function wait_for_network { 68 | for i in {1..60} ; do 69 | test_network && return 70 | sleep 1 71 | done 72 | 73 | return 1 74 | } 75 | 76 | osctl ct netif new routed $CTID eth0 || fail "unable to add netif" 77 | osctl ct netif ip add $CTID eth0 $IPADDR/32 || fail "unable to add ip" 78 | osctl ct start $CTID || fail "unable to start" 79 | 80 | wait_for_network || fail "network unreachable" 81 | wait_for_ssh || fail "ssh not responding" 82 | test_ssh 83 | -------------------------------------------------------------------------------- /tests/ssh_password.sh: -------------------------------------------------------------------------------- 1 | IPADDR="$OSCTL_IMAGE_TEST_IPV4_ADDRESS" 2 | PASSWORD=suCHS3crET 3 | 4 | function test_network { 5 | ping -c 1 $IPADDR > /dev/null 2>&1 6 | } 7 | 8 | function try_password { 9 | local pass="$1" 10 | sshpass \ 11 | -p "$pass" \ 12 | ssh -o StrictHostKeyChecking=no \ 13 | -o UserKnownHostsFile=/dev/null \ 14 | -o PubkeyAuthentication=no \ 15 | root@$IPADDR hostname 16 | } 17 | 18 | function test_ssh { 19 | try_password notreally && fail "accepted unset password" 20 | try_password "" && fail "accepted empty password" 21 | osctl ct passwd $CTID root $PASSWORD || fail "unable to set password" 22 | try_password justno && fail "accepted invalid password" 23 | try_password $PASSWORD || fail "rejected valid password" 24 | } 25 | 26 | function wait_for_ssh { 27 | for k in {1..30} ; do 28 | nc -z $IPADDR 22 && return 29 | sleep 1 30 | done 31 | 32 | return 1 33 | } 34 | 35 | function wait_for_network { 36 | for i in {1..60} ; do 37 | test_network && return 38 | sleep 1 39 | done 40 | 41 | return 1 42 | } 43 | 44 | osctl ct netif new routed $CTID eth0 || fail "unable to add netif" 45 | osctl ct netif ip add $CTID eth0 $IPADDR/32 || fail "unable to add ip" 46 | osctl ct start $CTID || fail "unable to start" 47 | 48 | wait_for_network || fail "network unreachable" 49 | wait_for_ssh || fail "ssh not responding" 50 | test_ssh 51 | -------------------------------------------------------------------------------- /tests/start.sh: -------------------------------------------------------------------------------- 1 | osctl ct start $CTID || fail "unable to start" 2 | -------------------------------------------------------------------------------- /tests/stop.sh: -------------------------------------------------------------------------------- 1 | osctl ct start $CTID || fail "unable to start container" 2 | 3 | # Give the system some time to complete boot 4 | if [ "$DISTNAME" == "debian" ] && [ "$RELVER" == "8" ] ; then 5 | sleep 30 6 | else 7 | sleep 10 8 | fi 9 | 10 | osctl ct stop --dont-kill $CTID || fail "unable to stop container" 11 | -------------------------------------------------------------------------------- /tests/veth_bridge.sh: -------------------------------------------------------------------------------- 1 | function test_network { 2 | # We assume that the bridge is setup in OS configuration using 3 | # 4 | # networking.lxcbr = true; 5 | # networking.dhcpd = true; 6 | # 7 | local ip=$(osctl ct exec $CTID ip route get 192.168.1.1 | awk -F"src " 'NR==1{split($2,a," ");print a[1]}') 8 | local rc=$? 9 | [ $rc != 0 ] && return $rc 10 | 11 | ping -c 1 $ip > /dev/null 2>&1 12 | } 13 | 14 | osctl ct netif new bridge --link lxcbr0 $CTID eth0 || fail "unable to add netif" 15 | osctl ct start $CTID || fail "unable to start container" 16 | 17 | for i in {1..60} ; do 18 | test_network && exit 0 19 | sleep 1 20 | done 21 | 22 | exit 1 23 | -------------------------------------------------------------------------------- /tests/veth_routed.sh: -------------------------------------------------------------------------------- 1 | IPADDR="$OSCTL_IMAGE_TEST_IPV4_ADDRESS" 2 | function test_network { 3 | ping -c 1 $IPADDR > /dev/null 2>&1 4 | } 5 | 6 | osctl ct netif new routed $CTID eth0 || fail "unable to add netif" 7 | osctl ct netif ip add $CTID eth0 $IPADDR/32 || fail "unable to add ip" 8 | osctl ct start $CTID || fail "unable to start" 9 | 10 | for i in {1..60} ; do 11 | test_network && exit 0 12 | sleep 1 13 | done 14 | 15 | exit 1 16 | --------------------------------------------------------------------------------