unofficial mirror of help-guix@gnu.org 
 help / color / mirror / Atom feed
From: myglc2 <myglc2@gmail.com>
To: Hartmut Goebel <h.goebel@crazy-compilers.com>
Cc: help-guix@gnu.org
Subject: Re: Seeking working, complete example for a vm
Date: Mon, 31 Oct 2016 14:18:58 -0400	[thread overview]
Message-ID: <861sywgz59.fsf@gmail.com> (raw)
In-Reply-To: 58133002.2070804@crazy-compilers.com

[-- Attachment #1: Type: text/plain, Size: 498 bytes --]

On 10/28/2016 at 13:01 Hartmut Goebel writes:

> Hi,
>
> for a demonstration I need to set up a container running nginx and
> postres and maybe ssh. nginx and ssh should be accessible from outside
> the vm, at least from the host. 

In an effort to reply to your request for a "working, complete example,"
I attach the hackage that I use to manage the care and feeding of
LAN-visible GuixSD VM images running on a headless GuixSD server.

For details please see the comments in 'aba'

HTH - George

[-- Attachment #2: aba --]
[-- Type: application/octet-stream, Size: 6291 bytes --]

#!/run/current-system/profile/bin/bash

# set -ex

# Run GuixSD VM image using QEMU/KVM and, optionally, TAP routed
# networking.

# naming conventions:
#   script name must be:    3 chars selected from [0-9A-G]
#   VM name (NAME) will be: <scriptname><0|vm#>
#   MAC address will be:    AA:00:00:00:NA:ME
#   IP address will be:     192.168.1.131
#   gateway will be:        192.168.1.1
#   DNS will be             192.168.1.1

# Addresses are set by this script or by running sed on the VM config
# file which is, by default, named: <scriptname>.scm

# example:
# script name: aba
# make vm:     ./aba mk 3
# run  vm:     sudo ./aba run 3
# VM name:     aba3
# MAC:         AA:00:00:00:AB:A3

# Cheat Sheet:
# ./aba mk 1                 # make VM aba1
# sudo ./aba route 1         # enable LAN access
# sudo ./aba x 1             # start VM w/ X Window console
#      - play the pianno     # provide randomness for key gen
#      - login root          # log in as root
#        - passwd g1         # set user g1 password
#        - shutdown          # shut down the VM
# sudo ./aba up 1            # run VM in background
# ssh g1@192.168.1.31        # log in to VM aba1 from LAN client

# usage details:

# $ ./<scriptname> mk  [vm#]
#                make VM

# Every VM must be initilized by either 'run' or 'x' in order to "play
# the piano" on the consoleto create the random seed and to set
# passwords for root and users:

# $ sudo ./<scriptname> run [vm#]
#                run and open console in terminal so we can
#                "play the piano" to generate random seed.
#                NOTE: when you kill the console the VM dies

# $ sudo ./<scriptname> x   [vm#]
#                run in bg & open console in X window
#                NOTE: when you kill X console the VM will dies
 
# After being initilized, a VM may be taken up or down

# $ sudo ./<scriptname> up  [vm#]
#                bring VM up in bg w/ no console

# To control LAN access to the VM, 'route' or 'unroute' it.

# $ sudo ./<scriptname> route [vm#]
#                set up LAN routing

# $ sudo ./<scriptname> unroute [vm#]
#                take down LAN routing

# to display the currently running VMs and enabled LAN routes

# $ ./<scriptname> show
#                show the running VMs and routed TAP interfaces

CMD=`basename "$0"`
VMNUM=${2:-""}
NAME=$CMD$VMNUM
VMDIR=$PWD/vm/$NAME
# TODO support NAME length > 4 char
MACIN=AA000000$NAME
MAC=$(echo $MACIN | sed -e 's/[0-9A-Fa-f]\{2\}/&:/g' -e 's/:$//')

case $1 in
    mk)
	mkdir -p vm
	# fail so we don't clobber an existing VM
	mkdir $VMDIR
	cp -f $CMD $VMDIR/$CMD
	# make an image
	# save the vm config
	sed s/v1/$NAME/ aba.scm > $VMDIR/v0.scm
	sed s/31/3$VMNUM/ $VMDIR/v0.scm > $VMDIR/v1.scm
	# save guix version 
	(stat $HOME/.config/guix/latest | grep File:) > $VMDIR/guix-version
	# save guix config
	git -C ~/.config/guix/latest branch -av | grep '* master' >> $VMDIR/guix-version
	# be sure the version of guix we have checked out is the one we are using
	make -C $HOME/.config/guix/latest -s > $VMDIR/guix-make.log
	# make vm image & copy from store
	cp -f $(guix system vm-image $VMDIR/v1.scm --image-size=4GB) $VMDIR/vm.img
	# make the image writeable
	chmod u+w $VMDIR/vm.img
	;;

    destroy)
	# destroy the vm
	rm -fr $VMDIR
	;;

    route)
	# TODO take-down and restart if already exists
	# enable LAN access via ARP proxy
	sudo sysctl -w net.ipv4.ip_forward=1            # allow IPv4 forwarding
	sudo sysctl net.ipv4.conf.enp2s0.proxy_arp=1    # publish routing info for interface
	# create the TAP device with ARP proxy
	ip tuntap add dev $NAME mode tap                # create TAP device
	ip link set $NAME up                            # turn TAP device on
	sudo route add 192.168.1.13$VMNUM dev $NAME     # add route to the TAP device
	sudo sysctl net.ipv4.conf.$NAME.proxy_arp=1     # ARP proxy
	;;

    unroute)
	# remove the TAP device with ARP proxy
	sudo sysctl net.ipv4.conf.$NAME.proxy_arp=0     # disable ARP proxy
	sudo route del 192.168.1.13$VMNUM dev $NAME     # delete route to the TAP device
	ip link set $NAME down                          # turn TAP device off
	ip tuntap del dev $NAME mode tap                # delete TAP device
	;;

    run)
	# run console in foreground in terminal
	# note: qemu-ifup and qemu-ifdn are no-ops specified to avoid default call to /dev/net/tun which fails
	echo starting VM: $NAME w/MAC: $MAC
	qemu-system-x86_64 \
	    -net tap,ifname=$NAME,vlan=0,script=/home/g1/src/vma/qemu-ifup,downscript=/home/g1/src/vma/qemu-ifdn \
	    -net nic,model=virtio,macaddr=$MAC \
	    -enable-kvm \
	    -m 4096 \
	    -curses \
	    -name $NAME \
	    $VMDIR/vm.img
	;;

    x)
	# run console in background w/console in X window
	echo starting VM: $NAME w/MAC: $MAC
	# note: '-k en-us' seems required for Mac XQuartz keymap, but option it still broken
	qemu-system-x86_64 \
	    -net tap,ifname=$NAME,vlan=0,script=/home/g1/src/vma/qemu-ifup,downscript=/home/g1/src/vma/qemu-ifdn \
	    -net nic,model=virtio,macaddr=$MAC \
	    -enable-kvm \
	    -m 4096 \
	    -k en-us \
	    -daemonize \
	    -name $NAME \
	    $VMDIR/vm.img
	;;

    up)
	# run in bg with inaccessible console
	echo starting VM: $NAME w/MAC: $MAC
	qemu-system-x86_64 \
	    -net tap,ifname=$NAME,vlan=0,script=/home/g1/src/vma/qemu-ifup,downscript=/home/g1/src/vma/qemu-ifdn \
	    -net nic,model=virtio,macaddr=$MAC \
	    -enable-kvm \
	    -m 4096 \
	    -daemonize \
	    -display none \
	    -name $NAME \
	    $VMDIR/vm.img
	;;

    show)
	# show info about VMs
	echo VMs Available: `ls vm`
	echo VMs running:
	pstree -ap | grep tap | grep -v grep
	echo VMs routed:
	ip a | grep aba
	;;

    *)
	echo ERROR: you typed: \"$CMD $*\" which has missing arguments or invalid arguments
	echo Cheat Sheet: 
	echo ./aba mk 1                 # make VM aba1
	echo sudo ./aba route 1         # enable LAN access
	echo sudo ./aba x 1             # start VM w/ X Window console
	echo      - play the pianno     # provide randomness for key gen
	echo      - login root          # log in as root
	echo        - passwd g1         # set user g1 password
	echo        - shutdown          # shut down the VM
	echo sudo ./aba up 1            # run VM in background
	echo ssh g1@192.168.1.31        # log in to VM from LAN client	
esac

[-- Attachment #3: aba.scm --]
[-- Type: application/octet-stream, Size: 1803 bytes --]

;;; v1 system config
;;; following http://paste.lisp.org/display/145436
(use-modules (gnu))
(use-service-modules networking ssh)
(use-package-modules
 base                  ; glibc-utf8-locales
 admin
 disk
 linux                 ; mdadm
 package-management    ; guix
 screen
 ghostscript           ; gs-fonts
 fonts                 ; font-dejavu font-gnu-freefont-ttf
 curl                  ;lpaste
 ssh                   ; openssh mosh
 rsync
 wget
 version-control       ; git
 aspell                ; aspell-dict-en
 emacs                 ; emacs-no-x-toolkit
 gv
 autotools             ; automake
 texinfo
 gettext
 xorg certs
 graphviz
 qemu
 )
(operating-system
  (host-name "v1")
  (timezone "America/New_York")
  (locale "en_US.utf8")
  (bootloader (grub-configuration (device "/dev/sda")))
  (file-systems (cons (file-system
			(device "g1sd")
			(title 'label)
			(mount-point "/")
			(type "ext4"))
		      %base-file-systems))
  (users (cons* (user-account
		 (name "g1")
		 (group "users")
		 (supplementary-groups '("wheel" "kvm"))
		 (home-directory "/home/g1"))
		%base-user-accounts))
  (packages
   (cons*
    glibc-utf8-locales
    parted
    qemu
    guix
    screen
    openssh nss-certs xauth mosh
    rsync wget curl ;lpaste
    git
    gs-fonts font-dejavu font-gnu-freefont-ttf
    aspell aspell-dict-en
    emacs-no-x-toolkit 
    flycheck paredit magit gv
    emacs-zenburn-theme emacs-markdown-mode emacs-web-mode 
    gnu-make
    texinfo
    automake
    graphviz
    gnu-make
    texinfo automake
    %base-packages))
  (services (cons*
	     ;; (dhcp-client-service)
	     ;; Ethernet.
	     (static-networking-service "eth0" "192.168.1.131"
					#:gateway "192.168.1.1"
					#:name-servers '("192.168.1.1"))
	     (lsh-service #:root-login? #t)
	     %base-services)))

[-- Attachment #4: qemu-ifdn --]
[-- Type: application/octet-stream, Size: 360 bytes --]

#!/run/current-system/profile/bin/bash
set -e

bridge=br0

if [ -n "$1" ];then
    # operations we could do to take a QEMU TAP interface down
    # but which seem to be unnecessary.
    # ip link set $1 down
    sleep 0.5s
    # ip link set $1 nomaster
    # ip tuntap del dev $1 mode tap
    exit 0
else
    echo "Error: no interface specified"
    exit 1
fi

[-- Attachment #5: qemu-ifup --]
[-- Type: application/octet-stream, Size: 437 bytes --]

#!/run/current-system/profile/bin/bash
set -e

bridge=br0

if [ -n "$1" ];then    
    # QEMU -net tap,ifname=$NAME,vlan=0 seems effect the operation below
    # ip tuntap add dev $1 mode tap # user `whoami`
    # but we need to enslave the interface to the desired bridge
    # ip link set $1 up
    sleep 0.5s
    # ip link set $1 master $bridge
    # bridge link
    exit 0
else
    echo "Error: no interface specified"
    exit 1
fi

  parent reply	other threads:[~2016-10-31 18:17 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-10-28 11:01 Seeking working, complete example for a vm Hartmut Goebel
2016-10-28 16:27 ` Leo Famulari
2016-10-28 16:52   ` Hartmut Goebel
2016-10-28 18:07     ` Leo Famulari
2016-10-28 23:49       ` Ludovic Courtès
2016-10-28 23:57 ` Ludovic Courtès
2016-11-02 22:09   ` Hartmut Goebel
2016-10-31 18:18 ` myglc2 [this message]
     [not found]   ` <be122fc0-6302-31ec-c9a9-8ebfc50d3824@crazy-compilers.com>
2016-11-03  1:20     ` myglc2

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://guix.gnu.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=861sywgz59.fsf@gmail.com \
    --to=myglc2@gmail.com \
    --cc=h.goebel@crazy-compilers.com \
    --cc=help-guix@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).