Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save herbetom/d10180676b22304d18f2eba046a73c25 to your computer and use it in GitHub Desktop.
Save herbetom/d10180676b22304d18f2eba046a73c25 to your computer and use it in GitHub Desktop.
Make sure to use Ubuntu 18.04 or this may not work

Install NixOS on Oracle Cloud over Ubuntu 18.04

# install useful tools
sudo apt-get update
sudo apt-get install --no-install-recommends -y nano mc git

# prepare /boot
sudo umount /boot/efi
sudo mv /boot /boot.bak
sudo mkdir /boot/
sudo mount /dev/sda15 /boot
sudo mv /boot/* /boot.bak/efi/

# use swap file
sudo dd if=/dev/zero of=/swapfile bs=1M count=1024 status=progress
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

# install nix
sh <(curl -L https://nixos.org/nix/install)
. $HOME/.nix-profile/etc/profile.d/nix.sh
nix-channel --add https://nixos.org/channels/nixos-21.11 nixpkgs
nix-channel --update

# install nixos-generate-config and nixos-install
nix-env -f '<nixpkgs>' -iA nixos-install-tools

# generate config
sudo `which nixos-generate-config` --root /

# remove lxc mounts
sudo nano /etc/nixos/hardware-configuration.nix
# set hostname, add users and ssh-keys, enable openssh
sudo nano /etc/nixos/configuration.nix

# build config
nix-env -p /nix/var/nix/profiles/system -f '<nixpkgs/nixos>' -I nixos-config=/etc/nixos/configuration.nix -iA system

# prepare target
sudo chown -R 0.0 /nix
sudo touch /etc/NIXOS
sudo touch /etc/NIXOS_LUSTRATE
echo etc/nixos | sudo tee -a /etc/NIXOS_LUSTRATE

# install NixOS
sudo NIXOS_INSTALL_BOOTLOADER=1 /nix/var/nix/profiles/system/bin/switch-to-configuration boot

sudo reboot

Recommended configuration options

{
  # Oracle Cloud uses EFI boot
  boot.loader.systemd-boot.enable = true;
  boot.loader.efi.canTouchEfiVariables = true;

  # Kernel cmdline from Ubuntu config
  boot.kernelParams = [
    "console=ttyS0"
    "console=tty1"
    "nvme.shutdown_timeout=10"
    "libiscsi.debug_libiscsi_eh=1"
  ];

  # Load graphics driver in stage 1
  boot.initrd.kernelModules = [ "bochs_drm" ];

  # swap file is recommended
  swapDevices = [
    {
      device = "/swapfile";
      priority = 0;
    }
  ];
}

Repartitioning target system from kexec image

Create kexec.nix file with following contents (do not add any packages to environment.systemPackages or it won't boot on 1GB system):

{ config, pkgs, ... }:
{
  imports = [
    # this will work only under qemu, uncomment next line for full image
    # <nixpkgs/nixos/modules/installer/netboot/netboot-minimal.nix>
    <nixpkgs/nixos/modules/installer/netboot/netboot.nix>
    <nixpkgs/nixos/modules/profiles/qemu-guest.nix>
  ];

  # stripped down version of https://github.com/cleverca22/nix-tests/tree/master/kexec
  system.build = rec {
    image = pkgs.runCommand "image" { buildInputs = [ pkgs.nukeReferences ]; } ''
      mkdir $out
      cp ${config.system.build.kernel}/${config.system.boot.loader.kernelFile} $out/kernel
      cp ${config.system.build.netbootRamdisk}/initrd $out/initrd
      nuke-refs $out/kernel
    '';
    kexec_script = pkgs.writeTextFile {
      executable = true;
      name = "kexec-nixos";
      text = ''
        #!${pkgs.stdenv.shell}
        set -e
        ${pkgs.kexectools}/bin/kexec -l ${image}/kernel --initrd=${image}/initrd --append="init=${builtins.unsafeDiscardStringContext config.system.build.toplevel}/init ${toString config.boot.kernelParams}"
        sync
        echo "executing kernel, filesystems will be improperly umounted"
        ${pkgs.kexectools}/bin/kexec -e
      '';
    };
    kexec_tarball = pkgs.callPackage <nixpkgs/nixos/lib/make-system-tarball.nix> {
      storeContents = [
        {
          object = config.system.build.kexec_script;
          symlink = "/kexec_nixos";
        }
      ];
      contents = [ ];
      compressCommand = "cat";
      compressionExtension = "";
    };
    kexec_tarball_self_extract_script = pkgs.writeTextFile {
      executable = true;
      name = "kexec-nixos";
      text = ''
        #!/bin/sh
        set -eu
        ARCHIVE=`awk '/^__ARCHIVE_BELOW__/ { print NR + 1; exit 0; }' $0`
        tail -n+$ARCHIVE $0 | tar x -C /
        /kexec_nixos $@
        exit 1
        __ARCHIVE_BELOW__
      '';
    };
    kexec_bundle = pkgs.runCommand "kexec_bundle" { } ''
      cat \
        ${kexec_tarball_self_extract_script} \
        ${kexec_tarball}/tarball/nixos-system-${kexec_tarball.system}.tar \
        > $out
      chmod +x $out
    '';
  };

  boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" ];
  boot.kernelParams = [
    "panic=30" "boot.panic_on_fail" # reboot the machine upon fatal boot issues
    "console=ttyS0" # enable serial console
    "console=tty1"
  ];
  boot.kernel.sysctl."vm.overcommit_memory" = "1";

  environment.systemPackages = with pkgs; [ cryptsetup ];
  environment.variables.GC_INITIAL_HEAP_SIZE = "1M";

  networking.hostName = "kexec";

  services.getty.autologinUser = "root";
  services.openssh = {
    enable = true;
    challengeResponseAuthentication = false;
    passwordAuthentication = false;
  };

  documentation.enable = false;
  documentation.nixos.enable = false;
  fonts.fontconfig.enable = false;
  programs.bash.enableCompletion = false;
  programs.command-not-found.enable = false;
  security.polkit.enable = false;
  security.rtkit.enable = pkgs.lib.mkForce false;
  services.udisks2.enable = false;
  i18n.supportedLocales = [ (config.i18n.defaultLocale + "/UTF-8") ];

  users.users.root.openssh.authorizedKeys.keys = [
    # add your ssh key here
    "ssh-ed25519 ...."
  ];
}

Build kexec image (you'll need nix/NixOS installed on your machine):

nix-build '<nixpkgs/nixos>' -A config.system.build.kexec_bundle -I nixos-config=./kexec.nix

Copy tarball to remote machine using scp and reboot into kexec image:

scp ./result ubuntu@somehost:/tmp/kexec
ssh ubuntu@somehost -t sudo /tmp/kexec
# wait for machine to boot and then connect
ssh root@somehost

Repartition your drive, format, mount file systems, create swap(file) and activate it as soon as possible. Check manual for more info.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment