#!/usr/bin/enc bash
set -e
set -o pipefail

# Every server should be as basic as possible and use unprivileged incus
# containers to run services.

sudo apt install -y \
  incus \
  incus-tools \
  incus-client \
  incus-agent \
  dnsmasq-base

# https://linuxcontainers.org/incus/docs/main/howto/network_bridge_firewalld/#prevent-connectivity-issues-with-incus-and-docker

sudo lshw -short -c disk

# modify the default lxc profile to set the timezone in the containers automatically. To do this you enter the following.
# TIMEZONE='Region/City'
TIMEZONE='Europe/London'
incus profile set default environment.TZ ${TIMEZONE}

# Add current user to admin for incus
sudo newgrp incus-admin
sudo usermod -aG incus-admin ${USERNAME}

# trimming support on all newly created pools on ZFS 0.8 or later. 
# This increases the lifetime of SSDs by allowing better block re-use by the 
# controller, and it also allows to free space on the root file system when 
# using a loop-backed ZFS pool.
ZPOOL_NAME='rpool'
zpool upgrade ${ZPOOL_NAME}
zpool set autotrim=on ${ZPOOL_NAME}
zpool trim ${ZPOOL_NAME}

# Create a storage pool using exist rpool.
# incus storage create <pool_name> <driver> [configuration_options...]
POOL='incus-default'
incus storage create ${POOL} zfs source=${ZPOOL_NAME}


# Configure incus init with a non-interactive preseed settings:
# https://linuxcontainers.org/incus/docs/main/howto/initialize/#non-interactive-configuration
# incus admin init
#
# core.https_address :8443
# core.https_address 192.168.1.69
ADDRESS=':8443'

cat <<-EOF | incus admin init --preseed
  # Daemon settings
  config:
    core.https_address: :8443
    images.auto_update_interval: 36

  # Storage pools
  storage_pools:
  - name: incus-default
    driver: zfs
    config:
      source: rpool/incus-1

  # Network devices
  networks:
  - name: incusbr0
    type: bridge
    config:
      ipv4.address: auto
      ipv6.address: auto

  # Profiles
  profiles:
  - name: default
    devices:
      root:
        path: /
        pool: incus-default
        type: disk
  - name: test-profile
    description: "Test profile"
    config:
      limits.memory: 2GiB
    devices:
      test0:
        name: test0
        nictype: bridged
        parent: incusbr0
        type: nic
EOF

cat <<-EOF
  # Creating & starting a container.
	incus create images:centos/9-Stream centos --vm
	incus config device add centos agent disk source=agent:config
	incus start centos

  or:

  incus launch images:ubuntu/22.04 incus1 -c boot.autostart=true
EOF

# https://linuxcontainers.org/incus/docs/main/reference/storage_zfs/#storage-zfs
#
# https://ciphermenial.github.io/posts/configure-incus-for-docker/
# Create a new Incus container. In this instance, I name this container docker
# ZFS 2.2 introduced Linux container support for overlayfs.
cat <<-EOF
  # https://linuxcontainers.org/incus/docs/main/reference/storage_zfs/#storage-zfs
  # https://linuxcontainers.org/incus/docs/main/howto/storage_pools/#howto-storage-pools
  # https://linuxcontainers.org/incus/docs/main/howto/storage_pools/#examples
  #
  # ZFS Pool Delegation
  # incus storage volume set <storage name> container/<container name> zfs.delegate=true
  incus create images:debian/12 docker -c security.nesting=true -c security.syscalls.intercept.mknod=true -c security.syscalls.intercept.setxattr=true
  incus storage volume set default container/docker zfs.delegate=true
  incus start docker
EOF

cat <<-EOF
  # Useful commands:
  incus list to view a list of containers.
  incus config show <container name> to view the containers configuration.
  incus admin init --dump to view the intial configuration for Incus.
  incus exec <containter name> bash to connect a container terminal session using bash.
EOF
