From 68f39098fd648c988394b28cab15e569dfe4dd49 Mon Sep 17 00:00:00 2001 From: Dhya Date: Thu, 17 Oct 2024 15:04:16 -0700 Subject: [PATCH] fix initial commit --- kvm/get-kvm-link-local | 22 +++++++ kvm/kvm-setup | 55 +++++++++++++++++ kvm/kvm-setup-from-img | 51 ++++++++++++++++ kvm/vclone | 32 ++++++++++ mmdebstrap/mmdebstrap-deb12 | 119 ++++++++++++++++++++++++++++++++++++ 5 files changed, 279 insertions(+) create mode 100755 kvm/get-kvm-link-local create mode 100755 kvm/kvm-setup create mode 100755 kvm/kvm-setup-from-img create mode 100755 kvm/vclone create mode 100755 mmdebstrap/mmdebstrap-deb12 diff --git a/kvm/get-kvm-link-local b/kvm/get-kvm-link-local new file mode 100755 index 0000000..0017b0f --- /dev/null +++ b/kvm/get-kvm-link-local @@ -0,0 +1,22 @@ +#!/bin/bash + +if [[ $# -ne 1 ]]; then + echo "USAGE: $0 " + exit 0 +else + domain="$1" +fi + +if [[ ! -e /etc/libvirt/qemu/${domain}.xml ]]; then + echo "Error: ${domain} configuration not found on this system" + exit 1 +fi + +macAddress=$(sudo grep -o -E '([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}' /etc/libvirt/qemu/${domain}.xml) +# courtesy of https://stackoverflow.com/a/48378567 +printf "%02x%s" $(( 16#${macAddress:0:2} ^ 2#00000010 )) "${macAddress:2}" \ + | sed -E -e 's/([0-9a-zA-Z]{2})*/0x\0|/g' \ + | tr -d ':\n' \ + | xargs -d '|' \ + printf "fe80::%02x%02x:%02xff:fe%02x:%02x%02x\n" + diff --git a/kvm/kvm-setup b/kvm/kvm-setup new file mode 100755 index 0000000..a743bb5 --- /dev/null +++ b/kvm/kvm-setup @@ -0,0 +1,55 @@ +#!/bin/bash + +# Some notes: +# +# Prior to running this script it is recommended to update the osinfo-db: +# git clone https://gitlab.com/libosinfo/osinfo-db.git +# apt install gettext osinfo-db-tools libosinfo-bin +# cd osinfo-db +# make && make install +# osinfo-query os +# +# Some ISO images are not in the osinfo-db and therefore require initrd= and kernel= arguments provided to --location, for example: +# --location $isoImage,initrd=install.amd/initrd.gz,kernel=install.amd/vmlinuz +# +# To find them in the ISO image use: +# isoinfo -J -i -l | grep -e '(initrd|vmlinuz)' +# and: +# isoinfo -J -i -l | less +# to find what directory they are in. `isoinfo` is provided by the `genisoimage` package. +# +# The --boot line below selects UEFI non-secure-boot and requires `ovmf` to be installed +# +# The --extra-args allows console access to the installation +# +# This script assumes you have a bridge named 'br0'. Otherwise you might want to use: +# --network network:default + + +machineName="rock9-base" +isoImage="/mnt/e/Downloads/ISO/Rocky-9.4-x86_64-dvd.iso" +machineMemory=2 # in GB +diskSize=20 +cpuNumber=2 +# run `osinfo-query os` to get the name of the OS variant +osVariant="rocky9" + +#--location $isoImage,initrd=install.amd/initrd.gz,kernel=install.amd/vmlinuz \ + +virt-install \ +--connect qemu:///system \ +--virt-type kvm \ +--name "$machineName" \ +--hvm \ +--memory $(( $machineMemory * 1024 )) \ +--boot loader=/usr/share/OVMF/OVMF_CODE.fd,loader.readonly=yes,loader.type=pflash,nvram.template=/usr/share/OVMF/OVMF_VARS.fd,loader_secure=no \ +--disk size="$diskSize",bus=virtio,format=qcow2 \ +--location $isoImage \ +--vcpus $cpuNumber \ +--cpu host \ +--osinfo detect=on \ +--os-variant "$osVariant" \ +--network bridge=br1 \ +--graphics none \ +--console pty,target_type=serial \ +--extra-args 'console=ttyS0,115200n8 --- console=ttyS0,115200n8' diff --git a/kvm/kvm-setup-from-img b/kvm/kvm-setup-from-img new file mode 100755 index 0000000..07e53c2 --- /dev/null +++ b/kvm/kvm-setup-from-img @@ -0,0 +1,51 @@ +#!/bin/bash + +# Some notes: +# +# Prior to running this script it is recommended to update the osinfo-db: +# git clone https://gitlab.com/libosinfo/osinfo-db.git +# apt install gettext osinfo-db-tools libosinfo-bin +# cd osinfo-db +# make && make install +# osinfo-query os +# +# Some ISO images are not in the osinfo-db and therefore require initrd= and kernel= arguments provided to --location, for example: +# --location $isoImage,initrd=install.amd/initrd.gz,kernel=install.amd/vmlinuz +# +# To find them in the ISO image use: +# isoinfo -J -i -l | grep -e '(initrd|vmlinuz)' +# and: +# isoinfo -J -i -l | less +# to find what directory they are in. `isoinfo` is provided by the `genisoimage` package. +# +# The --boot line below selects UEFI non-secure-boot and requires `ovmf` to be installed +# +# The --extra-args allows console access to the installation +# +# This script assumes you have a bridge named 'br0'. Otherwise you might want to use: +# --network network:default + + +machineName="deb12-gencld" +diskImage="/mnt/e-lin/Downloads/ISO/debian-12-genericcloud-amd64.qcow2" +machineMemory=2 # in GB +cpuNumber=2 +# run `osinfo-query os` to get the name of the OS variant +osVariant="debian12" + +virt-install \ +--connect qemu:///system \ +--virt-type kvm \ +--name "$machineName" \ +--hvm \ +--memory $(( $machineMemory * 1024 )) \ +--boot loader=/usr/share/OVMF/OVMF_CODE.fd,loader.readonly=yes,loader.type=pflash,nvram.template=/usr/share/OVMF/OVMF_VARS.fd,loader_secure=no \ +--disk ${diskImage},bus=virtio,format=qcow2 \ +--import \ +--vcpus $cpuNumber \ +--cpu host \ +--os-variant "$osVariant" \ +--network bridge=br1 \ +--graphics none \ +--console pty,target_type=serial \ +#--extra-args 'console=ttyS0,115200n8 --- console=ttyS0,115200n8' diff --git a/kvm/vclone b/kvm/vclone new file mode 100755 index 0000000..d12584e --- /dev/null +++ b/kvm/vclone @@ -0,0 +1,32 @@ +#!/bin/bash + +if [[ $# -ne 2 ]]; then + echo "USAGE: $0 " + exit 0 +else + orig="$1" + dest="$2" +fi + +sudo virt-clone --original "${orig}" --name "${dest}" --auto-clone + +sudo virt-sysprep \ + -d "${dest}" \ + --operations defaults,-ssh-userdir \ + --hostname "${dest}" \ + --edit /etc/hosts:"s/${orig}/${dest}/" \ + --edit /etc/hostname:"s/${orig}/${dest}/" \ + --edit /etc/motd:"s/${orig}/${dest}/" \ + --firstboot-command 'dpkg-reconfigure openssh-server' \ + --firstboot-command 'systemctl restart sshd' + +getLinkLocalAddress() { + local macAddress=$(sudo grep -o -E '([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}' /etc/libvirt/qemu/${dest}.xml) + printf "%02x%s" $(( 16#${macAddress:0:2} ^ 2#00000010 )) "${macAddress:2}" \ + | sed -E -e 's/([0-9a-zA-Z]{2})*/0x\0|/g' \ + | tr -d ':\n' \ + | xargs -d '|' \ + printf "fe80::%02x%02x:%02xff:fe%02x:%02x%02x" +} + +printf "The link-local IP address of %s is:\n %s\n" "${dest}" "$(getLinkLocalAddress)" diff --git a/mmdebstrap/mmdebstrap-deb12 b/mmdebstrap/mmdebstrap-deb12 new file mode 100755 index 0000000..fe4f640 --- /dev/null +++ b/mmdebstrap/mmdebstrap-deb12 @@ -0,0 +1,119 @@ +#!/bin/bash -e +# +# This script creates an mmdebstrap .tar and imports it into systemd-nspawn +# where it can be managed by machinectl +# +# This script configures the container in multiple ways: +# 1. Installs system very similar to Debian genericcloud build including +# cloud tools and cloud variant Linux kernel. +# 2. Installs and configures sudo with NOPASSWD enabled for suoders +# 3. Installs public SSH keys to user and root for pre-shared auth out- +# of-the-box +# 4. Installs netplan.io (which is also used with Debian genericcloud +# and configures it to bring the link-local interface up only +# 5. Purges multiple packages that are not part of Debian genericcloud +# 6. Configures /etc/hosts, /etc/hostname, and /etc/motd with the +# container name +# 7. Sets the container locale to `en_US.UTF-8 UTF-8` +# 8. Imports the container into machined +# +# With systemd-contianer connecting to the container should be as easy +# as `ssh ` +# systemd-container takes care of creating a virtual ethernet interface +# shared between the host and the container, and libnss-mymachines +# handles the name resolution for containers +# +# Start the container: +# sudo machinectl start +# +# Access the container: +# ssh +# - or - +# machinectl login +# - or - +# machinectl shell +# +# If you want to ssh in to the container as root edit /etc/ssh/sshd_config +# on the container and use: +# PermitRootLogin yes +# + +if [[ $# -ne 1 ]]; then + echo "USAGE: $0 " + exit 0 +else + containerName="$1" +fi + +user="dhya" +pass="" +groups="adm,staff,sudo" + +sources_list="# For information about how to configure apt package sources, +# see the sources.list(5) manual. + +deb http://deb.debian.org/debian/ bookworm main contrib +deb-src http://deb.debian.org/debian/ bookworm main contrib + +deb http://deb.debian.org/debian/ bookworm-proposed-updates main contrib +deb-src http://deb.debian.org/debian/ bookworm-proposed-updates main contrib + +deb http://deb.debian.org/debian/ bookworm-updates main contrib +deb-src http://deb.debian.org/debian/ bookworm-updates main contrib + +deb http://security.debian.org/debian-security bookworm-security main contrib +deb-src http://security.debian.org/debian-security bookworm-security main contrib" + +netplanConf=$(cat << 'EOF' +network: + version: 2 + ethernets: + enp1s0: + link-local: [ ipv6 ] +EOF +) + +motdText="\n\t${containerName}\n" + +# Apt proxy to use for mmdebstrap build +aptProxy='Acquire::http { Proxy "http://192.168.0.35:3142"; }' +# Apt proxy to configure in container +aptProxyConf='Acquire::http::Proxy::deb.debian.org \"http://192.168.0.35:3142/\";' + +# User public SSH key for pre-shared auth with container +user_ssh_key="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFaTibSQqYaaBk86kbjI6GCtq0Et6j3yrhVRdIaKhSTO dhya@fusion" + +# Root public SSH key for pre-shared auth with container +root_ssh_key="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINAooLnlfGBOOfWtGD5kf4fAgHnUcNM5Fjcq6V7bUJoX root@fusion" + +# Note: $ needs to be escaped, e.g. Perl capture group reference $1 +# machinectl requires systemd and dbus (dbus-broker) in the container +mmdebstrap \ + --aptopt=''"${aptProxy}"'' \ + --aptopt='Apt::Install-Recommends "false"' \ + --include=dbus-broker,systemd-container,linux-image-cloud-amd64,locales,netplan.io,sudo \ + --customize-hook='chroot "$1" apt -y purge linux-image-amd64 ifupdown nano vim-tiny vim-common firmware-linux-free busybox console-setup console-setup-linux cron cron-daemon-common dbus-user-session debconf-i18n dictionaries-common discover discover-data dmidecode efibootmgr emacsen-common firmware-linux-free iamerican ibritish ienglish-common intel-microcode isc-dhcp-common ispell iucode-tool laptop-detect logrotate shared-mime-info task-english tasksel tasksel-data usbutils util-linux-locales wamerican xdg-user-dirs xkb-data' \ + --customize-hook='echo '"${containerName}"' > "$1/etc/hostname"' \ + --customize-hook='printf "127.0.0.1\tlocalhost\n127.0.1.1\t'"${containerName}"'\n\n::1\tlocalhost ip6-localhost ip6-loopback\nff02::1\tip6-allnodes\nff02::2\tip6-allrouters" > "$1/etc/hosts"' \ + --customize-hook='printf "'"${netplanConf}"'" > "$1/etc/netplan/50-cloud-init.yaml"' \ + --customize-hook='printf "'"${sources_list}"'" > "$1/etc/apt/sources.list"' \ + --customize-hook='printf "'"${aptProxyConf}"'" > "$1/etc/apt/apt.conf.d/02proxy"' \ + --customize-hook='printf "'"${motdText}"'" > "$1/etc/motd"' \ + --customize-hook='echo '"en_US.UTF-8 UTF-8"' >> "$1/etc/locale.gen"' \ + --customize-hook='chroot "$1" useradd -s /bin/bash -m -G '"${groups}"' '"${user}"'' \ + --customize-hook='printf "'"${root_ssh_key}"'" > "$1/root/.ssh/authorized_keys"' \ + --customize-hook='echo '"${user}":"${pass}"' | chroot "$1" chpasswd' \ + --customize-hook='mkdir "$1/home/'"${user}"'/.ssh"' \ + --customize-hook='printf "'"${user_ssh_key}"'" > "$1/home/'"${user}"'/.ssh/authorized_keys"' \ + --customize-hook='chown -R '"${user}"':'"${user}"' "$1/home/'"${user}"'/.ssh"' \ + --customize-hook='perl -pi -e "s/(^%sudo\s+ALL=\(ALL:ALL\)\s+)ALL/\$1NOPASSWD:ALL/" "$1/etc/sudoers"' \ + --customize-hook='chroot "$1" apt --no-install-recommends -y install vim openssh-server python3 cloud-guest-utils cloud-image-utils cloud-init cloud-initramfs-growroot cloud-utils distro-info-data rsync' \ + --customize-hook='chroot "$1" rm -rf /etc/network' \ + --customize-hook='chroot "$1" locale-gen' \ + bookworm ${containerName}.tar + +printf "\nFinished creating ${containerName} container: ${containerName}.tar\n" +sudo machinectl import-tar ${containerName}.tar ${containerName} +printf "\nFinished importing ${containerName}.tar\n" +printf "It can be started with:\n\$ sudo machinectl start $containerName\n" +