Merge pull request #119856 from ilian/oci-image

oci-image: init scripts to build and upload image

authored by Thiago Kenji Okada and committed by GitHub a3a7520a 85050921

+261
+24
nixos/maintainers/scripts/oci/create-image.sh
···
··· 1 + #! /usr/bin/env bash 2 + 3 + set -euo pipefail 4 + 5 + export NIX_PATH=nixpkgs=$(dirname $(readlink -f $0))/../../../.. 6 + export NIXOS_CONFIG=$(dirname $(readlink -f $0))/../../../modules/virtualisation/oci-image.nix 7 + 8 + if (( $# < 1 )); then 9 + ( 10 + echo "Usage: create-image.sh <architecture>" 11 + echo 12 + echo "Where <architecture> is one of:" 13 + echo " x86_64-linux" 14 + echo " aarch64-linux" 15 + ) >&2 16 + fi 17 + 18 + system="$1"; shift 19 + 20 + nix-build '<nixpkgs/nixos>' \ 21 + -A config.system.build.OCIImage \ 22 + --argstr system "$system" \ 23 + --option system-features kvm \ 24 + -o oci-image
+100
nixos/maintainers/scripts/oci/upload-image.sh
···
··· 1 + #! /usr/bin/env bash 2 + 3 + set -euo pipefail 4 + 5 + script_dir="$(dirname $(readlink -f $0))" 6 + nixpkgs_root="$script_dir/../../../.." 7 + export NIX_PATH="nixpkgs=$nixpkgs_root" 8 + 9 + cat - <<EOF 10 + This script will locally build a NixOS image and upload it as a Custom Image 11 + using oci-cli. Make sure that an API key for the tenancy administrator has been 12 + added to '~/.oci'. 13 + For more info about configuring oci-cli, please visit 14 + https://docs.cloud.oracle.com/iaas/Content/API/Concepts/apisigningkey.htm#Required_Keys_and_OCIDs 15 + 16 + EOF 17 + 18 + qcow="oci-image/nixos.qcow2" 19 + if [ ! -f "$qcow" ]; then 20 + echo "OCI image $qcow does not exist" 21 + echo "Building image with create-image.sh for 'x86_64-linux'" 22 + "$script_dir/create-image.sh" x86_64-linux 23 + [ -f "$qcow" ] || { echo "Build failed: image not present after build"; exit 1; } 24 + else 25 + echo "Using prebuilt image $qcow" 26 + fi 27 + 28 + cli="$( 29 + nix-build '<nixpkgs>' \ 30 + --no-out-link \ 31 + -A oci-cli 32 + )" 33 + 34 + PATH="$cli/bin:$PATH" 35 + bucket="_TEMP_NIXOS_IMAGES_$RANDOM" 36 + 37 + echo "Creating a temporary bucket" 38 + root_ocid="$( 39 + oci iam compartment list \ 40 + --all \ 41 + --compartment-id-in-subtree true \ 42 + --access-level ACCESSIBLE \ 43 + --include-root \ 44 + --raw-output \ 45 + --query "data[?contains(\"id\",'tenancy')].id | [0]" 46 + )" 47 + bucket_ocid=$( 48 + oci os bucket create \ 49 + -c "$root_ocid" \ 50 + --name "$bucket" \ 51 + --raw-output \ 52 + --query "data.id" 53 + ) 54 + # Clean up bucket on script termination 55 + trap 'echo Removing temporary bucket; oci os bucket delete --force --name "$bucket"' INT TERM EXIT 56 + 57 + echo "Uploading image to temporary bucket" 58 + oci os object put -bn "$bucket" --file "$qcow" 59 + 60 + echo "Importing image as a Custom Image" 61 + bucket_ns="$(oci os ns get --query "data" --raw-output)" 62 + image_id="$( 63 + oci compute image import from-object \ 64 + -c "$root_ocid" \ 65 + --namespace "$bucket_ns" \ 66 + --bucket-name "$bucket" \ 67 + --name nixos.qcow2 \ 68 + --operating-system NixOS \ 69 + --source-image-type QCOW2 \ 70 + --launch-mode PARAVIRTUALIZED \ 71 + --display-name NixOS \ 72 + --raw-output \ 73 + --query "data.id" 74 + )" 75 + 76 + cat - <<EOF 77 + Image created! Please mark all available shapes as compatible with this image by 78 + visiting the following link and by selecting the 'Edit Details' button on: 79 + https://cloud.oracle.com/compute/images/$image_id 80 + EOF 81 + 82 + # Workaround until https://github.com/oracle/oci-cli/issues/399 is addressed 83 + echo "Sleeping for 15 minutes before cleaning up files in the temporary bucket" 84 + sleep $((15 * 60)) 85 + 86 + echo "Deleting image from bucket" 87 + par_id="$( 88 + oci os preauth-request list \ 89 + --bucket-name "$bucket" \ 90 + --raw-output \ 91 + --query "data[0].id" 92 + )" 93 + 94 + if [[ -n $par_id ]]; then 95 + oci os preauth-request delete \ 96 + --bucket-name "$bucket" \ 97 + --par-id "$par_id" 98 + fi 99 + 100 + oci os object delete -bn "$bucket" --object-name nixos.qcow2 --force
+1
nixos/modules/module-list.nix
··· 1485 ./virtualisation/nixos-containers.nix 1486 ./virtualisation/oci-containers.nix 1487 ./virtualisation/openstack-options.nix 1488 ./virtualisation/openvswitch.nix 1489 ./virtualisation/parallels-guest.nix 1490 ./virtualisation/podman/default.nix
··· 1485 ./virtualisation/nixos-containers.nix 1486 ./virtualisation/oci-containers.nix 1487 ./virtualisation/openstack-options.nix 1488 + ./virtualisation/oci-options.nix 1489 ./virtualisation/openvswitch.nix 1490 ./virtualisation/parallels-guest.nix 1491 ./virtualisation/podman/default.nix
+60
nixos/modules/virtualisation/oci-common.nix
···
··· 1 + { config, lib, pkgs, ... }: 2 + 3 + let 4 + cfg = config.oci; 5 + in 6 + { 7 + imports = [ ../profiles/qemu-guest.nix ]; 8 + 9 + # Taken from /proc/cmdline of Ubuntu 20.04.2 LTS on OCI 10 + boot.kernelParams = [ 11 + "nvme.shutdown_timeout=10" 12 + "nvme_core.shutdown_timeout=10" 13 + "libiscsi.debug_libiscsi_eh=1" 14 + "crash_kexec_post_notifiers" 15 + 16 + # VNC console 17 + "console=tty1" 18 + 19 + # x86_64-linux 20 + "console=ttyS0" 21 + 22 + # aarch64-linux 23 + "console=ttyAMA0,115200" 24 + ]; 25 + 26 + boot.growPartition = true; 27 + 28 + fileSystems."/" = { 29 + device = "/dev/disk/by-label/nixos"; 30 + fsType = "ext4"; 31 + autoResize = true; 32 + }; 33 + 34 + fileSystems."/boot" = lib.mkIf cfg.efi { 35 + device = "/dev/disk/by-label/ESP"; 36 + fsType = "vfat"; 37 + }; 38 + 39 + boot.loader.efi.canTouchEfiVariables = false; 40 + boot.loader.grub = { 41 + device = if cfg.efi then "nodev" else "/dev/sda"; 42 + splashImage = null; 43 + extraConfig = '' 44 + serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1 45 + terminal_input --append serial 46 + terminal_output --append serial 47 + ''; 48 + efiInstallAsRemovable = cfg.efi; 49 + efiSupport = cfg.efi; 50 + }; 51 + 52 + # https://docs.oracle.com/en-us/iaas/Content/Compute/Tasks/configuringntpservice.htm#Configuring_the_Oracle_Cloud_Infrastructure_NTP_Service_for_an_Instance 53 + networking.timeServers = [ "169.254.169.254" ]; 54 + 55 + services.openssh.enable = true; 56 + 57 + # Otherwise the instance may not have a working network-online.target, 58 + # making the fetch-ssh-keys.service fail 59 + networking.useNetworkd = true; 60 + }
+12
nixos/modules/virtualisation/oci-config-user.nix
···
··· 1 + { modulesPath, ... }: 2 + 3 + { 4 + # To build the configuration or use nix-env, you need to run 5 + # either nixos-rebuild --upgrade or nix-channel --update 6 + # to fetch the nixos channel. 7 + 8 + # This configures everything but bootstrap services, 9 + # which only need to be run once and have already finished 10 + # if you are able to see this comment. 11 + imports = [ "${modulesPath}/virtualisation/oci-common.nix" ]; 12 + }
+50
nixos/modules/virtualisation/oci-image.nix
···
··· 1 + { config, lib, pkgs, ... }: 2 + 3 + let 4 + cfg = config.oci; 5 + in 6 + { 7 + imports = [ ./oci-common.nix ]; 8 + 9 + config = { 10 + system.build.OCIImage = import ../../lib/make-disk-image.nix { 11 + inherit config lib pkgs; 12 + name = "oci-image"; 13 + configFile = ./oci-config-user.nix; 14 + format = "qcow2"; 15 + diskSize = 8192; 16 + partitionTableType = if cfg.efi then "efi" else "legacy"; 17 + }; 18 + 19 + systemd.services.fetch-ssh-keys = { 20 + description = "Fetch authorized_keys for root user"; 21 + 22 + wantedBy = [ "sshd.service" ]; 23 + before = [ "sshd.service" ]; 24 + 25 + after = [ "network-online.target" ]; 26 + wants = [ "network-online.target" ]; 27 + 28 + path = [ pkgs.coreutils pkgs.curl ]; 29 + script = '' 30 + mkdir -m 0700 -p /root/.ssh 31 + if [ -f /root/.ssh/authorized_keys ]; then 32 + echo "Authorized keys have already been downloaded" 33 + else 34 + echo "Downloading authorized keys from Instance Metadata Service v2" 35 + curl -s -S -L \ 36 + -H "Authorization: Bearer Oracle" \ 37 + -o /root/.ssh/authorized_keys \ 38 + http://169.254.169.254/opc/v2/instance/metadata/ssh_authorized_keys 39 + chmod 600 /root/.ssh/authorized_keys 40 + fi 41 + ''; 42 + serviceConfig = { 43 + Type = "oneshot"; 44 + RemainAfterExit = true; 45 + StandardError = "journal+console"; 46 + StandardOutput = "journal+console"; 47 + }; 48 + }; 49 + }; 50 + }
+14
nixos/modules/virtualisation/oci-options.nix
···
··· 1 + { config, lib, pkgs, ... }: 2 + { 3 + options = { 4 + oci = { 5 + efi = lib.mkOption { 6 + default = true; 7 + internal = true; 8 + description = '' 9 + Whether the OCI instance is using EFI. 10 + ''; 11 + }; 12 + }; 13 + }; 14 + }