change to two stage deploy to get IP on br0

This commit is contained in:
James Andariese 2022-09-27 11:16:53 -05:00
parent 4a14f2a0c1
commit 15e8495cd7
10 changed files with 156 additions and 46 deletions

View File

@ -1,21 +1,43 @@
with builtins;
with import (toString ../functions);
{config, lib, ...}: { {config, lib, ...}: {
options = with lib; with types; { options = with lib; with types; {
cascade.bridge-interface = mkOption { cascade.bridge-interface = mkOption {
type = str; type = nullOr str;
default = null;
description = "interface on which to create primary bridge (br0)"; description = "interface on which to create primary bridge (br0)";
}; };
cascade.bridge-mac-prefix = mkOption {
type = str;
description = "prefix of mac addresses generated for primary bridge (br0)";
};
}; };
config = with lib; { config = with lib; {
networking = { cascade.bridge-mac-prefix = mkDefault "02:${name-to-mac 2 config.networking.domain}";
networking = mkIf (config.cascade.bridge-interface != null) {
useNetworkd = mkForce true; useNetworkd = mkForce true;
bridges.br0.interfaces = [config.cascade.bridge-interface]; bridges.br0.interfaces = [config.cascade.bridge-interface];
interfaces.br0.useDHCP = mkImageMediaOverride true; interfaces.br0.useDHCP = mkImageMediaOverride true;
interfaces.br0.macAddress = mkImageMediaOverride "${config.cascade.bridge-mac-prefix}:${name-to-mac 3 config.networking.hostName}";
# also work around an issue with ipv6 and reverse lookups
hosts = lib.mkForce {
"127.0.1.1" = ["${config.networking.hostName}.${config.networking.domain}" config.networking.hostName];
}; };
#systemd.network.links."05-br0".matchConfig.Name = "br0"; };
#systemd.network.links."05-br0".linkConfig.MACAddressPolicy = "none";
#services.resolved.enable = mkForce false;
# let's just do this here to be sure...
system.activationScripts.cascade-networking-domainname = ''
domainname "${config.networking.domain}"
hostname "${config.networking.hostName}"
'';
}; };
} }

36
common/cascade-source.nix Normal file
View File

@ -0,0 +1,36 @@
with builtins;
with import (toString ../functions);
{config, lib, ...}: {
options = with lib; with types; {
environment.cascade-source.enable = mkOption {
default = true;
type = bool;
description = ''
Include cascade source code configured for nixos-rebuild.
'';
};
};
config = with lib; {
system.activationScripts.cascade-source = mkMerge [
(mkIf config.environment.cascade-source.enable ''
mkdir -m 0755 -p /usr/src /etc/nixos
[ -h /usr/src/cascade ] && rm /usr/src/cascade # do this first so the dir test that comes next won't read the symlink as a dir
[ -d /usr/src/cascade ] && mv /usr/src/cascade /usr/src/cascade.before-nixos
ln -sfn ${./..} /usr/src/cascade # but why isn't this atomic?
ln -sf /usr/src/cascade/hosts/${config.networking.hostName}.nix /etc/nixos/configuration.nix
'')
(mkIf (!config.environment.cascade-source.enable) ''
# if we delete the symlink version of cascade, we delete a symlink in /etc/nixos as well
[ -h /usr/src/cascade ] && rm /usr/src/cascade && \
[ -h /etc/nixos/configuration.nix ] && rm /etc/nixos/configuration.nix
'')
];
nix.nixPath = [
"nixos-config=/etc/nixos/configuration.nix"
];
};
}

View File

@ -1,10 +1,14 @@
{ {
imports = [ imports = [
(toString ../profiles/qemu-vm) (toString ../profiles/qemu-vm-install-media)
]; ];
config = { config = {
#deployment.targetHost = ""; #deployment.targetHost = "";
#deployment.targetUser = ""; #deployment.targetUser = "";
#deployment.targetPort = ""; #deployment.targetPort = "";
networking.hostName = "nixos";
#networking.interfaces.br0.ipv4.addresses = [ ];
#networking.interfaces.br0.ipv4.routes = [ {address = "0.0.0.0"; prefixLength = 0; via = "172.16.1.1"; } ];
#networking.interfaces.br0.useDHCP = false;
}; };
} }

View File

@ -1,7 +1,7 @@
with builtins; with builtins;
with import ./functions; with import ./functions;
let pkgs = import <nixpkgs> {}; let pkgs = (import "${import ./nixpkgs-path.nix}" {});
network = { network = {
inherit pkgs; inherit pkgs;
description = "cascade"; description = "cascade";

15
nixpkgs-path.nix Normal file
View File

@ -0,0 +1,15 @@
let pkgs = import <nixpkgs> {};
in
if pkgs == null then
builtins.fetchGit {
url = "https://github.com/nixos/nixpkgs";
ref = "master";
rev = "da4c6be0187a694bdeb3efc28b29ee0e4c30702f";
shallow = true;
}
else pkgs.fetchgit {
url = "https://github.com/nixos/nixpkgs";
rev = "da4c6be0187a694bdeb3efc28b29ee0e4c30702f";
sha256 = "sha256-1rcG6x0vKnnzGhABPg/QvL75DzhJxM810wZKAukoF1M=";
}

View File

@ -41,8 +41,7 @@
boot.loader.systemd-boot.enable = true; boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true; boot.loader.efi.canTouchEfiVariables = true;
#networking.meth.meth0.replaceInterface = "enp1s0";
#
cascade.bridge-interface = "enp1s0"; cascade.bridge-interface = "enp1s0";
systemd.network.wait-online.ignoredInterfaces = lib.mkDefault [ "wlp0s20u3" ];
}; };
} }

View File

@ -1,4 +1,4 @@
{pkgs,...}: {pkgs ? (import "${import ../../nixpkgs-path.nix}" {}), ...}:
{ {
imports = [ imports = [
(toString ../../common) (toString ../../common)
@ -7,23 +7,29 @@
# used for deployment. This is done automatically with shell.nix. # used for deployment. This is done automatically with shell.nix.
]; ];
config = { config = {
environment.systemPackages = with pkgs; [ bridge-utils ]; environment.systemPackages = with pkgs; [ bridge-utils git ];
programs.neovim.enable = true; programs.neovim.enable = true;
programs.neovim.vimAlias = true; programs.neovim.vimAlias = true;
programs.neovim.viAlias = true; programs.neovim.viAlias = true;
networking.domain = "cascade.strudelline.net";
networking.search = [ "cascade.strudelline.net" "strudelline.net" ];
networking.nameservers = [ "172.16.44.1" "172.16.1.1" ];
cascade.bridge-mac-prefix = "00:80:10";
environment.binbash.enable = true; environment.binbash.enable = true;
services.getty.autologinUser = "root"; services.getty.autologinUser = pkgs.lib.mkForce "root";
services.sshd.enable = true; services.sshd.enable = true;
networking.firewall.allowedTCPPorts = [ 22 ]; networking.firewall.allowedTCPPorts = [ 22 ];
system.stateVersion = "22.11"; system.stateVersion = "22.11";
nix.nixPath = with pkgs; [ nix.nixPath = with pkgs; [
"nixpkgs=/usr/src/nixpkgs" "nixpkgs=${ import ../../nixpkgs-path.nix }"
"home-manager=/usr/src/nixpkgs" "home-manager=/usr/src/home-manager"
"morph-options=${morph.lib}/options.nix" "morph-options=${morph.lib}/options.nix"
]; ];
}; };

View File

@ -0,0 +1,10 @@
{lib, config, ...}:
with lib;
{
imports = [ (toString ../qemu-vm) ];
config = {
cascade.bridge-interface = mkForce null; # let it come up with its default interface with dhcp first
};
}

View File

@ -6,7 +6,7 @@ with lib;
config = { config = {
deployment.targetUser = lib.mkDefault "root"; deployment.targetUser = lib.mkDefault "root";
cascade.bridge-interface = "ens18"; cascade.bridge-interface = mkImageMediaOverride "ens18";
fileSystems."/" = { fileSystems."/" = {
device = "/dev/disk/by-label/nixos"; device = "/dev/disk/by-label/nixos";
fsType = "ext4"; fsType = "ext4";

View File

@ -1,4 +1,4 @@
{ pkgs ? import <nixpkgs> {}, ... }: { pkgs ? (import (import ./nixpkgs-path.nix) {}), ... }:
let let
vault_addr = "http://vault:8200"; vault_addr = "http://vault:8200";
@ -10,16 +10,17 @@ with lib;
stdenv.mkDerivation { stdenv.mkDerivation {
name = "commands-nix"; name = "commands-nix";
buildInputs = [ terraform vault coreutils-full dig bash samba4Full morph ]; buildInputs = [ terraform vault gnused coreutils-full dig bash samba4Full morph xxd ];
shellHook = '' shellHook = ''
export NIX_PATH="nixpkgs=${toString <nixpkgs>}:morph-options=${morph.lib}/options.nix" export NIX_PATH="nixpkgs=${import ./nixpkgs-path.nix}:morph-options=${morph.lib}/options.nix"
export LD_LIBRARY_PATH="${libvirt}/lib:$LD_LIBRARY_PATH" export LD_LIBRARY_PATH="${libvirt}/lib:$LD_LIBRARY_PATH"
export VAULT_ADDR=${escapeShellArg vault_addr} export VAULT_ADDR=${escapeShellArg vault_addr}
export DOMAIN="$(hostname -d)" export DOMAIN="$(hostname -d)"
PROXMOX_STORAGE=hdd-fs PROXMOX_STORAGE=hdd-fs
MEMORY=2048 MEMORY=2048
NETWORK_PREFIX_LENGTH=12
rebuild-nixos-image() { rebuild-nixos-image() {
echo "$(nix-build custom-image.nix)/nixos".img echo "$(nix-build custom-image.nix)/nixos".img
@ -33,8 +34,11 @@ mkvirt() {
1>&2 echo "there is already a file at ./hosts/$name"".nix. move it or remove it." 1>&2 echo "there is already a file at ./hosts/$name"".nix. move it or remove it."
return 1 return 1
fi fi
cp "./hosts/_basic.nix" "./hosts/""$name"".nix"
morph build network.nix --on="$name" & # free-ips.txt contains fre IPs, one per line
# this is currently not being used in favor of DHCP towards the end
#IPALLOC="$(head -1 free-ips.txt)"
#sed -i -e '1d' free-ips.txt
[ -f "result/nixos.img" ] || ( [ -f "result/nixos.img" ] || (
1>&2 echo "you do not seem to have a result/nixos.img file. building one now." 1>&2 echo "you do not seem to have a result/nixos.img file. building one now."
@ -61,33 +65,49 @@ mkvirt() {
--start 1 --start 1
[ $? -eq 0 ] || return 7 [ $? -eq 0 ] || return 7
IP="$(wait-for-vm-ipv4 $VMID)" IP="$(wait-for-vm-ipv4 $VMID)" ; [ $? -eq 0 ] || return 8
[ $? -eq 0 ] || return 8
samba-create-ipv4-records "$IP" "$name" "$DOMAIN" ssh-rescan "$IP"
[ $? -eq 0 ] || return 9
1>&2 echo "removing any stale ssh keys" sed -e '
ssh-keygen -f "$HOME/.ssh/known_hosts" -R "$name" s#profiles/qemu-vm-install-media#profiles/qemu-vm#g
ssh-keygen -f "$HOME/.ssh/known_hosts" -R "$name.$DOMAIN" s#networking[.]hostName = "nixos";#networking.hostName = "'"$name"'";#g
ssh-keygen -f "$HOME/.ssh/known_hosts" -R "$IP" ' "./hosts/_basic.nix" > "./hosts/""$name"".nix"
1>&2 echo "scanning for new ssh keys"
# head -1 allows us to grab the ed25519 key before the rsa key. 1>&2 echo "performing initial deployment to temporary IP: $IP"
# at worst, it will yield a single key of some sort which is also fine. rsync -a ./ "$IP":/tmp/cascade/
( guestbash $VMID 'nixos-rebuild -I nixos-config=/tmp/cascade/hosts/'"$name"'.nix switch && systemctl restart systemd-networkd'
echo
ssh-keyscan "$IP" | sort | head -1 1>&2 echo "retrieving permanent IP"
echo IP="$(wait-for-vm-ipv4 $VMID)" ; [ $? -eq 0 ] || return 8
ssh-keyscan "$name" | sort | head -1 samba-create-ipv4-records "$IP" "$name" "$DOMAIN" ; [ $? -eq 0 ] || return 9
echo
ssh-keyscan "$name.$DOMAIN" | sort | head -1 ssh-rescan "$name" "$name.$DOMAIN" "$IP"
echo
) 2> /dev/null >> ~/.ssh/known_hosts
1>&2 echo "waiting for morph build to finish"
wait
1>&2 echo "morphing host" 1>&2 echo "morphing host"
morph deploy network.nix switch --on="$name" morph deploy network.nix switch --on="$name"
} }
file-ends-with-newline() {
[ x"$(xxd -ps "$1" | sed -E -e '$! d' -e 's/.*(..)$/\1/')" = x"0a" ]
}
ensure-file-ends-with-newline() {
file-ends-with-newline "$1" || echo >> "$1"
}
ssh-rescan() {
1>&2 echo "ensuring known_hosts ends with a newline"
ensure-file-ends-with-newline "$HOME/.ssh/known_hosts"
while [ $# -gt 0 ];do
1>&2 echo "replacing any stale ssh keys that can be found"
ssh-keygen -f "$HOME/.ssh/known_hosts" -R "$1" 2> /dev/null || true
ssh-keyscan "$1" 2> /dev/null | sort | head -1 >> "$HOME/.ssh/known_hosts"
shift
done
}
samba-create-ipv4-records() { samba-create-ipv4-records() {
eval "$(env_cascade)" eval "$(env_cascade)"
IP="$1" IP="$1"
@ -108,7 +128,6 @@ samba-create-ipv4-records() {
} }
wait-for-vm-ipv4() { wait-for-vm-ipv4() {
set -x
VMID="$1" VMID="$1"
while true;do while true;do
IP="$( sudo qm guest cmd $VMID network-get-interfaces | \ IP="$( sudo qm guest cmd $VMID network-get-interfaces | \
@ -126,7 +145,6 @@ set -x
fi fi
sleep 1 sleep 1
done done
set +x
} }
env_cascade() { env_cascade() {
@ -187,7 +205,7 @@ destroy-host() {
while [ $# -gt 0 ];do while [ $# -gt 0 ];do
eval "$(env_name "$1")" eval "$(env_name "$1")"
VMID="$(sudo qm list | awk -v N="$1" '$2 == N {print $name}')" VMID="$(sudo qm list | awk -v N="$1" '$2 == N {print $1}')"
echo "destroying hosts/$1.nix and VM #$VMID" 1>&2 echo "destroying hosts/$1.nix and VM #$VMID" 1>&2
sleep 1 sleep 1
@ -215,7 +233,7 @@ You may also register an existing host in DNS using:
Then morph may be used to deploy: Then morph may be used to deploy:
# Create a hosts/hostname-here.nix file based on hosts/basic.nix.sample # Create a hosts/hostname-here.nix file based on hosts/_basic.nix
deploy test # this is an alias which runs morph on network.nix. deploy test # this is an alias which runs morph on network.nix.
deploy switch # the argument is the same as to morph deploy and nixos-rebuild deploy switch # the argument is the same as to morph deploy and nixos-rebuild