diff --git a/Makefile b/Makefile index b965dca..37f5503 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ -include .env export -.PHONY: help cloud-deploy cloud-status cloud-destroy usb-build usb-flash local-dev-shell local-deploy local-ssh local-clean clean +.PHONY: help cloud-deploy cloud-status cloud-destroy usb-build usb-flash local-vm-run local-shell clean DOMAIN := $(or $(WORKSHOP_DOMAIN),codecrispi.es) USB_DEVICE := /dev/sdX @@ -12,27 +12,33 @@ help: @echo "" @echo "Usage: make " @echo "" - @echo "Cloud Commands:" - @echo " cloud-deploy - Deploy VMs to Hetzner and run health checks" - @echo " cloud-status - Check the status of cloud servers" - @echo " cloud-destroy - Destroy all cloud infrastructure" + @echo "--- Local VM Development ---" + @echo " make local-vm-run - Start the complete workshop environment in a VM" @echo "" - @echo "USB Drive Commands:" - @echo " usb-build - Build the NixOS ISO for the workshop" - @echo " usb-flash - Flash the ISO to a USB drive (set USB_DEVICE)" + @echo "--- Cloud Infrastructure ---" + @echo " make cloud-deploy - Deploy VMs to Hetzner" + @echo " make cloud-status - Check the status of cloud servers" + @echo " make cloud-destroy - Destroy all cloud infrastructure" @echo "" - @echo "Local Development Commands:" - @echo " local-dev-shell - Enter the development shell with all tools" - @echo " local-deploy - Deploy local NixOS containers for testing" - @echo " local-ssh - SSH into a local participant container" - @echo " local-clean - Stop and destroy all local containers" + @echo "--- USB Drive Creation ---" + @echo " make usb-build - Build the NixOS ISO for the workshop" + @echo " make usb-flash - Flash the ISO to a USB drive (set USB_DEVICE)" + @echo "" + @echo "--- Host Development Shell ---" + @echo " make local-shell - Enter a dev shell with terraform, etc., on your main machine" + + +# --- Local Development --- +local-vm-run: + @echo "🚀 Starting local workshop environment inside a VM..." + @echo " (Close the VM window or press Ctrl+A, X to exit)" + nix run --impure .#local-vm # --- Cloud Infrastructure --- cloud-deploy: - @echo "🚀 Deploying to Hetzner Cloud..." ./scripts/deploy.sh -cloud-status: +status-cloud: @echo "📊 Checking server status..." @for name in hopper curie lovelace noether hamilton franklin johnson clarke goldberg liskov wing rosen shaw karp rich; do \ echo -n "$$name.${DOMAIN}: "; \ @@ -43,37 +49,22 @@ cloud-status: fi; \ done -cloud-destroy: - cd cloud && terraform destroy -auto-approve +destroy-cloud: + cd terraform && terraform destroy -auto-approve # --- USB Boot Drive --- usb-build: - @echo "🔨 Building NixOS workshop ISO..." - nix build .#packages.x86_64-linux.live-iso - @echo "✅ ISO built: result/iso/nixos.iso" + nix build .#live-iso -usb-flash: usb-build - @echo "⚠️ Flashing to ${USB_DEVICE} - THIS WILL ERASE THE DEVICE!" +flash-usb: usb-build + @echo "⚠️ Flashing to ${USB_DEVICE} - THIS WILL ERASE THE DEVICE!" @read -p "Continue? [y/N]: " confirm && [ "$$confirm" = "y" ] sudo dd if=result/iso/nixos.iso of=${USB_DEVICE} bs=4M status=progress oflag=sync @echo "✅ USB drive ready!" -# --- Local Development --- -local-dev-shell: +# --- Host Development --- +local-shell: nix develop -local-deploy: - @echo "🏠 Deploying local workshop environment..." - sudo nixos-rebuild switch --impure --flake .#workshop-local - @echo "✅ Local containers running!" - -local-ssh: - @read -p "Connect to participant number [1-15]: " num; \ - ssh root@192.168.100.$$((10 + $$num)) - -local-clean: - sudo nixos-container stop participant{1..15} || true - sudo nixos-container destroy participant{1..15} || true - clean: rm -rf result .direnv diff --git a/flake.nix b/flake.nix index 4a44158..989dc4f 100644 --- a/flake.nix +++ b/flake.nix @@ -1,5 +1,5 @@ { - description = "CODE CRISPIES Workshop Environment"; + description = "CODE CRISPIES Workshop Infrastructure"; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; @@ -9,6 +9,7 @@ outputs = { self, nixpkgs, nixos-generators }: let system = "x86_64-linux"; + pkgs = nixpkgs.legacyPackages.${system}; participantNames = [ "hopper" "curie" "lovelace" "noether" "hamilton" "franklin" "johnson" "clarke" "goldberg" "liskov" @@ -17,121 +18,122 @@ in { # -------------------------------------------------------------------------------- - # 1. USB BOOT DRIVE (ISO) - # `nix build .#live-iso` + # 1. PACKAGES (USB ISO and Local VM) # -------------------------------------------------------------------------------- - packages.${system}.live-iso = nixos-generators.nixosGenerate { - inherit system; - format = "iso"; - modules = [ - ({ pkgs, ... }: { - networking.networkmanager.enable = true; - systemd.services.workshop-wifi = { - wantedBy = [ "multi-user.target" ]; - after = [ "network.target" ]; - script = '' - ${pkgs.networkmanager}/bin/nmcli dev wifi connect "CODE_CRISPIES_GUEST" password "workshop2024" || true - ''; - }; + packages.${system} = { + # `nix build .#live-iso` + live-iso = nixos-generators.nixosGenerate { + inherit system; + format = "iso"; + modules = [ + ({ pkgs, ... }: { + system.stateVersion = "25.05"; + networking.networkmanager.enable = true; + systemd.services.workshop-wifi = { + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + script = '' + ${pkgs.networkmanager}/bin/nmcli dev wifi connect "CODE_CRISPIES_GUEST" password "workshop2024" || true + ''; + }; - services.getty.autologinUser = "workshop"; - users.users.workshop = { - isNormalUser = true; - shell = pkgs.zsh; - }; + services.getty.autologinUser = "workshop"; + users.users.workshop = { isNormalUser = true; shell = pkgs.zsh; }; - programs.zsh = { - enable = true; - interactiveShellInit = '' - echo "🍪 CODE CRISPIES Workshop Environment" - echo "📶 WiFi: CODE_CRISPIES_GUEST (auto-connecting...)" - echo "📡 Available servers:" - ${builtins.concatStringsSep "\n" (map (name: "echo \" - ${name}.codecrispi.es\"") participantNames)} - echo "" - echo "💡 Commands: connect | recipes | help" - - connect() { - [ -z "$1" ] && { echo "Usage: connect "; return 1; } - echo "🔗 Connecting to $1.codecrispi.es..." - ssh -o StrictHostKeyChecking=no workshop@$1.codecrispi.es - } - - recipes() { - echo "🍪 Featured Co-op Cloud Recipes: (wordpress, nextcloud, hedgedoc...)" - echo "Browse all 100+ recipes: https://recipes.coopcloud.tech" - } - - help() { + programs.zsh = { + enable = true; + interactiveShellInit = '' + echo "🍪 CODE CRISPIES Workshop Environment" echo "💡 Commands: connect | recipes | help" - } - ''; - }; - - environment.systemPackages = with pkgs; [ openssh curl git networkmanager ]; - services.xserver = { - enable = true; - displayManager.autoLogin.enable = true; - displayManager.autoLogin.user = "workshop"; - desktopManager.xfce.enable = true; - displayManager.sessionCommands = "${pkgs.xfce.xfce4-terminal}/bin/xfce4-terminal &"; - }; - }) - ]; + connect() { ssh -o StrictHostKeyChecking=no workshop@$1.codecrispi.es; } + recipes() { echo "Featured Recipes: wordpress, nextcloud, gitea..."; } + help() { echo "Commands: connect, recipes, help"; } + ''; + }; + + environment.systemPackages = with pkgs; [ openssh curl git networkmanager ]; + services.xserver = { + enable = true; + displayManager.autoLogin.enable = true; + displayManager.autoLogin.user = "workshop"; + desktopManager.xfce.enable = true; + displayManager.sessionCommands = "${pkgs.xfce.xfce4-terminal}/bin/xfce4-terminal &"; + }; + }) + ]; + }; + + # `nix run .#local-vm` + local-vm = self.nixosConfigurations.workshop-local.config.system.build.vm; }; # -------------------------------------------------------------------------------- - # 2. LOCAL DEVELOPMENT ENVIRONMENT (NixOS Containers) - # `make local-deploy` + # 2. LOCAL DEVELOPMENT VM CONFIGURATION # -------------------------------------------------------------------------------- nixosConfigurations.workshop-local = nixpkgs.lib.nixosSystem { inherit system; modules = [ - # Dynamically import the configuration for the current host machine. - ( - let - # Read the hostname and remove the trailing newline. - hostname = builtins.replaceStrings [ "\n" ] [ "" ] (builtins.readFile "/etc/hostname"); - in - # Build the correct path to the configuration file. - /etc/nixos/hosts/${hostname}/configuration.nix - ) + ( let hostname = builtins.replaceStrings [ "\n" ] [ "" ] (builtins.readFile "/etc/hostname"); + in "/etc/nixos/hosts/${hostname}/configuration.nix" ) - # Your container definitions are then added on top of the host config. - ({ pkgs, config, ... }: { - # Set this to your host's NixOS version (e.g., "23.11", "24.05") + ({ config, ... }: { system.stateVersion = "25.05"; + + # Use `gnumake` instead of `make` + environment.systemPackages = with pkgs; [ gnumake nano nixos-container ]; - containers = builtins.listToAttrs (map (i: - let - participantNum = toString i; - ipAddr = "192.168.100.${toString (10 + i)}"; - in - { - name = "participant${participantNum}"; + containers = builtins.listToAttrs (map (i: + let participant = builtins.elemAt participantNames (i - 1); + in { + name = "participant${toString i}"; value = { autoStart = true; privateNetwork = true; hostAddress = "192.168.100.1"; - localAddress = ipAddr; + localAddress = "192.168.100.${toString (10 + i)}"; config = { - system.stateVersion = "24.05"; - virtualisation.docker.enable = true; - environment.systemPackages = with pkgs; [ docker git curl ]; + system.stateVersion = "25.05"; services.openssh.enable = true; - networking.firewall.allowedTCPPorts = [ 22 80 443 ]; + # networking.hostName = "${participant}.local"; # <-- REMOVED this conflicting line + virtualisation.docker.enable = true; + environment.systemPackages = with pkgs; [ docker git curl jq ]; + systemd.services.workshop-setup = { + wantedBy = [ "multi-user.target" ]; + after = [ "docker.service" ]; + script = '' + ${pkgs.docker}/bin/docker swarm init --advertise-addr 192.168.100.${toString (10 + i)} || true + ${pkgs.docker}/bin/docker network create -d overlay proxy || true + export HOME=/root + ${pkgs.curl}/bin/curl -fsSL https://install.abra.coopcloud.tech | ${pkgs.bash}/bin/bash + mkdir -p /root/.abra/servers + /root/.local/bin/abra server add ${participant}.local + ''; + serviceConfig = { Type = "oneshot"; RemainAfterExit = true; }; + }; }; }; - }) (nixpkgs.lib.range 1 15)); + } + ) (nixpkgs.lib.range 1 2)); + + services.dnsmasq = { + enable = true; + settings.address = builtins.concatMap (i: + let participant = builtins.elemAt participantNames (i - 1); + in [ + "/${participant}.local/192.168.100.${toString (10 + i)}" + "/.${participant}.local/192.168.100.${toString (10 + i)}" + ] + ) (nixpkgs.lib.range 1 2); + }; }) ]; }; - + # -------------------------------------------------------------------------------- - # 3. DEVELOPMENT SHELL - # `nix develop` + # 3. DEVELOPMENT SHELL (for your host machine) # -------------------------------------------------------------------------------- - devShells.${system}.default = nixpkgs.legacyPackages.${system}.mkShell { - buildInputs = with nixpkgs.legacyPackages.${system}; [ + devShells.${system}.default = pkgs.mkShell { + buildInputs = with pkgs; [ terraform nixos-rebuild docker