forked from fediversity/fediversity
		
	
		
			
				
	
	
		
			250 lines
		
	
	
	
		
			7.2 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
			
		
		
	
	
			250 lines
		
	
	
	
		
			7.2 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
| {
 | |
|   lib,
 | |
|   pkgs,
 | |
|   modulesPath,
 | |
|   sources,
 | |
|   ...
 | |
| }:
 | |
| let
 | |
|   inherit (pkgs) system;
 | |
|   backendPort = builtins.toString 8080;
 | |
|   tfBackend = fragment: {
 | |
|     address = "http://localhost:${backendPort}/state/${fragment}";
 | |
|   };
 | |
|   template-deployment =
 | |
|     (import ./setups/template.nix {
 | |
|       inherit sources system modulesPath;
 | |
|       config = {
 | |
|         httpBackend = tfBackend "proxmox-test/upload";
 | |
|         nodeName = "pve";
 | |
|         targetSystem = system;
 | |
|         node-name = "pve";
 | |
|         imageDatastoreId = "local";
 | |
|       };
 | |
|     }).default.tf-proxmox-template;
 | |
|   vm-deployment =
 | |
|     (import ./setups/vm.nix {
 | |
|       inherit sources system modulesPath;
 | |
|       config = {
 | |
|         httpBackend = tfBackend "proxmox-test/nixos";
 | |
|         inherit (import ./constants.nix) pathToRoot;
 | |
|         nodeName = "pve";
 | |
|         targetSystem = system;
 | |
|         # for the test use the proxmox host as jump host,
 | |
|         # as we have no static IPs the deployer can reach the deployed VM on
 | |
|         sshOpts = [
 | |
|           "ProxyCommand=ssh -W %h:%p pve"
 | |
|         ];
 | |
|         key-file = "/root/.ssh/id_ed25519";
 | |
|         node-name = "pve";
 | |
|         bridge = "br0";
 | |
|         vlanId = 0;
 | |
|         imageDatastoreId = "local";
 | |
|         vmDatastoreId = "local";
 | |
|         cdDatastoreId = "local";
 | |
|         ipv4Gateway = "192.168.10.1";
 | |
|         ipv4Address = "192.168.10.236/24";
 | |
|         ipv6Gateway = "";
 | |
|         ipv6Address = "";
 | |
|         # dynamically get the id from the template upload step
 | |
|         templateId = null;
 | |
|       };
 | |
|     }).default.tf-proxmox-vm;
 | |
| in
 | |
| {
 | |
|   _class = "nixosTest";
 | |
|   name = "deployment-model";
 | |
|   sourceFileset = lib.fileset.unions [
 | |
|     ../../run/tf-proxmox-vm/await-ssh.sh
 | |
|   ];
 | |
| 
 | |
|   nodes.pve =
 | |
|     { sources, ... }:
 | |
|     {
 | |
|       imports = [
 | |
|         "${sources.proxmox-nixos}/modules/proxmox-ve"
 | |
|       ];
 | |
|       environment.systemPackages = [
 | |
|         pkgs.jq
 | |
|         pkgs.qemu
 | |
|       ];
 | |
|       networking.firewall.enable = false;
 | |
|       networking.vlans = {
 | |
|         vlan0 = {
 | |
|           id = 0;
 | |
|           interface = "eth0";
 | |
|         };
 | |
|       };
 | |
|       networking.useDHCP = false;
 | |
| 
 | |
|       networking = {
 | |
|         bridges.br0.interfaces = [ ];
 | |
|         interfaces.br0.ipv4.addresses = [
 | |
|           {
 | |
|             address = "192.168.10.1";
 | |
|             prefixLength = 24;
 | |
|           }
 | |
|         ];
 | |
|         nat = {
 | |
|           enable = true;
 | |
|           internalInterfaces = [ "br0" ];
 | |
|         };
 | |
|       };
 | |
|       boot.kernel.sysctl."net.ipv4.ip_forward" = "1";
 | |
| 
 | |
|       users.users.root = {
 | |
|         password = "mytestpw";
 | |
|         hashedPasswordFile = lib.mkForce null;
 | |
|       };
 | |
|       # https://github.com/SaumonNet/proxmox-nixos/blob/main/modules/proxmox-ve/default.nix
 | |
|       services.proxmox-ve = {
 | |
|         enable = true;
 | |
|         ipAddress = "192.168.1.1";
 | |
|       };
 | |
|       virtualisation = {
 | |
|         diskSize = 5 * 1024;
 | |
|         memorySize = 3 * 1024;
 | |
|       };
 | |
|     };
 | |
| 
 | |
|   nodes.deployer =
 | |
|     { ... }:
 | |
|     {
 | |
|       imports = [
 | |
|         ../../modules/terraform-backend
 | |
|       ];
 | |
| 
 | |
|       networking.firewall.enable = false;
 | |
|       nix.nixPath = [
 | |
|         (lib.concatStringsSep ":" (lib.mapAttrsToList (k: v: k + "=" + v) sources))
 | |
|       ];
 | |
| 
 | |
|       environment.systemPackages = [
 | |
|         vm-deployment.run
 | |
|         template-deployment.run
 | |
|         pkgs.pve-manager
 | |
|         pkgs.openssl
 | |
|         pkgs.jq
 | |
|         (pkgs.callPackage ../../run/tf-proxmox-template/tf.nix { })
 | |
|         (pkgs.callPackage ../../run/tf-proxmox-vm/tf.nix { })
 | |
|       ];
 | |
| 
 | |
|       # needed only when building from deployer
 | |
|       system.extraDependenciesFromModule =
 | |
|         { pkgs, ... }:
 | |
|         {
 | |
|           environment.systemPackages = with pkgs; [
 | |
|             hello
 | |
|           ];
 | |
|         };
 | |
|       system.extraDependencies = [
 | |
|         sources.disko
 | |
|         pkgs.ubootQemuX86
 | |
|         pkgs.ubootQemuX86.inputDerivation
 | |
|         pkgs.pve-qemu
 | |
|         pkgs.pve-qemu.inputDerivation
 | |
|         pkgs.gnu-config
 | |
|         pkgs.byacc
 | |
|         pkgs.stdenv
 | |
|         pkgs.stdenvNoCC
 | |
|         sources.nixpkgs
 | |
|         pkgs.vte
 | |
|       ];
 | |
|       services.terraform-backend = {
 | |
|         enable = true;
 | |
|         settings = {
 | |
|           LISTEN_ADDR = ":${backendPort}";
 | |
|           # FIXME randomly generate this
 | |
|           KMS_KEY = "tsjxw9NjKUBUlzbTnD7orqIAdEmpGYRARvxD51jtY+o=";
 | |
|         };
 | |
|       };
 | |
|     };
 | |
| 
 | |
|   extraTestScript = ''
 | |
|     pve.wait_for_unit("pveproxy.service")
 | |
|     assert "running" in pve.succeed("pveproxy status")
 | |
|     pve.succeed("mkdir -p /run/pve")
 | |
|     assert "Proxmox" in pve.succeed("curl -s -i -k https://localhost:8006")
 | |
| 
 | |
|     cert = pve.succeed("cat /etc/pve/pve-root-ca.pem").strip()
 | |
| 
 | |
|     pve.succeed("pvesh create /pools --poolid Fediversity")
 | |
| 
 | |
|     # allow upload of `import` (template) files
 | |
|     pve.succeed("""
 | |
|       pvesh set /storage/local --content "vztmpl,rootdir,backup,snippets,import,iso,images" 1>/dev/null
 | |
|     """)
 | |
| 
 | |
|     template_token = pve.succeed("""
 | |
|       pvesh create /access/users/root@pam/token/template --output-format json | jq -r .value
 | |
|       pvesh set /access/acl --path "/" --token "root@pam!template" --roles "PVEDatastoreAdmin"
 | |
|     """).strip()
 | |
| 
 | |
|     vm_token = pve.succeed("""
 | |
|       pvesh create /access/users/root@pam/token/vm --output-format json | jq -r .value
 | |
|       pvesh set /access/acl --path "/" --token "root@pam!vm" --roles "PVEVMAdmin PVEDatastoreAdmin PVESDNUser"
 | |
|     """).strip()
 | |
| 
 | |
|     # skip indent for EOF
 | |
|     deployer.succeed(f"""
 | |
|     cat > /etc/ssl/certs/pve-root-ca.pem <<EOF
 | |
|     {cert}
 | |
|     EOF
 | |
| 
 | |
|     mkdir -p /root/.ssh
 | |
|     cat > /root/.ssh/id_ed25519 <<EOF
 | |
|     -----BEGIN OPENSSH PRIVATE KEY-----
 | |
|     b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
 | |
|     QyNTUxOQAAACBWbJXVjBLGo2MrI2LBKTbzDozuA/C9taU630EtU/h38gAAAJDAOy8uwDsv
 | |
|     LgAAAAtzc2gtZWQyNTUxOQAAACBWbJXVjBLGo2MrI2LBKTbzDozuA/C9taU630EtU/h38g
 | |
|     AAAECcF8xjLavgWePoVx45Euewsh6Kw07L6QDDy3WXFCn4bFZsldWMEsajYysjYsEpNvMO
 | |
|     jO4D8L21pTrfQS1T+HfyAAAAC2tpYXJhQG5peG9zAQI=
 | |
|     -----END OPENSSH PRIVATE KEY-----
 | |
|     EOF
 | |
|     chmod 600 /root/.ssh/id_ed25519
 | |
|     """)
 | |
| 
 | |
|     deployer.succeed("""
 | |
|       set -e
 | |
|       cd /etc/ssl/certs
 | |
|       { cat ca-bundle.crt
 | |
|         cat ca-certificates.crt
 | |
|         cat pve-root-ca.pem
 | |
|       } > new-ca-bundle.crt
 | |
|       rm ca-bundle.crt ca-certificates.crt
 | |
|       mv new-ca-bundle.crt ca-bundle.crt
 | |
|       ln -s ca-bundle.crt ca-certificates.crt
 | |
|       openssl verify -CApath /etc/ssl/certs ./pve-root-ca.pem
 | |
|     """)
 | |
| 
 | |
|     with subtest("Deploy the template"):
 | |
|       template_id = deployer.succeed(f"""
 | |
|         ssh -o BatchMode=yes -o StrictHostKeyChecking=no pve "true"
 | |
|         export PROXMOX_VE_INSECURE="true"
 | |
|         export SSL_CERT_FILE=/tmp/pve-ca-bundle.crt
 | |
|         export PROXMOX_VE_API_TOKEN="root@pam!template={template_token}"
 | |
|         ${lib.getExe template-deployment.run} | jq -r '.id.value'
 | |
|       """).strip()
 | |
| 
 | |
|     deploy = f"""
 | |
|       set -e
 | |
|       ssh -o BatchMode=yes -o StrictHostKeyChecking=no pve "true"
 | |
|       export PROXMOX_VE_INSECURE="true"
 | |
|       export SSL_CERT_FILE=/tmp/pve-ca-bundle.crt
 | |
|       export PROXMOX_VE_API_TOKEN="root@pam!vm={vm_token}"
 | |
|       export TF_VAR_template_id="{template_id}"
 | |
|       ${lib.getExe vm-deployment.run} | jq -r '.ipv4.value[0]'
 | |
|     """
 | |
| 
 | |
|     with subtest("Run the deployment"):
 | |
|       ip = deployer.succeed(deploy).strip()
 | |
| 
 | |
|     with subtest("Verify package"):
 | |
|       deployer.succeed(f"""
 | |
|         ssh -i "/root/.ssh/id_ed25519" -o StrictHostKeyChecking=no -o BatchMode=yes -J pve root@{ip} su - operator -c hello >&2
 | |
|       """)
 | |
| 
 | |
|     with subtest("No-op update"):
 | |
|       deployer.succeed(deploy, timeout=120)
 | |
|   '';
 | |
| }
 |