oci-image: init scripts to build and upload image

Add image configuration for Oracle Cloud Infrastructure and scripts to
build and upload the image as a Custom Image.

ilian 362d1d62 c57e7d56

Changed files
+208
nixos
maintainers
modules
+10
nixos/maintainers/scripts/oci/create-image.sh
···
+
#! /usr/bin/env bash
+
+
export NIX_PATH=nixpkgs=$(dirname $(readlink -f $0))/../../../..
+
export NIXOS_CONFIG=$(dirname $(readlink -f $0))/../../../modules/virtualisation/oci-image.nix
+
+
nix-build '<nixpkgs/nixos>' \
+
-A config.system.build.OCIImage \
+
--argstr system x86_64-linux \
+
--option system-features kvm \
+
-o oci-image
+98
nixos/maintainers/scripts/oci/upload-image.sh
···
+
#! /usr/bin/env bash
+
+
script_dir="$(dirname $(readlink -f $0))"
+
nixpkgs_root="$script_dir/../../../.."
+
export NIX_PATH="nixpkgs=$nixpkgs_root"
+
+
cat - <<EOF
+
This script will locally build a NixOS image and upload it as a Custom Image
+
using oci-cli. Make sure that an API key for the tenancy administrator has been
+
added to '~/.oci'.
+
For more info about configuring oci-cli, please visit
+
https://docs.cloud.oracle.com/iaas/Content/API/Concepts/apisigningkey.htm#Required_Keys_and_OCIDs
+
+
EOF
+
+
qcow="oci-image/nixos.qcow2"
+
if [ ! -f "$qcow" ]; then
+
echo "OCI image $qcow does not exist"
+
echo "Building image with create-image.sh"
+
"$script_dir/create-image.sh"
+
[ -f "$qcow" ] || { echo "Build failed: image not present after build"; exit 1; }
+
else
+
echo "Using prebuilt image $qcow"
+
fi
+
+
cli="$(
+
nix-build '<nixpkgs>' \
+
--no-out-link \
+
-A oci-cli
+
)"
+
+
PATH="$cli/bin:$PATH"
+
bucket="_TEMP_NIXOS_IMAGES_$RANDOM"
+
+
echo "Creating a temporary bucket"
+
root_ocid="$(
+
oci iam compartment list \
+
--all \
+
--compartment-id-in-subtree true \
+
--access-level ACCESSIBLE \
+
--include-root \
+
--raw-output \
+
--query "data[?contains(\"id\",'tenancy')].id | [0]"
+
)"
+
bucket_ocid=$(
+
oci os bucket create \
+
-c "$root_ocid" \
+
--name "$bucket" \
+
--raw-output \
+
--query "data.id"
+
)
+
# Clean up bucket on script termination
+
trap 'echo Removing temporary bucket; oci os bucket delete --force --name "$bucket"' INT TERM EXIT
+
+
echo "Uploading image to temporary bucket"
+
oci os object put -bn "$bucket" --file "$qcow"
+
+
echo "Importing image as a Custom Image"
+
bucket_ns="$(oci os ns get --query "data" --raw-output)"
+
image_id="$(
+
oci compute image import from-object \
+
-c "$root_ocid" \
+
--namespace "$bucket_ns" \
+
--bucket-name "$bucket" \
+
--name nixos.qcow2 \
+
--operating-system NixOS \
+
--source-image-type QCOW2 \
+
--launch-mode PARAVIRTUALIZED \
+
--display-name NixOS \
+
--raw-output \
+
--query "data.id"
+
)"
+
+
cat - <<EOF
+
Image created! Please mark all available shapes as compatible with this image by
+
visiting the following link and by selecting the 'Edit Details' button on:
+
https://cloud.oracle.com/compute/images/$image_id
+
EOF
+
+
# Workaround until https://github.com/oracle/oci-cli/issues/399 is addressed
+
echo "Sleeping for 15 minutes before cleaning up files in the temporary bucket"
+
sleep $((15 * 60))
+
+
echo "Deleting image from bucket"
+
par_id="$(
+
oci os preauth-request list \
+
--bucket-name "$bucket" \
+
--raw-output \
+
--query "data[0].id"
+
)"
+
+
if [[ -n $par_id ]]; then
+
oci os preauth-request delete \
+
--bucket-name "$bucket" \
+
--par-id "$par_id"
+
fi
+
+
oci os object delete -bn "$bucket" --object-name nixos.qcow2 --force
+39
nixos/modules/virtualisation/oci-common.nix
···
+
{ lib, pkgs, ... }:
+
+
with lib;
+
{
+
imports = [ ../profiles/qemu-guest.nix ];
+
+
# Taken from /proc/cmdline of Ubuntu 20.04.2 LTS on OCI
+
boot.kernelParams = [
+
"console=tty1"
+
"console=ttyS0"
+
"nvme.shutdown_timeout=10"
+
"libiscsi.debug_libiscsi_eh=1"
+
"crash_kexec_post_notifiers"
+
];
+
+
boot.growPartition = true;
+
+
fileSystems."/" = {
+
device = "/dev/disk/by-label/nixos";
+
fsType = "ext4";
+
autoResize = true;
+
};
+
+
boot.loader.grub = {
+
version = 2;
+
device = "/dev/sda";
+
splashImage = null;
+
extraConfig = ''
+
serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1
+
terminal_input --append serial
+
terminal_output --append serial
+
'';
+
};
+
+
# https://docs.oracle.com/en-us/iaas/Content/Compute/Tasks/configuringntpservice.htm#Configuring_the_Oracle_Cloud_Infrastructure_NTP_Service_for_an_Instance
+
networking.timeServers = [ "169.254.169.254" ];
+
+
services.openssh.enable = true;
+
}
+12
nixos/modules/virtualisation/oci-config-user.nix
···
+
{ modulesPath, ... }:
+
+
{
+
# To build the configuration or use nix-env, you need to run
+
# either nixos-rebuild --upgrade or nix-channel --update
+
# to fetch the nixos channel.
+
+
# This configures everything but bootstrap services,
+
# which only need to be run once and have already finished
+
# if you are able to see this comment.
+
imports = [ "${modulesPath}/virtualisation/oci-common.nix" ];
+
}
+49
nixos/modules/virtualisation/oci-image.nix
···
+
+
{ config, lib, pkgs, ... }:
+
+
with lib;
+
+
{
+
imports = [ ./oci-common.nix ];
+
+
config = {
+
system.build.OCIImage = import ../../lib/make-disk-image.nix {
+
inherit config lib pkgs;
+
name = "oci-image";
+
configFile = ./oci-config-user.nix;
+
format = "qcow2";
+
diskSize = 8192;
+
};
+
+
systemd.services.fetch-ssh-keys = {
+
description = "Fetch authorized_keys for root user";
+
+
wantedBy = [ "sshd.service" ];
+
before = [ "sshd.service" ];
+
+
after = [ "network-online.target" ];
+
wants = [ "network-online.target" ];
+
+
path = [ pkgs.coreutils pkgs.curl ];
+
script = ''
+
mkdir -m 0700 -p /root/.ssh
+
if [ -f /root/.ssh/authorized_keys ]; then
+
echo "Authorized keys have already been downloaded"
+
else
+
echo "Downloading authorized keys from Instance Metadata Service v2"
+
curl -s -S -L \
+
-H "Authorization: Bearer Oracle" \
+
-o /root/.ssh/authorized_keys \
+
http://169.254.169.254/opc/v2/instance/metadata/ssh_authorized_keys
+
chmod 600 /root/.ssh/authorized_keys
+
fi
+
'';
+
serviceConfig = {
+
Type = "oneshot";
+
RemainAfterExit = true;
+
StandardError = "journal+console";
+
StandardOutput = "journal+console";
+
};
+
};
+
};
+
}