(define-module (msg machine) #:use-module (ice-9 match) #:use-module (ice-9 rdelim) #:use-module (ice-9 textual-ports) #:use-module (system foreign) #:use-module (msg helpers) #:use-module (msg config) #:export (machine)) (define home-path (getenv "HOME")) (define arch (run-shell-command "uname -m")) (define cpu-conf #f) (define mem-conf #f) (define* (load-config #:optional args) (define config-file (format #f "~a/.guix/qemu/config.scm" home-path)) (define loaded-config (manage-config config-file)) (if (not (null? loaded-config)) (begin (set! cpu-conf (cdr (assoc 'cpu loaded-config))) (set! mem-conf (cdr (assoc 'mem loaded-config))) #t) #f)) (define* (machine #:optional (args (command-line))) ;;(define clean-args (cdr args)) (match args (("-h") (help)) (("init" rest ...) (init rest)) (("reinit") (stop) (clear-install) (init)) (("start" rest ...) (start rest)) (("stop") (stop)) (("rm") (stop) (clear-install)) (_ (display "Please enter a valid command or -h for help.\n")))) (define* (help) (display "\nHere are the available commands:\n\n") (display "start: Start the MSG envrionment.\n")) (define* (clear-install) (let loop () (display "This is a destructive command and will remove your entire Guix instance. Proceed? (y/n)\n") (define response (read-line)) (cond ((string=? response "y") (system "rm -r ~/.guix") ) ((string=? response "n") (display "Operation canceled.\n") (exit 0)) (else (display "Please enter a valid response.\n") (loop))))) (define* (start #:optional args) (define config (load-config)) (if (not (directory-exists? (format #f "~a/.guix" home-path))) (begin (display "MSG not initialized. Please run `msg machine init` to continue. If you already tried to install and are receiving this message, try running `msg machine reinit`") (exit 0))) (cond ((string=? arch "arm64") (system (format #f "/opt/homebrew/bin/qemu-system-aarch64 \ -machine virt,highmem=on \ -accel hvf \ -cpu cortex-a57 \ -smp ~a \ -display none \ -hda $HOME/.guix/qemu/guix-user.qcow2 \ -m ~aG \ -virtfs local,path=/Users,security_model=mapped,mount_tag=macos \ -bios /opt/homebrew/opt/qemu/share/qemu/edk2-aarch64-code.fd \ -device virtio-net,netdev=vmnic \ -netdev user,id=vmnic,hostfwd=tcp:127.0.0.1:9001-:22 &" cpu-conf mem-conf))) ((string=? arch "x86_64") (system (format #f "/usr/local/bin/qemu-system-x86_64 \ -machine type=q35,accel=hvf \ -smp ~a \ -hda $HOME/.guix/qemu/guix-user.qcow2 \ -m ~aG \ -display none \ -cpu Nehalem \ -virtfs local,path=/Users,security_model=mapped,mount_tag=macos \ -device virtio-net,netdev=vmnic \ -netdev user,id=vmnic,hostfwd=tcp:127.0.0.1:9001-:22 &" cpu-conf mem-conf)))) (display "MSG has been started") ) (define* (stop) (system "ssh -o StrictHostKeyChecking=no -i $HOME/.guix/ssh-cert/msg_rsa admin@127.0.0.1 -p 9001 'sudo shutdown'")) (define* (init #:optional args) (if (not (directory-exists? (format #f "~a/.guix" home-path))) (begin ;; Grab ssh cert for installer (system "mkdir -p $HOME/.guix/qemu $HOME/.guix/home $HOME/.guix/ssh-cert") (system "ssh-keygen -R \"[127.0.0.1]:9001\"") ;; Download system image and and start vm (cond ((string=? arch "arm64") (system "/opt/homebrew/bin/wget https://objectstorage.us-phoenix-1.oraclecloud.com/n/axfgkze2xif1/b/guix-system/o/msg-system-aarch64guix-installer.qcow2.tar.gz -O $HOME/.guix/qemu/guix.qcow2.tar.gz") (system "tar -xvzf $HOME/.guix/qemu/guix.qcow2.tar.gz -C $HOME/.guix/qemu/") (system "/opt/homebrew/bin/wget https://objectstorage.us-phoenix-1.oraclecloud.com/n/axfgkze2xif1/b/guix-system/o/msg-system-aarch64config.scm -O $HOME/.guix/home/config.scm") ;; Get msg ssh-key (system "/opt/homebrew/bin/wget https://objectstorage.us-phoenix-1.oraclecloud.com/n/axfgkze2xif1/b/guix-system/o/msg_rsa -O $HOME/.guix/ssh-cert/msg_rsa") (system "chmod 400 ~/.guix/ssh-cert/msg_rsa ") (system "/opt/homebrew/bin/qemu-system-aarch64 \ -machine virt,highmem=on \ -accel hvf \ -cpu cortex-a57 \ -smp 4 \ -display none \ -hda $HOME/.guix/qemu/guix-user.qcow2 \ -m 4G \ -virtfs local,path=$HOME/.guix/home,security_model=mapped,mount_tag=macos \ -bios /opt/homebrew/opt/qemu/share/qemu/edk2-aarch64-code.fd \ -device virtio-net,netdev=vmnic \ -netdev user,id=vmnic,hostfwd=tcp:127.0.0.1:9001-:22 &") (sleep 5) (update-uid) (build-msg) (system "ssh -o StrictHostKeyChecking=no -i $HOME/.guix/ssh-cert/msg_rsa root@127.0.0.1 -p 9001 'shutdown'") (system "ssh-keygen -R \"[127.0.0.1]:9001\"") (sleep 30) (system "rm ~/.guix/qemu/guix-user.qcow2") (system "mv ~/.guix/home/guix-user.qcow2 ~/.guix/qemu/") (start) (sleep 15) (system "ssh -o StrictHostKeyChecking=no -i $HOME/.guix/ssh-cert/msg_rsa admin@127.0.0.1 -p 9001 'sudo mkdir /Users /boot/efi'") (system "ssh -o StrictHostKeyChecking=no -i $HOME/.guix/ssh-cert/msg_rsa admin@127.0.0.1 -p 9001 'sudo mount /dev/vda1 /boot/efi'")) ((string=? arch "x86_64") (system "/usr/local/bin/wget https://objectstorage.us-phoenix-1.oraclecloud.com/n/axfgkze2xif1/b/guix-system/o/msg-system-x86_64guix-installer.qcow2.tar.gz -O $HOME/.guix/qemu/guix.qcow2.tar.gz") (system "tar -xvzf $HOME/.guix/qemu/guix.qcow2.tar.gz -C $HOME/.guix/qemu/") (system "/usr/local/bin/wget https://objectstorage.us-phoenix-1.oraclecloud.com/n/axfgkze2xif1/b/guix-system/o/msg-system-x86_64config.scm -O $HOME/.guix/home/config.scm") ;; Get msg ssh-key (system "/usr/local/bin/wget https://objectstorage.us-phoenix-1.oraclecloud.com/n/axfgkze2xif1/b/guix-system/o/msg_rsa -O $HOME/.guix/ssh-cert/msg_rsa") (system "chmod 400 ~/.guix/ssh-cert/msg_rsa ") (system "/usr/local/bin/qemu-system-x86_64 \ -machine type=q35,accel=hvf \ -smp 4 \ -hda $HOME/.guix/qemu/guix-installer.qcow2 \ -m 4G \ -display none \ -cpu Nehalem \ -virtfs local,path=$HOME/.guix/home,security_model=mapped,mount_tag=macos \ -device virtio-net,netdev=vmnic \ -netdev user,id=vmnic,hostfwd=tcp:127.0.0.1:9001-:22 &") (sleep 5) (update-uid) (build-msg) (system "ssh -o StrictHostKeyChecking=no -i $HOME/.guix/ssh-cert/msg_rsa root@127.0.0.1 -p 9001 'shutdown'") (system "ssh-keygen -R \"[127.0.0.1]:9001\"") (sleep 30) (system "rm ~/.guix/qemu/guix-installer.qcow2") (system "mv ~/.guix/home/guix-user.qcow2 ~/.guix/qemu/") (start) (sleep 15) (system "ssh -o StrictHostKeyChecking=no -i $HOME/.guix/ssh-cert/msg_rsa admin@127.0.0.1 -p 9001 'sudo mkdir /Users'")) ) (newline) (display "Reconfiguring MSG, this may take a few minutes...") (system "ssh -o StrictHostKeyChecking=no -i $HOME/.guix/ssh-cert/msg_rsa admin@127.0.0.1 -p 9001 'sudo guix system reconfigure --allow-downgrades /etc/config.scm'") (system "ssh -o StrictHostKeyChecking=no -i $HOME/.guix/ssh-cert/msg_rsa admin@127.0.0.1 -p 9001 'sudo shutdown'") (display "\nMSG is ready to be started. Run 'msg machine start' to begin.\n")) (display "MSG already initialized. Please run `msg machine reinit` if you would like to recreate it.")) ) (define (build-msg) ;; Build MSG (define* filename (run-shell-command "ssh -o StrictHostKeyChecking=no -i $HOME/.guix/ssh-cert/msg_rsa root@127.0.0.1 -p 9001 'guix system image -t qcow2 --save-provenance --image-size=100G /etc/config.scm'")) (system (format #f "ssh -o StrictHostKeyChecking=no -i $HOME/.guix/ssh-cert/msg_rsa root@127.0.0.1 -p 9001 'cp ~a /mnt/macos/guix-user.qcow2'" filename))) (define (update-uid) ;; Update UID for msg image (system "sed -i.bak \"s/\\$UID/$(id -u)/g\" ~/.guix/home/config.scm && rm ~/.guix/home/config.scm.bak") (system "ssh -o StrictHostKeyChecking=no -i $HOME/.guix/ssh-cert/msg_rsa root@127.0.0.1 -p 9001 'cp /mnt/macos/config.scm /etc/config.scm'"))