]> gitweb.fluxo.info Git - kvm-manager.git/commitdiff
switch from KVMOPTS to HDA HDB HDC HDD; use udev to set the ownership for the block...
authorDaniel Kahn Gillmor <dkg@fifthhorseman.net>
Sun, 15 Nov 2009 23:25:08 +0000 (18:25 -0500)
committerDaniel Kahn Gillmor <dkg@fifthhorseman.net>
Sun, 15 Nov 2009 23:25:08 +0000 (18:25 -0500)
kvm-creator
kvm-manager

index e2c0ca9bd8fc7e719d3809f7f45a627dd32680df..8d083ecdd4b0e332e6501e488cdfad7e2293715f 100755 (executable)
@@ -9,11 +9,18 @@ CMD="$1"
 shift
 
 NAME="$1"
+# FIXME: make this default to the only vg (if only one vg exists), or to vg_$(hostname0) or $(hostname), if those VGs exist
 VG="${2:-vg_$(hostname)0}"
 SIZE="${3:-3G}"
 RAM="${4:-512}"
 DISK="/dev/mapper/${VG}-${NAME}"
 
+# for managing udev (we want to make sure that logical volumes get
+# created with ownership by the controlling user:
+UDEV_RULES_FILE="/etc/udev/rules.d/92-kvm_creator-%s.rules"
+# Why choose 92?  /usr/share/doc/udev/README.Debian.gz says after 91
+# default permissions and ownership are set.
+
 [ "$CMD" == "create" ] && mkdir -p /etc/sv/kvm
 
 ls /etc/sv/kvm/* &> /dev/null
@@ -47,22 +54,43 @@ destroy() {
     rm -rf "/etc/sv/kvm/$NAME"
     deluser --remove-home "$NAME"
     lvremove "$VG/$NAME"
+    rm -f "$(udevrulename "$NAME")"
 
 }
 
 validate() {
 
+  errors=""
+
   # Make sure none of the pieces already exist.
-  [ -z "$NAME" ] && die "Please pass the name of the virtual server to create" || :
-  [ -z "$VG" ] && [ "$CMD" == "create" ] && die "Please pass the name of the volume group to use" || :
-  getent passwd "$NAME" > /dev/null && die "The username '$NAME' already exists." || :
-  getent group "$NAME" > /dev/null && die "The group '$NAME' already exists." || :
-  [ -d /home/"$NAME" ] && die "The directory '/home/$NAME' already exists." || :
-  [ -d /etc/sv/kvm/"$NAME" ] && die "The directory '/etc/sv/kvm/$NAME' already exists." || :
-  [ -e $DISK ] && die "The logical volume $NAME already exists." || :
+  [ -z "$NAME" ] && errors=$(printf "%s\n%s" "$errors" "Please pass the name of the virtual server to create") || :
+  [ -z "$VG" ] && errors=$(printf "%s\n%s" "$errors"  "Please pass the name of the volume group to use") || :
+  vgs --noheadings --unbuffered -o name | tr -d ' ' | grep -q -F -x "$VG" || errors=$(printf "%s\n%s" "$errors"  "Please pass the name of the volume group to use") || :
+  getent passwd "$NAME" > /dev/null && errors=$(printf "%s\n%s" "$errors" "The username '$NAME' already exists.") || :
+  getent group "$NAME" > /dev/null && errors=$(printf "%s\n%s" "The group '$NAME' already exists.") || :
+  [ -d /home/"$NAME" ] && errors=$(printf "%s\n%s" "The directory '/home/$NAME' already exists.") || :
+  [ -d /etc/sv/kvm/"$NAME" ] && errors=$(printf "%s\n%s" "The directory '/etc/sv/kvm/$NAME' already exists.") || :
+  [ -e $DISK ] && errors=$(printf "%s\n%s" "The logical volume $NAME already exists.") || :
+  [ -e "$(udevrulename "$NAME")" ] && errors=$(printf "%s\n%s" "The udev rules file '$(udevrulename "$NAME")' already exists.") || :
+
+  [ -z "$errors" ] || die "$errors"
 
 }
 
+udevrule() {
+    VOLUME_GROUP="$1"
+    LOGICAL_VOLUME="$2"
+    GROUP="$3"
+
+    # this appears to be the way that a udev rule to control the LVM device gets created:
+
+    printf 'ACTION=="change", SUBSYSTEM=="block", ATTR{dm/name}=="%s-%s", GROUP="%s"\n' "$VOLUME_GROUP" "$LOGICAL_VOLUME" "$GROUP" 
+}
+
+udevrulename() {
+    printf "$UDEV_RULES_FILE" "$1"
+}
+
 create() {
 
     set -e
@@ -75,6 +103,13 @@ create() {
         # is this really the right thing to do?
         cp /root/.ssh/authorized_keys "$USERHOMEDIR/.ssh/"
     fi
+    USERGID="$(getent passwd "$OWNER")"
+    USERGID="$(cut -f4 -d: <<<$USERGID)"
+    USERGROUP="$(getent group "$USERGID")"
+    USERGROUP=${USERGROUP%%:*}
+    udevrule "$VG" "$NAME" "$USERGROUP" > $(udevrulename "$NAME")
+
     lvcreate --name "$NAME" --size "$SIZE" $VG
     mkdir "/etc/sv/kvm/$NAME"{,/log,/env}
     cat > "/etc/sv/kvm/$NAME/log/run" <<EOF
@@ -101,7 +136,7 @@ EOF
     echo "$TAP" > "/etc/sv/kvm/$NAME/env/TAP"
     echo "$RAM" > "/etc/sv/kvm/$NAME/env/RAM"
     echo "$MAC" > "/etc/sv/kvm/$NAME/env/MAC"
-               echo "$DISK" > "/etc/sv/kvm/$NAME/env/KVMOPTS"
+    echo "$DISK" > "/etc/sv/kvm/$NAME/env/HDA"
 
 }
 
index 04c024a2fc70613fc3f25b82f537f0321cc10dd1..aee3dbb0f7bb16a507f5a57cd378c4e918e9d1bc 100755 (executable)
@@ -13,7 +13,10 @@ set -x
 # TAP=tap0
 # RAM=512
 # MAC=52:54:00:12:34:56
-# KVMOPTS=/path/to/disk
+# HDA=/path/to/disk0 # optional
+# HDB=/path/to/disk1 # optional
+# HDC=/path/to/disk2 # optional
+# HDD=/path/to/disk3 # optional
 
 if [ -z "$VMNAME" ] ; then
     exit 1
@@ -32,9 +35,6 @@ up() {
     ip link set "$TAP" up
     brctl addif br0 "$TAP"
     
-# make sure the block device is readable by the owner:
-    chgrp "$OWNERGROUP" "/dev/mapper/${VGNAME}-$VMNAME"
-    
     chpst -u "$OWNER:$OWNERGROUP" mkdir -p "$OWNERHOME/vms/$VMNAME"
 
     CDISO="$OWNERHOME/vms/$VMNAME/cd.iso"
@@ -47,13 +47,19 @@ up() {
        KVMARGS="-cdrom $CDISO -boot d"
     fi
 
+    # set up the disks, if needed:
+    [ -z "$HDA" ] || KVMARGS="$KVMARGS -hda $HDA"
+    [ -z "$HDB" ] || KVMARGS="$KVMARGS -hdb $HDB"
+    [ -z "$HDC" ] || KVMARGS="$KVMARGS -hdc $HDC"
+    [ -z "$HDD" ] || KVMARGS="$KVMARGS -hdd $HDD"
+
     LOGNAME="$OWNERHOME/vms/$VMNAME/console"
     ln -sfT "$LOGNAME" ./servicelog
     if [ -e "$LOGNAME" ] ; then
        chpst -u "$OWNER" mv "$LOGNAME" "$LOGNAME".$(date +%F_%T%z|tr : .)
     fi
 
-    exec chpst -u "$OWNER:$OWNERGROUP:kvm" /usr/bin/screen -D -m -L -c /etc/screenrc.kvm-manager -S "$VMNAME" -t "$VMNAME" -s /bin/false /usr/bin/kvm $KVMARGS -nographic -name "$VMNAME" -m "$RAM" -net nic,"macaddr=$MAC" -net "tap,hostname=$VMNAME,ifname=$TAP,script=no,downscript=no" -no-reboot -serial stdio "$KVMOPTS" 
+    exec chpst -u "$OWNER:$OWNERGROUP:kvm" /usr/bin/screen -D -m -L -c /etc/screenrc.kvm-manager -S "$VMNAME" -t "$VMNAME" -s /bin/false /usr/bin/kvm $KVMARGS -nographic -name "$VMNAME" -m "$RAM" -net nic,"macaddr=$MAC" -net "tap,hostname=$VMNAME,ifname=$TAP,script=no,downscript=no" -no-reboot -serial stdio
 }