Initial public commit.
(c) 2010 Invisible Things Lab Authors: ========= Joanna Rutkowska <joanna@invisiblethingslab.com> Rafal Wojtczuk <rafal@invisiblethingslab.com>
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
rpm/
|
||||
*.pyc
|
18
Makefile
Normal file
@ -0,0 +1,18 @@
|
||||
RPMS_DIR=rpm/
|
||||
help:
|
||||
@echo "make rpms -- generate binary rpm packages"
|
||||
@echo "make update_repo -- copy newly generated rpms to qubes yum repo"
|
||||
|
||||
rpms:
|
||||
rpmbuild --define "_rpmdir $(RPMS_DIR)" -bb rpm_spec/core-appvm.spec
|
||||
rpmbuild --define "_rpmdir $(RPMS_DIR)" -bb rpm_spec/core-netvm.spec
|
||||
rpmbuild --define "_rpmdir $(RPMS_DIR)" -bb rpm_spec/core-dom0.spec
|
||||
rpmbuild --define "_rpmdir $(RPMS_DIR)" -bb rpm_spec/dom0-cleanup.spec
|
||||
rpm --addsign $(RPMS_DIR)/x86_64/*.rpm
|
||||
|
||||
update_repo:
|
||||
ln -f $(RPMS_DIR)/x86_64/*.rpm ../yum/rpm/
|
||||
(if [ -d $(RPMS_DIR)/i686 ] ; then ln -f $(RPMS_DIR)/i686/*.rpm ../yum/rpm/; fi)
|
||||
|
||||
clean:
|
||||
(cd appvm && make clean)
|
16
TODO
Normal file
@ -0,0 +1,16 @@
|
||||
* file exchange -- handle correctly files that have spaces in name
|
||||
-- qvm-copy-to-vm* do not copy files in the top directory has spaces in the name
|
||||
|
||||
* qvm-update-appmenus
|
||||
-- let the user install appmenus for (potential) new apps after template update
|
||||
-- BUT: potential problem of Dom0 needing to mount the template's fs
|
||||
-- but: perhaps we should trust the template and its update process?
|
||||
|
||||
* netvm: prevent inter-VM networking
|
||||
-- do not allow one AppVM to send any packets to other AppVMs that use the same netvm
|
||||
|
||||
* qvm-prefs: allow to grow/shrink AppVM's private.img?
|
||||
|
||||
* Dom0 udev scripts: do not load network drivers at all!
|
||||
|
||||
* Dom0: detect when running without VT-d enabled and display a warning
|
9
appvm/Makefile
Normal file
@ -0,0 +1,9 @@
|
||||
CC=gcc
|
||||
CFLAGS=-Wall
|
||||
all: qubes_penctl qubes_add_pendrive_script
|
||||
qubes_penctl: qubes_penctl.o
|
||||
$(CC) -o qubes_penctl qubes_penctl.o -lxenstore
|
||||
qubes_add_pendrive_script: qubes_add_pendrive_script.o
|
||||
$(CC) -o qubes_add_pendrive_script qubes_add_pendrive_script.o
|
||||
clean:
|
||||
rm -f qubes_penctl qubes_add_pendrive_script *.o *~
|
17
appvm/fstab
Normal file
@ -0,0 +1,17 @@
|
||||
|
||||
#
|
||||
# /etc/fstab
|
||||
# Created by anaconda on Thu Dec 3 11:26:49 2009
|
||||
#
|
||||
# Accessible filesystems, by reference, are maintained under '/dev/disk'
|
||||
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
|
||||
#
|
||||
/dev/mapper/dmroot / ext4 defaults,noatime 1 1
|
||||
/dev/mapper/dmswap swap swap defaults 0 0
|
||||
/dev/xvdb /rw ext4 defaults 0 0
|
||||
tmpfs /dev/shm tmpfs defaults 0 0
|
||||
devpts /dev/pts devpts gid=5,mode=620 0 0
|
||||
sysfs /sys sysfs defaults 0 0
|
||||
proc /proc proc defaults 0 0
|
||||
/dev/xvdg /mnt/outgoing vfat noauto,user,rw 0 0
|
||||
/dev/xvdh /mnt/incoming vfat noauto,user,rw 0 0
|
12
appvm/iptables
Normal file
@ -0,0 +1,12 @@
|
||||
# Firewall configuration written by system-config-firewall
|
||||
# Manual customization of this file is not recommended.
|
||||
*filter
|
||||
:INPUT ACCEPT [0:0]
|
||||
:FORWARD ACCEPT [0:0]
|
||||
:OUTPUT ACCEPT [0:0]
|
||||
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
|
||||
-A INPUT -p icmp -j ACCEPT
|
||||
-A INPUT -i lo -j ACCEPT
|
||||
-A INPUT -j REJECT --reject-with icmp-host-prohibited
|
||||
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
|
||||
COMMIT
|
1
appvm/qubes.rules
Normal file
@ -0,0 +1 @@
|
||||
SUBSYSTEM=="block", KERNEL=="xvdh", ACTION=="add", RUN+="/usr/bin/qubes_add_pendrive_script"
|
87
appvm/qubes_add_pendrive_script.c
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* The Qubes OS Project, http://www.qubes-os.org
|
||||
*
|
||||
* Copyright (C) 2010 Rafal Wojtczuk <rafal@invisiblethingslab.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/inotify.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
int parse_events(char *buf, int len)
|
||||
{
|
||||
int i = 0;
|
||||
while (i < len) {
|
||||
struct inotify_event *ev = (struct inotify_event *)(buf + i);
|
||||
if ((ev->mask & IN_UNMOUNT) || (ev->mask & IN_IGNORED))
|
||||
return 1;
|
||||
i += sizeof(struct inotify_event) + ev->len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define BUFLEN 1024
|
||||
void wait_for_umount(char *name)
|
||||
{
|
||||
char buf[BUFLEN];
|
||||
int fd = inotify_init();
|
||||
int len;
|
||||
int ret = inotify_add_watch(fd, name, IN_ATTRIB);
|
||||
if (ret < 0) {
|
||||
perror("inotify_add_watch");
|
||||
return;
|
||||
}
|
||||
for (;;) {
|
||||
len = read(fd, buf, BUFLEN - 1);
|
||||
if (len <= 0) {
|
||||
perror("read inotify");
|
||||
return;
|
||||
}
|
||||
if (parse_events(buf, len))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void background()
|
||||
{
|
||||
int i, fd;
|
||||
for (i = 0; i < 256; i++)
|
||||
close(i);
|
||||
fd = open("/dev/null", O_RDWR);
|
||||
for (i = 0; i <= 2; i++)
|
||||
dup2(fd, i);
|
||||
switch (fork()) {
|
||||
case -1:
|
||||
exit(1);
|
||||
case 0: break;
|
||||
default:
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define MOUNTDIR "/mnt/incoming"
|
||||
int main()
|
||||
{
|
||||
background();
|
||||
if (!system("su - user -c 'mount " MOUNTDIR "'"))
|
||||
wait_for_umount(MOUNTDIR "/.");
|
||||
system("xenstore-write device/qpen umount");
|
||||
return 0;
|
||||
}
|
87
appvm/qubes_core
Executable file
@ -0,0 +1,87 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# chkconfig: 345 90 90
|
||||
# description: Executes Qubes core scripts at VM boot
|
||||
#
|
||||
# Source function library.
|
||||
. /etc/rc.d/init.d/functions
|
||||
|
||||
start()
|
||||
{
|
||||
echo -n $"Executing Qubes Core scripts:"
|
||||
|
||||
if ! [ -d /rw/home ] ; then
|
||||
echo
|
||||
echo "--> Virgin boot of the VM: Linking /home to /rw/home"
|
||||
mv /home /home.orig
|
||||
mkdir -p /rw/config
|
||||
mkdir -p /rw/home
|
||||
ln -s /rw/home/ /home
|
||||
# chcon --reference /home.orig /rw/home
|
||||
cp -a /home.orig/user /home
|
||||
touch /rw/config/rc.local
|
||||
rm -fr /home.orig
|
||||
touch /var/lib/qubes/first_boot_completed
|
||||
else
|
||||
mv /home /home.tmpl
|
||||
ln -s /rw/home/ /home
|
||||
fi
|
||||
|
||||
|
||||
if ! [ -x /usr/bin/xenstore-read ] ; then
|
||||
echo "ERROR: /usr/bin/xenstore-read not found!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
name=$(/usr/bin/xenstore-read name)
|
||||
hostname $name
|
||||
|
||||
vmtype=$(/usr/bin/xenstore-read qubes_vm_type)
|
||||
|
||||
if [ $vmtype == 'NetVM' ] ; then
|
||||
# Setup gateway for all the VMs this netVM is serviceing...
|
||||
brctl addbr br0
|
||||
gateway=$(/usr/bin/xenstore-read qubes_netvm_gateway)
|
||||
netmask=$(/usr/bin/xenstore-read qubes_netvm_netmask)
|
||||
network=$(/usr/bin/xenstore-read qubes_netvm_network)
|
||||
ifconfig br0 $gateway netmask $netmask up
|
||||
echo "1" > /proc/sys/net/ipv4/ip_forward
|
||||
dnsmasq
|
||||
iptables -t nat -A POSTROUTING -s $network/$netmask -j MASQUERADE
|
||||
else
|
||||
ip=$(/usr/bin/xenstore-read qubes_ip)
|
||||
netmask=$(/usr/bin/xenstore-read qubes_netmask)
|
||||
gateway=$(/usr/bin/xenstore-read qubes_gateway)
|
||||
if [ x$ip != x ]; then
|
||||
/sbin/ifconfig eth0 $ip netmask $netmask up
|
||||
/sbin/route add default gw $gateway
|
||||
echo "nameserver $gateway" > /etc/resolv.conf
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
[ -x /rw/config/rc.local ] && /rw/config/rc.local
|
||||
success
|
||||
echo ""
|
||||
return 0
|
||||
}
|
||||
|
||||
stop()
|
||||
{
|
||||
return 0
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
start
|
||||
;;
|
||||
stop)
|
||||
stop
|
||||
;;
|
||||
*)
|
||||
echo $"Usage: $0 {start|stop}"
|
||||
exit 3
|
||||
;;
|
||||
esac
|
||||
|
||||
exit $RETVAL
|
71
appvm/qubes_penctl.c
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* The Qubes OS Project, http://www.qubes-os.org
|
||||
*
|
||||
* Copyright (C) 2010 Rafal Wojtczuk <rafal@invisiblethingslab.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <xs.h>
|
||||
int check_name(unsigned char *s)
|
||||
{
|
||||
int c;
|
||||
for (; *s; s++) {
|
||||
c = *s;
|
||||
if (c >= 'a' && c <= 'z')
|
||||
continue;
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
continue;
|
||||
if (c == '_' || c == '-')
|
||||
continue;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char buf[256] = "new";
|
||||
struct xs_handle *xs;
|
||||
xs = xs_domain_open();
|
||||
setuid(getuid());
|
||||
if (!xs) {
|
||||
perror("xs_domain_open");
|
||||
exit(1);
|
||||
}
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "usage: %s new\n"
|
||||
"%s send vmname\n", argv[0], argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
if (argc > 2) {
|
||||
if (!check_name((unsigned char*)argv[2])) {
|
||||
fprintf(stderr, "invalid vmname %s\n", argv[2]);
|
||||
exit(1);
|
||||
}
|
||||
snprintf(buf, sizeof(buf), "send %s", argv[2]);
|
||||
}
|
||||
if (!xs_write(xs, 0, "device/qpen", buf, strlen(buf))) {
|
||||
perror("xs_write");
|
||||
exit(1);
|
||||
}
|
||||
xs_daemon_close(xs);
|
||||
return 0;
|
||||
}
|
40
appvm/qvm-copy-to-vm
Executable file
@ -0,0 +1,40 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# The Qubes OS Project, http://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2010 Rafal Wojtczuk <rafal@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
#
|
||||
|
||||
if [ $# -lt 2 ] ; then
|
||||
echo usage: $0 'vmname file [file]*'
|
||||
exit 1
|
||||
fi
|
||||
qubes_penctl new || exit 1
|
||||
echo -n Waiting for the Qubes virtual pendrive
|
||||
while ! [ -e /dev/xvdg ] ; do
|
||||
echo -n .
|
||||
sleep 1
|
||||
done
|
||||
echo " received"
|
||||
mount /mnt/outgoing
|
||||
VMNAME=$1
|
||||
shift
|
||||
cp -v -a $* /mnt/outgoing
|
||||
#sometimes Dolphin lags a bit
|
||||
umount /mnt/outgoing || (sleep 1; umount /mnt/outgoing) || exit 1
|
||||
qubes_penctl send $VMNAME || exit 1
|
42
appvm/qvm-copy-to-vm.kde
Executable file
@ -0,0 +1,42 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# The Qubes OS Project, http://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2010 Rafal Wojtczuk <rafal@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
#
|
||||
|
||||
FILES="$*"
|
||||
VM=$(kdialog -inputbox "Enter the VM name to send $FILE to:")
|
||||
if [ X$VM = X ] ; then exit 0 ; fi
|
||||
DEST=/mnt/outgoing
|
||||
SIZE=$(du -c $FILES | tail -1 | cut -f 1)
|
||||
REF=$(kdialog --progressbar "Copy progress")
|
||||
qdbus $REF org.freedesktop.DBus.Properties.Set "" maximum $SIZE
|
||||
FLAG=$(mktemp)
|
||||
(qvm-copy-to-vm $VM $FILES ; rm $FLAG) &
|
||||
while ! grep -q $DEST /proc/mounts && [ -f $FLAG ] ; do
|
||||
sleep 0.1
|
||||
done
|
||||
while grep -q $DEST /proc/mounts ; do
|
||||
CURRSIZE=$(du -c $DEST | tail -1 | cut -f 1)
|
||||
qdbus $REF org.freedesktop.DBus.Properties.Set "" value $CURRSIZE
|
||||
sleep 1
|
||||
done
|
||||
qdbus $REF close
|
||||
|
||||
|
10
appvm/qvm-copy.desktop
Normal file
@ -0,0 +1,10 @@
|
||||
[Desktop Entry]
|
||||
Actions=QvmCopy;
|
||||
Type=Service
|
||||
X-KDE-ServiceTypes=KonqPopupMenu/Plugin,inode/directory,all/allfiles
|
||||
|
||||
[Desktop Action QvmCopy]
|
||||
Exec=/usr/bin/qvm-copy-to-vm.kde %U
|
||||
Icon=kget
|
||||
Name=Send To VM
|
||||
|
14
dom0/aux-tools/check_and_remove_appmenu.sh
Executable file
@ -0,0 +1,14 @@
|
||||
#!/bin/sh
|
||||
if grep -q X-Qubes-VmName $1 ; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if grep -q "Categories=.*\(System\|Settings\)" $1 ; then
|
||||
#echo "Leaving file: $1"
|
||||
exit 0
|
||||
fi
|
||||
BACKUP_DIR="/var/lib/qubes/backup/removed-apps/"
|
||||
mkdir -p $BACKUP_DIR
|
||||
#echo "Moving file: $1 to $BACKUP_DIR
|
||||
mv $1 $BACKUP_DIR
|
||||
|
13
dom0/aux-tools/convert_apptemplate2vm.sh
Executable file
@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
SRC=$1
|
||||
DSTDIR=$2
|
||||
VMNAME=$3
|
||||
VMDIR=$4
|
||||
|
||||
DST=$DSTDIR/$VMNAME-$(basename $SRC)
|
||||
|
||||
sed -e "s/%VMNAME%/$VMNAME/" \
|
||||
-e "s %VMDIR% $VMDIR " \
|
||||
<$SRC >$DST
|
||||
|
||||
|
11
dom0/aux-tools/convert_dirtemplate2vm.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
SRC=$1
|
||||
DST=$2
|
||||
VMNAME=$3
|
||||
VMDIR=$4
|
||||
|
||||
sed -e "s/%VMNAME%/$VMNAME/" \
|
||||
-e "s %VMDIR% $VMDIR " \
|
||||
<$SRC >$DST
|
||||
|
||||
|
41
dom0/aux-tools/create_apps_for_appvm.sh
Executable file
@ -0,0 +1,41 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# The Qubes OS Project, http://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2010 Joanna Rutkowska <joanna@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
#
|
||||
|
||||
SRCDIR=$1
|
||||
VMNAME=$2
|
||||
VMDIR=/var/lib/qubes/appvms/$VMNAME
|
||||
APPSDIR=$VMDIR/apps
|
||||
|
||||
if [ $# != 2 ]; then
|
||||
echo "usage: $0 <apps_templates_dir> <vmname>"
|
||||
exit
|
||||
fi
|
||||
mkdir -p $APPSDIR
|
||||
|
||||
echo "--> Converting Appmenu Templates..."
|
||||
find $SRCDIR -name "*.desktop" -exec /usr/lib/qubes/convert_apptemplate2vm.sh {} $APPSDIR $VMNAME $VMDIR \;
|
||||
|
||||
/usr/lib/qubes/convert_dirtemplate2vm.sh $SRCDIR/qubes-vm.directory.template $APPSDIR/$VMNAME-vm.directory $VMNAME $VMDIR
|
||||
|
||||
echo "--> Adding Apps to the Menu..."
|
||||
xdg-desktop-menu install $APPSDIR/*.directory $APPSDIR/*.desktop
|
||||
|
82
dom0/aux-tools/patch_appvm_initramfs.sh
Executable file
@ -0,0 +1,82 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# The Qubes OS Project, http://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2010 Joanna Rutkowska <joanna@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
#
|
||||
|
||||
#
|
||||
# This script can be used to patch the initramfs of the Qubes AppVM
|
||||
# It inserts an additional script that is responsible for setting up
|
||||
# COW-based root fs and VM private fs
|
||||
#
|
||||
|
||||
INITRAMFS=$1
|
||||
INITRAMFS_QUBES=$2
|
||||
QUBES_COW_SETUP_FILE=$3
|
||||
|
||||
|
||||
TMP_DIR=`mktemp -d /tmp/qubes-initramfs-patching-XXXXXXX`
|
||||
|
||||
if [ $# != 3 ] ; then
|
||||
echo "usage: $0 <original initramfs to patch> <patched initramfs file> <qubes_cow_setup_file>"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ x$INITRAMFS = x ] ; then
|
||||
echo "INITRAMFS missing!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ x$INITRAMFS_QUBES = x ] ; then
|
||||
echo "INITRAMFS_QUBES missing!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ x$QUBES_COW_SETUP_FILE = x ] ; then
|
||||
echo "$QUBES_COW_SETUP_FILE missing!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
ID=$(id -ur)
|
||||
|
||||
if [ $ID != 0 ] ; then
|
||||
echo "This script should be run as root user. Apparently the initramfs files must have root.root owener..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir $TMP_DIR/initramfs.qubes || exit 1
|
||||
|
||||
cp $INITRAMFS $TMP_DIR/initramfs.cpio.gz
|
||||
|
||||
pushd $TMP_DIR/initramfs.qubes
|
||||
|
||||
gunzip < ../initramfs.cpio.gz | cpio -i --quiet || exit 1
|
||||
|
||||
cp $QUBES_COW_SETUP_FILE pre-trigger/90_qubes_cow_setup.sh || exit 1
|
||||
|
||||
find ./ | cpio -H newc -o --quiet > $TMP_DIR/initramfs.qubes.cpio || exit 1
|
||||
|
||||
popd
|
||||
|
||||
gzip $TMP_DIR/initramfs.qubes.cpio || exit 1
|
||||
|
||||
mv $TMP_DIR/initramfs.qubes.cpio.gz $INITRAMFS_QUBES || exit 1
|
||||
|
||||
rm -fr $TMP_DIR || exit 1
|
12
dom0/aux-tools/remove_appvm_appmenus.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
VMNAME=$1
|
||||
VMDIR=/var/lib/qubes/appvms/$VMNAME
|
||||
APPSDIR=$VMDIR/apps
|
||||
|
||||
if [ $# != 1 ]; then
|
||||
echo "usage: $0 <vmname>"
|
||||
exit
|
||||
fi
|
||||
|
||||
xdg-desktop-menu uninstall $APPSDIR/*.directory $APPSDIR/*.desktop
|
||||
|
6
dom0/aux-tools/remove_dom0_appmenus.sh
Executable file
@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
echo "--> Removing unnecessary Dom0 Appmenus..."
|
||||
find /usr/share/applications -name *.desktop -exec /usr/lib/qubes/check_and_remove_appmenu.sh {} \;
|
||||
|
||||
xdg-desktop-menu forceupdate
|
74
dom0/aux-tools/unbind_all_network_devices
Executable file
@ -0,0 +1,74 @@
|
||||
#!/usr/bin/python2.6
|
||||
#
|
||||
# The Qubes OS Project, http://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2010 Joanna Rutkowska <joanna@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
#
|
||||
|
||||
from optparse import OptionParser
|
||||
import subprocess
|
||||
import shutil
|
||||
import re
|
||||
|
||||
|
||||
def find_net_devices():
|
||||
p = subprocess.Popen (["lspci", "-mm", "-n"], stdout=subprocess.PIPE)
|
||||
result = p.communicate()
|
||||
retcode = p.returncode
|
||||
if (retcode != 0):
|
||||
print "ERROR when executing lspci!"
|
||||
raise IOError
|
||||
|
||||
net_devices = set()
|
||||
rx_netdev = re.compile (r"^([0-9][0-9]:[0-9][0-9].[0-9]) \"02")
|
||||
for dev in str(result[0]).splitlines():
|
||||
match = rx_netdev.match (dev)
|
||||
if match is not None:
|
||||
dev_bdf = match.group(1)
|
||||
assert dev_bdf is not None
|
||||
net_devices.add (dev_bdf)
|
||||
|
||||
return net_devices
|
||||
|
||||
def main():
|
||||
usage = "usage: %prog [options] <netvm-name>"
|
||||
parser = OptionParser (usage)
|
||||
parser.add_option ("-v", "--verbose", dest="verbose", action="store_true", default=False)
|
||||
(options, args) = parser.parse_args ()
|
||||
|
||||
if options.verbose:
|
||||
print "Loading Xen PCI Backend..."
|
||||
retcode = subprocess.call (["/sbin/modprobe", "xen-pciback"])
|
||||
if retcode != 0:
|
||||
print "ERROR: Cannot load xen-pciback module!"
|
||||
exit(1)
|
||||
|
||||
if options.verbose:
|
||||
print "Unbinding the following net devices:"
|
||||
|
||||
net_devices = find_net_devices()
|
||||
|
||||
for dev in net_devices:
|
||||
if options.verbose:
|
||||
print "--> {0}".format(dev)
|
||||
retcode = subprocess.call (["/usr/lib/qubes/unbind_pci_device.sh", dev])
|
||||
if (retcode != 0):
|
||||
print "WARNING: Could not unbind device {0}".format(dev)
|
||||
|
||||
|
||||
main()
|
35
dom0/aux-tools/unbind_pci_device.sh
Executable file
@ -0,0 +1,35 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# The Qubes OS Project, http://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2010 Joanna Rutkowska <joanna@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
#
|
||||
|
||||
BDF=$1
|
||||
if [ x$BDF = x ] ; then
|
||||
echo "usage: $0 <BDF>"
|
||||
exit 0
|
||||
fi
|
||||
BDF=0000:$BDF
|
||||
#echo -n "Binding device $BDF to xen-pciback..."
|
||||
if [ -e /sys/bus/pci/devices/$BDF/driver/unbind ] ; then
|
||||
echo -n $BDF > /sys/bus/pci/devices/$BDF/driver/unbind || exit 1
|
||||
fi
|
||||
echo -n $BDF > /sys/bus/pci/drivers/pciback/new_slot || exit 1
|
||||
echo -n $BDF > /sys/bus/pci/drivers/pciback/bind || exit 1
|
||||
#echo ok
|
85
dom0/clipboard_notifier/qclipd
Executable file
@ -0,0 +1,85 @@
|
||||
#!/usr/bin/python2.6
|
||||
#
|
||||
# The Qubes OS Project, http://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2010 Joanna Rutkowska <joanna@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
#
|
||||
|
||||
import os
|
||||
import daemon
|
||||
from pyinotify import WatchManager, Notifier, ThreadedNotifier, EventsCodes, ProcessEvent
|
||||
import dbus
|
||||
from qubes.qubes import QubesDaemonPidfile
|
||||
|
||||
qubes_clipboard_info_file = "/var/run/qubes/qubes_clipboard.bin.source"
|
||||
|
||||
def watch_qubes_clipboard():
|
||||
|
||||
def tray_notify(str, timeout = 3000):
|
||||
notify_object.Notify("Qubes", 0, "dialog-information", "", str, [], [], timeout, dbus_interface="org.freedesktop.Notifications")
|
||||
|
||||
notify_object = dbus.SessionBus().get_object("org.freedesktop.Notifications", "/org/freedesktop/Notifications")
|
||||
wm = WatchManager()
|
||||
mask = EventsCodes.OP_FLAGS.get('IN_CLOSE_WRITE')
|
||||
|
||||
if not os.path.exists (qubes_clipboard_info_file):
|
||||
file = open (qubes_clipboard_info_file, 'w')
|
||||
file.close()
|
||||
|
||||
|
||||
class ClipboardWatcher(ProcessEvent):
|
||||
def process_IN_CLOSE_WRITE (self, event):
|
||||
src_info_file = open (qubes_clipboard_info_file, 'r')
|
||||
src_vmname = src_info_file.readline().strip('\n')
|
||||
if src_vmname == "":
|
||||
tray_notify ("Qubes Clipboard has been copied to the VM and wiped.\n"\
|
||||
"<small>Trigger a paste operation (e.g. Ctrl-v) to insert it into an application.</small>" )
|
||||
else:
|
||||
print src_vmname
|
||||
tray_notify ("Qubes Clipboard fetched from VM: <b>'{0}'</b>\n"\
|
||||
"<small>Press Ctrl-Shift-v to copy this clipboard onto dest VM's clipboard.</small>".format(src_vmname))
|
||||
src_info_file.close()
|
||||
|
||||
|
||||
notifier = Notifier(wm, ClipboardWatcher())
|
||||
wdd = wm.add_watch(qubes_clipboard_info_file, mask)
|
||||
|
||||
while True:
|
||||
notifier.process_events()
|
||||
if notifier.check_events():
|
||||
notifier.read_events()
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
lock = QubesDaemonPidfile ("qclipd")
|
||||
if lock.pidfile_exists():
|
||||
if lock.pidfile_is_stale():
|
||||
lock.remove_pidfile()
|
||||
print "Removed stale pidfile (has the previous daemon instance crashed?)."
|
||||
else:
|
||||
exit (0)
|
||||
|
||||
context = daemon.DaemonContext(
|
||||
working_directory = "/var/run/qubes",
|
||||
pidfile = lock)
|
||||
|
||||
with context:
|
||||
watch_qubes_clipboard()
|
||||
|
||||
main()
|
BIN
dom0/icons/black.png
Normal file
After Width: | Height: | Size: 169 KiB |
BIN
dom0/icons/blue.png
Normal file
After Width: | Height: | Size: 181 KiB |
10
dom0/icons/credits-crystal-icons
Normal file
@ -0,0 +1,10 @@
|
||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
This copyright and license notice covers the images in this directory.
|
||||
************************************************************************
|
||||
|
||||
TITLE: Crystal Project Icons
|
||||
AUTHOR: Everaldo Coelho
|
||||
SITE: http://www.everaldo.com
|
||||
CONTACT: everaldo@everaldo.com
|
||||
|
||||
Copyright (c) 2006-2007 Everaldo Coelho.
|
1
dom0/icons/credits-padlock-icons
Normal file
@ -0,0 +1 @@
|
||||
Color padlock images downloaded from www.openclipart.org
|
BIN
dom0/icons/gray.png
Normal file
After Width: | Height: | Size: 192 KiB |
BIN
dom0/icons/green.png
Normal file
After Width: | Height: | Size: 187 KiB |
BIN
dom0/icons/netvm.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
dom0/icons/orange.png
Normal file
After Width: | Height: | Size: 188 KiB |
BIN
dom0/icons/purple.png
Normal file
After Width: | Height: | Size: 188 KiB |
BIN
dom0/icons/red.png
Normal file
After Width: | Height: | Size: 177 KiB |
BIN
dom0/icons/template.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
dom0/icons/yellow.png
Normal file
After Width: | Height: | Size: 185 KiB |
63
dom0/init.d/qubes_core
Executable file
@ -0,0 +1,63 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# chkconfig: 2345 99 00
|
||||
# description: Executes Qubes core scripts at Dom0 boot
|
||||
#
|
||||
### BEGIN INIT INFO
|
||||
# Provides: qubes-core
|
||||
# Required-Start: xend
|
||||
# Default-Start: 3 4 5
|
||||
# Default-Stop: 0 1 2 6
|
||||
# Default-Enabled: yes
|
||||
# Short-Description: Start/stop qubes-core services
|
||||
# Description: Starts and stops the qubes-core serives
|
||||
### END INIT INFO
|
||||
|
||||
# Source function library.
|
||||
. /etc/rc.d/init.d/functions
|
||||
|
||||
|
||||
|
||||
start()
|
||||
{
|
||||
echo -n $"Executing Qubes Core scripts:"
|
||||
chgrp qubes /etc/xen
|
||||
chmod 710 /etc/xen
|
||||
chgrp qubes /var/run/xend
|
||||
chmod 710 /var/run/xend
|
||||
chgrp qubes /var/run/xend/xen-api.sock /var/run/xend/xmlrpc.sock
|
||||
chmod 660 /var/run/xend/xen-api.sock /var/run/xend/xmlrpc.sock
|
||||
chgrp qubes /var/run/xenstored/*
|
||||
chmod 660 /var/run/xenstored/*
|
||||
xm sched-credit -d 0 -w 65535
|
||||
cp /var/lib/qubes/qubes.xml /var/lib/qubes/backup/qubes-$(date +%F-%T).xml
|
||||
touch /var/lock/subsys/qubes_core
|
||||
success
|
||||
echo
|
||||
|
||||
}
|
||||
|
||||
stop()
|
||||
{
|
||||
echo -n $"Shutting down all Qubes VMs:"
|
||||
NETVM=$(qvm-get-default-netvm)
|
||||
qvm-run -q --shutdown --all --wait --exclude $NETVM
|
||||
rm -f /var/lock/subsys/qubes_core
|
||||
success
|
||||
echo
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
start
|
||||
;;
|
||||
stop)
|
||||
stop
|
||||
;;
|
||||
*)
|
||||
echo $"Usage: $0 {start|stop}"
|
||||
exit 3
|
||||
;;
|
||||
esac
|
||||
|
||||
exit $RETVAL
|
102
dom0/init.d/qubes_netvm
Executable file
@ -0,0 +1,102 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# chkconfig: 2345 99 00
|
||||
# description: Starts/stops Qubes default netvm
|
||||
#
|
||||
### BEGIN INIT INFO
|
||||
# Provides: qubes-networking
|
||||
# Required-Start: qubes-core
|
||||
# Default-Start: 3 4 5
|
||||
# Default-Stop: 0 1 2 6
|
||||
# Default-Enabled: yes
|
||||
# Short-Description: Start/stop qubes networking
|
||||
# Description: Starts and stops the qubes networking
|
||||
### END INIT INFO
|
||||
|
||||
|
||||
#
|
||||
# Source function library.
|
||||
. /etc/rc.d/init.d/functions
|
||||
|
||||
NETVM=$(qvm-get-default-netvm)
|
||||
|
||||
start()
|
||||
{
|
||||
if [ x$NETVM = x ] ; then
|
||||
|
||||
echo WARNING: Qubes NetVM not configured!
|
||||
echo -n $"Doing nothing:"
|
||||
|
||||
elif [ $NETVM = "dom0" ] ; then
|
||||
|
||||
echo -n $"Setting up net backend in Dom0:"
|
||||
/etc/init.d/NetworkManager start
|
||||
brctl addbr br0 || exit 1
|
||||
ifconfig br0 10.0.0.1 netmask 255.255.0.0 up || exit 1
|
||||
echo "1" > /proc/sys/net/ipv4/ip_forward || exit 1
|
||||
/usr/sbin/dnsmasq --listen-address 10.0.0.1 --bind-interfaces || exit 1
|
||||
iptables -t nat -A POSTROUTING -s 10.0.0.0/16 '!' -d 10.0.0.0/16 -j MASQUERADE || exit 1
|
||||
iptables -I INPUT 1 -i br0 -s 10.0.0.0/16 -j ACCEPT || exit 1
|
||||
iptables -I FORWARD 1 -i br0 -s 10.0.0.0/16 -j ACCEPT || exit 1
|
||||
iptables -I FORWARD 1 -o br0 -d 10.0.0.0/16 -m state --state ESTABLISHED,RELATED -j ACCEPT || exit 1
|
||||
|
||||
else
|
||||
|
||||
echo -n $"Starting default NetVM:"
|
||||
/usr/lib/qubes/unbind_all_network_devices || exit 1
|
||||
qvm-start -q --no-guid $NETVM || exit 1
|
||||
|
||||
fi
|
||||
touch /var/lock/subsys/qubes_netvm
|
||||
success
|
||||
echo
|
||||
return 0
|
||||
}
|
||||
|
||||
stop()
|
||||
{
|
||||
if [ x$NETVM = x ] ; then
|
||||
|
||||
echo WARNING: Qubes NetVM not configured!
|
||||
echo -n $"Doing nothing:"
|
||||
|
||||
elif [ $NETVM = "dom0" ] ; then
|
||||
|
||||
echo -n $"Stopping Qubes networking in Dom0:"
|
||||
iptables -t nat -D POSTROUTING -s 10.0.0.0/16 '!' -d 10.0.0.0/16 -j MASQUERADE
|
||||
iptables -D INPUT -i br0 -s 10.0.0.0/16 -j ACCEPT || exit 1
|
||||
iptables -D FORWARD -i br0 -s 10.0.0.0/16 -j ACCEPT || exit 1
|
||||
iptables -D FORWARD -o br0 -d 10.0.0.0/16 -m state --state ESTABLISHED,RELATED -j ACCEPT || exit 1
|
||||
|
||||
|
||||
killall dnsmasq
|
||||
ifconfig br0 down
|
||||
brctl delbr br0
|
||||
|
||||
else
|
||||
|
||||
echo -n $"Stopping default NetVM:"
|
||||
qvm-run -q --shutdown --wait $NETVM
|
||||
|
||||
fi
|
||||
rm -f /var/lock/subsys/qubes_netvm
|
||||
success
|
||||
echo
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
start
|
||||
;;
|
||||
stop)
|
||||
stop
|
||||
;;
|
||||
*)
|
||||
echo $"Usage: $0 {start|stop}"
|
||||
exit 3
|
||||
;;
|
||||
esac
|
||||
|
||||
exit $RETVAL
|
223
dom0/pendrive_swapper/qfilexchgd
Executable file
@ -0,0 +1,223 @@
|
||||
#!/usr/bin/python2.6
|
||||
#
|
||||
# The Qubes OS Project, http://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2010 Rafal Wojtczuk <rafal@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
#
|
||||
|
||||
import xen.lowlevel.xs
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import daemon
|
||||
import time
|
||||
from qubes.qubes import QubesVmCollection
|
||||
from qubes.qubes import QubesException
|
||||
from qubes.qubes import QubesDaemonPidfile
|
||||
|
||||
filename_seq = 50
|
||||
pen_cmd = '/usr/lib/qubes/qubes_pencmd'
|
||||
|
||||
def get_next_filename_seq():
|
||||
global filename_seq
|
||||
filename_seq = filename_seq + 1
|
||||
return str(filename_seq)
|
||||
|
||||
def logproc(msg):
|
||||
f = file('/var/log/qubes/qfileexchgd', 'a')
|
||||
f.write(msg+'\n')
|
||||
f.close()
|
||||
|
||||
def get_req_node(domain_id):
|
||||
return '/local/domain/'+domain_id+'/device/qpen'
|
||||
|
||||
def get_name_node(domain_id):
|
||||
return '/local/domain/'+domain_id+'/name'
|
||||
|
||||
def only_in_first_list(l1, l2):
|
||||
ret=[]
|
||||
for i in l1:
|
||||
if not i in l2:
|
||||
ret.append(i)
|
||||
return ret
|
||||
|
||||
|
||||
class WatchType:
|
||||
def __init__(self, fn, param):
|
||||
self.fn = fn
|
||||
self.param = param
|
||||
|
||||
class DomainState:
|
||||
def __init__(self, domain, dict):
|
||||
self.rcv_state = 'idle'
|
||||
self.send_state = 'idle'
|
||||
self.domain_id = domain
|
||||
self.domdict = dict
|
||||
self.send_seq = None
|
||||
self.rcv_seq = None
|
||||
self.waiting_sender = None
|
||||
|
||||
def handle_request(self, request):
|
||||
req_ok = False
|
||||
if request is None:
|
||||
return
|
||||
tmp = request.split()
|
||||
rq = tmp[0]
|
||||
if len(tmp) > 1:
|
||||
arg = tmp[1]
|
||||
else:
|
||||
arg = None
|
||||
if rq == 'new' and self.send_state == 'idle':
|
||||
self.send_seq = get_next_filename_seq()
|
||||
retcode = subprocess.call([pen_cmd, 'new', self.domain_id, self.send_seq])
|
||||
logproc( 'Give domain ' + self.domain_id + ' a clean pendrive, retcode= ' + str(retcode))
|
||||
if retcode == 0:
|
||||
self.send_state = 'has_clean_pendrive'
|
||||
req_ok = True
|
||||
if rq == 'send' and self.send_state == 'has_clean_pendrive' and arg is not None:
|
||||
logproc( 'send from ' + self.domain_id + ' to ' + arg)
|
||||
if self.handle_transfer(arg):
|
||||
self.send_state = 'idle'
|
||||
req_ok = True;
|
||||
if rq == 'umount' and self.rcv_state == 'has_loaded_pendrive':
|
||||
retcode = subprocess.call([pen_cmd, 'umount', self.domain_id, self.rcv_seq])
|
||||
if retcode == 0:
|
||||
self.rcv_state = 'idle'
|
||||
self.rcv_seq = None
|
||||
logproc( 'set state of ' + self.domain_id + ' loaded->idle retcode=' + str(retcode))
|
||||
req_ok = True
|
||||
if rq == 'umount' and self.rcv_state == 'waits_to_umount':
|
||||
req_ok = True
|
||||
retcode = subprocess.call([pen_cmd, 'umount', self.domain_id, self.rcv_seq])
|
||||
if retcode != 0:
|
||||
return
|
||||
assert(self.waiting_sender != None)
|
||||
self.rcv_state = 'idle'
|
||||
self.rcv_seq = None
|
||||
tmp = self.waiting_sender
|
||||
self.waiting_sender = None
|
||||
if tmp.send_state == 'has_clean_pendrive':
|
||||
if tmp.handle_transfer(self.name):
|
||||
tmp.send_state = 'idle'
|
||||
|
||||
if not req_ok:
|
||||
logproc( 'request ' + request + ' not served due to nonmatching state')
|
||||
|
||||
def ask_to_umount(self, vmname):
|
||||
q = 'VM ' + vmname + ' has already an incoming pendrive, and thus '
|
||||
q+= 'cannot accept another one. If you intend to unmount its current '
|
||||
q+= 'pendrive and retry this transfer, press Yes. '
|
||||
q+= 'Otherwise press No to fail this transfer.'
|
||||
retcode = subprocess.call(['/usr/bin/kdialog', '--yesno', q, '--title', 'Some additional action required'])
|
||||
if retcode == 0:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def handle_transfer(self, vmname):
|
||||
qvm_collection = QubesVmCollection()
|
||||
qvm_collection.lock_db_for_reading()
|
||||
qvm_collection.load()
|
||||
qvm_collection.unlock_db()
|
||||
|
||||
vm = qvm_collection.get_vm_by_name(vmname)
|
||||
if vm is None:
|
||||
logproc( 'Domain ' + vmname + ' does not exist ?')
|
||||
return False
|
||||
if not vm.is_running():
|
||||
logproc( 'Domain ' + vmname + ' is not running ?')
|
||||
return False
|
||||
target=self.domdict[str(vm.get_xid())]
|
||||
if target.rcv_state != 'idle':
|
||||
if self.ask_to_umount(vmname):
|
||||
target.rcv_state='waits_to_umount'
|
||||
target.waiting_sender=self
|
||||
logproc( 'target domain ' + target.domain_id + ' is not idle, now ' + target.rcv_state)
|
||||
return False
|
||||
retcode = subprocess.call(['/usr/bin/kdialog', '--yesno', 'Do you authorize pendrive transfer from ' + self.name + ' to ' + vmname + '?' , '--title', 'Security confirmation'])
|
||||
logproc('handle_transfer: kdialog retcode=' + str(retcode))
|
||||
if retcode != 0:
|
||||
return False
|
||||
target.rcv_state='has_loaded_pendrive'
|
||||
retcode = subprocess.call([pen_cmd, 'send', self.domain_id, target.domain_id, self.send_seq])
|
||||
target.rcv_seq = self.send_seq
|
||||
self.send_seq = None
|
||||
logproc( 'set state of ' + target.domain_id + ' to has_loaded_pendrive, retcode=' + str(retcode))
|
||||
return True
|
||||
|
||||
|
||||
class XS_Watcher:
|
||||
def __init__(self):
|
||||
self.handle = xen.lowlevel.xs.xs()
|
||||
self.handle.watch('/local/domain', WatchType(XS_Watcher.dom_list_change, None))
|
||||
self.domdict = {}
|
||||
|
||||
def dom_list_change(self, param):
|
||||
curr = self.handle.ls('', '/local/domain')
|
||||
if curr == None:
|
||||
return
|
||||
for i in only_in_first_list(curr, self.domdict.keys()):
|
||||
newdom = DomainState(i, self.domdict)
|
||||
newdom.watch_token = WatchType(XS_Watcher.request, newdom)
|
||||
newdom.watch_name = WatchType(XS_Watcher.namechange, newdom)
|
||||
self.domdict[i] = newdom
|
||||
self.handle.watch(get_req_node(i), newdom.watch_token)
|
||||
self.handle.watch(get_name_node(i), newdom.watch_name)
|
||||
newdom.name = ''
|
||||
logproc( 'added domain ' + i)
|
||||
for i in only_in_first_list(self.domdict.keys(), curr):
|
||||
self.handle.unwatch(get_req_node(i), self.domdict[i].watch_token)
|
||||
self.handle.unwatch(get_name_node(i), self.domdict[i].watch_name)
|
||||
self.domdict.pop(i)
|
||||
logproc( 'removed domain ' + i)
|
||||
|
||||
def request(self, domain_param):
|
||||
ret = self.handle.read('', get_req_node(domain_param.domain_id))
|
||||
domain_param.handle_request(ret)
|
||||
|
||||
def namechange(self, domain_param):
|
||||
ret = self.handle.read('', get_name_node(domain_param.domain_id))
|
||||
if ret!= '' and ret!=None:
|
||||
domain_param.name = ret
|
||||
logproc( 'Name for domain xid ' + domain_param.domain_id + ' is ' + ret )
|
||||
|
||||
def watch_loop(self):
|
||||
sys.stderr = file('/var/log/qubes/qfileexchgd.errors', 'a')
|
||||
while True:
|
||||
result = self.handle.read_watch()
|
||||
token = result[1]
|
||||
token.fn(self, token.param)
|
||||
|
||||
def main():
|
||||
|
||||
lock = QubesDaemonPidfile ("qfileexchgd")
|
||||
if lock.pidfile_exists():
|
||||
if lock.pidfile_is_stale():
|
||||
lock.remove_pidfile()
|
||||
print "Removed stale pidfile (has the previous daemon instance crashed?)."
|
||||
else:
|
||||
exit (0)
|
||||
|
||||
|
||||
context = daemon.DaemonContext(
|
||||
working_directory = "/var/run/qubes",
|
||||
pidfile = lock)
|
||||
with context:
|
||||
XS_Watcher().watch_loop()
|
||||
|
||||
main()
|
74
dom0/pendrive_swapper/qubes_pencmd
Executable file
@ -0,0 +1,74 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# The Qubes OS Project, http://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2010 Rafal Wojtczuk <rafal@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
#
|
||||
|
||||
SHARE_DIR=/var/run/qubes
|
||||
function do_new()
|
||||
{
|
||||
FILE=$SHARE_DIR/pendrive.$2
|
||||
truncate -s 1G $FILE || exit 1
|
||||
vmname=$(xenstore-read /local/domain/$1/name)
|
||||
mkfs.vfat -n "$vmname" $FILE || exit 1
|
||||
xm block-attach $1 file:/$FILE /dev/xvdg w || exit 1
|
||||
}
|
||||
|
||||
function do_umount()
|
||||
{
|
||||
xm block-detach $1 /dev/xvdh || exit 1
|
||||
rm $SHARE_DIR/pendrive.$2
|
||||
}
|
||||
|
||||
function do_send()
|
||||
{
|
||||
FILE=$SHARE_DIR/pendrive.$3
|
||||
vmname=$(xenstore-read /local/domain/$1/name)
|
||||
xenstore-write /local/domain/$2/qubes_blocksrc $vmname
|
||||
xm block-detach $1 /dev/xvdg || exit 1
|
||||
xm block-attach $2 file:/$FILE /dev/xvdh w || exit 1
|
||||
}
|
||||
|
||||
if [ $# -lt 1 ] ; then
|
||||
echo args missing ?
|
||||
exit 1
|
||||
fi
|
||||
if [ "$1" = "new" ] ; then
|
||||
if ! [ $# = 3 ] ; then
|
||||
echo new requires 2 more args
|
||||
exit 1
|
||||
fi
|
||||
do_new "$2" "$3"
|
||||
elif [ "$1" = "umount" ] ; then
|
||||
if ! [ $# = 3 ] ; then
|
||||
echo umount requires 2 more args
|
||||
exit 1
|
||||
fi
|
||||
do_umount "$2" "$3"
|
||||
elif [ "$1" = "send" ] ; then
|
||||
if ! [ $# = 4 ] ; then
|
||||
echo send requires 3 more args
|
||||
exit 1
|
||||
fi
|
||||
do_send "$2" "$3" "$4"
|
||||
else
|
||||
echo bad cmd
|
||||
exit 1
|
||||
fi
|
||||
|
0
dom0/qvm-core/__init__.py
Normal file
1515
dom0/qvm-core/qubes.py
Executable file
82
dom0/qvm-tools/qvm-add-appvm
Executable file
@ -0,0 +1,82 @@
|
||||
#!/usr/bin/python2.6
|
||||
#
|
||||
# The Qubes OS Project, http://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2010 Joanna Rutkowska <joanna@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
#
|
||||
|
||||
from qubes.qubes import QubesVmCollection
|
||||
from qubes.qubes import QubesException
|
||||
from optparse import OptionParser;
|
||||
|
||||
def main():
|
||||
usage = "usage: %prog [options] <appvm-name> <vm-template-name>\n\n"\
|
||||
"Adds an already installed appvm to the Qubes DB\n"\
|
||||
"WARNING: Noramlly you would not need this command,\n"\
|
||||
"and you would use qvm-create instead!"
|
||||
|
||||
parser = OptionParser (usage)
|
||||
parser.add_option ("-p", "--path", dest="dir_path",
|
||||
help="Specify path to the template directory")
|
||||
parser.add_option ("-c", "--conf", dest="conf_file",
|
||||
help="Specify the Xen VM .conf file to use\
|
||||
(relative to the template dir path)")
|
||||
|
||||
(options, args) = parser.parse_args ()
|
||||
if (len (args) != 2):
|
||||
parser.error ("You must specify at least the AppVM and TemplateVM names!")
|
||||
vmname = args[0]
|
||||
templatename = args[1]
|
||||
|
||||
qvm_collection = QubesVmCollection()
|
||||
qvm_collection.lock_db_for_writing()
|
||||
qvm_collection.load()
|
||||
|
||||
if qvm_collection.get_vm_by_name(vmname) is not None:
|
||||
print "ERROR: A VM with the name '{0}' already exists in the system.".format(vmname)
|
||||
exit(1)
|
||||
|
||||
template_vm = qvm_collection.get_vm_by_name(templatename)
|
||||
if template_vm is None:
|
||||
print "ERROR: A Template VM with the name '{0}' does not exist in the system.".format(templatename)
|
||||
exit(1)
|
||||
|
||||
|
||||
vm = qvm_collection.add_new_appvm(vmname, template_vm,
|
||||
conf_file=options.conf_file,
|
||||
dir_path=options.dir_path)
|
||||
|
||||
try:
|
||||
vm.verify_files()
|
||||
except QubesException as err:
|
||||
print "ERROR: {0}".format(err)
|
||||
qvm_collection.pop(vm.qid)
|
||||
exit (1)
|
||||
|
||||
try:
|
||||
vm.add_to_xen_storage()
|
||||
|
||||
except (IOError, OSError) as err:
|
||||
print "ERROR: {0}".format(err)
|
||||
qvm_collection.pop(vm.qid)
|
||||
exit (1)
|
||||
|
||||
qvm_collection.save()
|
||||
qvm_collection.unlock_db()
|
||||
|
||||
main()
|
119
dom0/qvm-tools/qvm-add-netvm
Executable file
@ -0,0 +1,119 @@
|
||||
#!/usr/bin/python2.6
|
||||
#
|
||||
# The Qubes OS Project, http://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2010 Joanna Rutkowska <joanna@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
#
|
||||
|
||||
from optparse import OptionParser
|
||||
import subprocess
|
||||
import shutil
|
||||
import re
|
||||
|
||||
from qubes.qubes import QubesVmCollection
|
||||
from qubes.qubes import QubesException
|
||||
|
||||
def find_net_devices():
|
||||
p = subprocess.Popen (["lspci", "-mm", "-n"], stdout=subprocess.PIPE)
|
||||
result = p.communicate()
|
||||
retcode = p.returncode
|
||||
if (retcode != 0):
|
||||
print "ERROR when executing lspci!"
|
||||
raise IOError
|
||||
|
||||
net_devices = set()
|
||||
rx_netdev = re.compile (r"^([0-9][0-9]:[0-9][0-9].[0-9]) \"02")
|
||||
for dev in str(result[0]).splitlines():
|
||||
match = rx_netdev.match (dev)
|
||||
if match is not None:
|
||||
dev_bdf = match.group(1)
|
||||
assert dev_bdf is not None
|
||||
net_devices.add (dev_bdf)
|
||||
|
||||
return net_devices
|
||||
|
||||
def main():
|
||||
usage = "usage: %prog [options] <netvm-name>"
|
||||
parser = OptionParser (usage)
|
||||
parser.add_option ("-p", "--path", dest="dir_path",
|
||||
help="Specify path to the template directory")
|
||||
parser.add_option ("-c", "--conf", dest="conf_file",
|
||||
help="Specify the Xen VM .conf file to use\
|
||||
(relative to the template dir path)")
|
||||
|
||||
|
||||
(options, args) = parser.parse_args ()
|
||||
if (len (args) != 1):
|
||||
parser.error ("You must specify a NetVM name!")
|
||||
netvmname = args[0]
|
||||
|
||||
qvm_collection = QubesVmCollection()
|
||||
qvm_collection.lock_db_for_writing()
|
||||
qvm_collection.load()
|
||||
|
||||
if qvm_collection.get_vm_by_name(netvmname) is not None:
|
||||
print "ERROR: A VM with the name '{0}' already exists in the system.".format(netvmname)
|
||||
exit(1)
|
||||
|
||||
vm = qvm_collection.add_new_netvm(netvmname,
|
||||
conf_file=options.conf_file,
|
||||
dir_path=options.dir_path)
|
||||
|
||||
try:
|
||||
vm.verify_files()
|
||||
except QubesException as err:
|
||||
print "ERROR: {0}".format(err)
|
||||
qvm_collection.pop(vm.qid)
|
||||
exit (1)
|
||||
|
||||
|
||||
net_devices = find_net_devices()
|
||||
print "Found the following net devices in your system:"
|
||||
dev_str = ''
|
||||
for dev in net_devices:
|
||||
print "--> {0}".format(dev)
|
||||
dev_str += '"{0}", '.format(dev)
|
||||
|
||||
print "Assigning them to the netvm '{0}'".format(netvmname)
|
||||
rx_pcidevs = re.compile (r"%NETVMPCIDEVS%")
|
||||
conf_template = open (vm.conf_file, "r")
|
||||
conf_vm = open(vm.conf_file + ".processed", "w")
|
||||
|
||||
for line in conf_template:
|
||||
line = rx_pcidevs.sub(dev_str, line)
|
||||
conf_vm.write(line)
|
||||
|
||||
conf_template.close()
|
||||
conf_vm.close()
|
||||
|
||||
shutil.move (vm.conf_file + ".processed", vm.conf_file)
|
||||
|
||||
|
||||
try:
|
||||
pass
|
||||
vm.add_to_xen_storage()
|
||||
|
||||
except (IOError, OSError) as err:
|
||||
print "ERROR: {0}".format(err)
|
||||
qvm_collection.pop(vm.qid)
|
||||
exit (1)
|
||||
|
||||
qvm_collection.save()
|
||||
qvm_collection.unlock_db()
|
||||
|
||||
main()
|
78
dom0/qvm-tools/qvm-add-template
Executable file
@ -0,0 +1,78 @@
|
||||
#!/usr/bin/python2.6
|
||||
#
|
||||
# The Qubes OS Project, http://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2010 Joanna Rutkowska <joanna@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
#
|
||||
|
||||
from qubes.qubes import QubesVmCollection
|
||||
from qubes.qubes import QubesException
|
||||
from optparse import OptionParser;
|
||||
|
||||
def main():
|
||||
usage = "usage: %prog [options] <vm-template-name>\n"\
|
||||
"Adds an already installed template to the Qubes DB"
|
||||
|
||||
parser = OptionParser (usage)
|
||||
parser.add_option ("-p", "--path", dest="dir_path",
|
||||
help="Specify path to the template directory")
|
||||
parser.add_option ("-c", "--conf", dest="conf_file",
|
||||
help="Specify the Xen VM .conf file to use\
|
||||
(relative to the template dir path)")
|
||||
|
||||
parser.add_option ("--rpm", action="store_true", dest="installed_by_rpm",
|
||||
help="Template files have been installed by RPM", default=False)
|
||||
|
||||
|
||||
(options, args) = parser.parse_args ()
|
||||
if (len (args) != 1):
|
||||
parser.error ("You must specify at least the TemplateVM name!")
|
||||
vmname = args[0]
|
||||
|
||||
qvm_collection = QubesVmCollection()
|
||||
qvm_collection.lock_db_for_writing()
|
||||
qvm_collection.load()
|
||||
|
||||
if qvm_collection.get_vm_by_name(vmname) is not None:
|
||||
print "ERROR: A VM with the name '{0}' already exists in the system.".format(vmname)
|
||||
exit(1)
|
||||
|
||||
vm = qvm_collection.add_new_templatevm(vmname,
|
||||
conf_file=options.conf_file,
|
||||
dir_path=options.dir_path,
|
||||
installed_by_rpm=options.installed_by_rpm)
|
||||
|
||||
try:
|
||||
vm.verify_files()
|
||||
except QubesException as err:
|
||||
print "ERROR: {0}".format(err)
|
||||
qvm_collection.pop(vm.qid)
|
||||
exit (1)
|
||||
|
||||
try:
|
||||
vm.add_to_xen_storage()
|
||||
|
||||
except (IOError, OSError) as err:
|
||||
print "ERROR: {0}".format(err)
|
||||
qvm_collection.pop(vm.qid)
|
||||
exit (1)
|
||||
|
||||
qvm_collection.save()
|
||||
qvm_collection.unlock_db()
|
||||
|
||||
main()
|
75
dom0/qvm-tools/qvm-clone-template
Executable file
@ -0,0 +1,75 @@
|
||||
#!/usr/bin/python2.6
|
||||
#
|
||||
# The Qubes OS Project, http://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2010 Joanna Rutkowska <joanna@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
#
|
||||
|
||||
from qubes.qubes import QubesVmCollection
|
||||
from qubes.qubes import QubesException
|
||||
from optparse import OptionParser;
|
||||
|
||||
def main():
|
||||
usage = "usage: %prog [options] <src-template-name> <new-template-name>\n"\
|
||||
"Clones an existing template by copying all its disk files"
|
||||
|
||||
parser = OptionParser (usage)
|
||||
parser.add_option ("-q", "--quiet", action="store_false", dest="verbose", default=True)
|
||||
parser.add_option ("-p", "--path", dest="dir_path",
|
||||
help="Specify path to the template directory")
|
||||
|
||||
(options, args) = parser.parse_args ()
|
||||
if (len (args) != 2):
|
||||
parser.error ("You must specify at least the src and dst TemplateVM names!")
|
||||
srcname = args[0]
|
||||
dstname = args[1]
|
||||
|
||||
qvm_collection = QubesVmCollection()
|
||||
qvm_collection.lock_db_for_writing()
|
||||
qvm_collection.load()
|
||||
|
||||
src_tvm = qvm_collection.get_vm_by_name(srcname)
|
||||
if src_tvm is None:
|
||||
print "ERROR: A VM with the name '{0}' does not exist in the system.".format(srcname)
|
||||
exit(1)
|
||||
|
||||
if qvm_collection.get_vm_by_name(dstname) is not None:
|
||||
print "ERROR: A VM with the name '{0}' already exists in the system.".format(dstname)
|
||||
exit(1)
|
||||
|
||||
dst_tvm = qvm_collection.clone_templatevm(src_template_vm=src_tvm,
|
||||
name=dstname,
|
||||
dir_path=options.dir_path)
|
||||
|
||||
try:
|
||||
dst_tvm.clone_disk_files (src_template_vm=src_tvm, verbose=options.verbose)
|
||||
|
||||
if options.verbose:
|
||||
print "--> Adding to Xen Storage..."
|
||||
|
||||
dst_tvm.add_to_xen_storage()
|
||||
|
||||
except (IOError, OSError) as err:
|
||||
print "ERROR: {0}".format(err)
|
||||
qvm_collection.pop(dst_tvm.qid)
|
||||
exit (1)
|
||||
|
||||
qvm_collection.save()
|
||||
qvm_collection.unlock_db()
|
||||
|
||||
main()
|
101
dom0/qvm-tools/qvm-create
Executable file
@ -0,0 +1,101 @@
|
||||
#!/usr/bin/python2.6
|
||||
#
|
||||
# The Qubes OS Project, http://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2010 Joanna Rutkowska <joanna@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
#
|
||||
|
||||
from qubes.qubes import QubesVmCollection
|
||||
from qubes.qubes import QubesVmLabels
|
||||
from optparse import OptionParser;
|
||||
import subprocess
|
||||
|
||||
|
||||
def main():
|
||||
usage = "usage: %prog [options] <vm-name>"
|
||||
parser = OptionParser (usage)
|
||||
parser.add_option ("-t", "--template", dest="template",
|
||||
help="Specify the TemplateVM to use")
|
||||
parser.add_option ("-l", "--label", dest="label",
|
||||
help="Specify the label to use for the new VM (e.g. red, yellow, green, ...)")
|
||||
|
||||
parser.add_option ("-q", "--quiet", action="store_false", dest="verbose", default=True)
|
||||
(options, args) = parser.parse_args ()
|
||||
if (len (args) != 1):
|
||||
parser.error ("You must specify VM name!")
|
||||
vmname = args[0]
|
||||
|
||||
if options.label is None:
|
||||
print "You must choose a label for the new VM by passing the --label option."
|
||||
print "Possible values are:"
|
||||
for l in QubesVmLabels.values():
|
||||
print "* {0}".format(l.name)
|
||||
exit (1)
|
||||
|
||||
if options.label not in QubesVmLabels:
|
||||
print "Wrong label name, supported values are the following:"
|
||||
for l in QubesVmLabels.values():
|
||||
print "* {0}".format(l.name)
|
||||
exit (1)
|
||||
label = QubesVmLabels[options.label]
|
||||
|
||||
|
||||
qvm_collection = QubesVmCollection()
|
||||
qvm_collection.lock_db_for_writing()
|
||||
qvm_collection.load()
|
||||
|
||||
if qvm_collection.get_vm_by_name(vmname) is not None:
|
||||
print "A VM with the name '{0}' already exists in the system.".format(vmname)
|
||||
exit(1)
|
||||
|
||||
if options.template is not None:
|
||||
template_vm = qvm_collection.get_vm_by_name(options.template)
|
||||
if template_vm is None:
|
||||
print "There is no (Templete)VM with the name '{0}'".format(options.template)
|
||||
exit (1)
|
||||
if not template_vm.is_templete():
|
||||
print "VM '{0}' is not a TemplateVM".format(options.template)
|
||||
exit (1)
|
||||
if (options.verbose):
|
||||
print "--> Using TemplateVM: {0}".format(template_vm.name)
|
||||
|
||||
else:
|
||||
if qvm_collection.get_default_template_vm() is None:
|
||||
print "No default TempleteVM defined!"
|
||||
exit (1)
|
||||
else:
|
||||
template_vm = qvm_collection.get_default_template_vm()
|
||||
if (options.verbose):
|
||||
print "--> Using default TemplateVM: {0}".format(template_vm.name)
|
||||
|
||||
vm = qvm_collection.add_new_appvm(vmname, template_vm, label = label)
|
||||
try:
|
||||
vm.create_on_disk(verbose=options.verbose)
|
||||
vm.add_to_xen_storage()
|
||||
|
||||
except (IOError, OSError) as err:
|
||||
print "ERROR: {0}".format(err)
|
||||
vm.remove_from_disk()
|
||||
exit (1)
|
||||
|
||||
|
||||
qvm_collection.save()
|
||||
qvm_collection.unlock_db()
|
||||
|
||||
|
||||
main()
|
39
dom0/qvm-tools/qvm-get-default-netvm
Executable file
@ -0,0 +1,39 @@
|
||||
#!/usr/bin/python2.6
|
||||
#
|
||||
# The Qubes OS Project, http://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2010 Joanna Rutkowska <joanna@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
#
|
||||
|
||||
from qubes.qubes import QubesVmCollection
|
||||
from optparse import OptionParser;
|
||||
|
||||
def main():
|
||||
qvm_collection = QubesVmCollection()
|
||||
qvm_collection.lock_db_for_reading()
|
||||
qvm_collection.load()
|
||||
qvm_collection.unlock_db()
|
||||
netvm = qvm_collection.get_default_netvm_vm()
|
||||
if netvm is None:
|
||||
print ""
|
||||
else:
|
||||
print netvm.name
|
||||
|
||||
|
||||
|
||||
main()
|
32
dom0/qvm-tools/qvm-init-storage
Executable file
@ -0,0 +1,32 @@
|
||||
#!/usr/bin/python2.6
|
||||
#
|
||||
# The Qubes OS Project, http://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2010 Joanna Rutkowska <joanna@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
#
|
||||
|
||||
from qubes.qubes import QubesVmCollection
|
||||
|
||||
def main():
|
||||
qvm_collection = QubesVmCollection()
|
||||
if qvm_collection.check_if_storage_exists():
|
||||
print "Storage exists, not overwriting."
|
||||
exit(1)
|
||||
qvm_collection.create_empty_storage()
|
||||
|
||||
main()
|
54
dom0/qvm-tools/qvm-kill
Executable file
@ -0,0 +1,54 @@
|
||||
#!/usr/bin/python2.6
|
||||
#
|
||||
# The Qubes OS Project, http://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2010 Joanna Rutkowska <joanna@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
#
|
||||
|
||||
from qubes.qubes import QubesVmCollection
|
||||
from optparse import OptionParser;
|
||||
import subprocess
|
||||
|
||||
qubes_guid_path = "/usr/bin/qubes_guid"
|
||||
|
||||
def main():
|
||||
usage = "usage: %prog [options] <vm-name>"
|
||||
parser = OptionParser (usage)
|
||||
(options, args) = parser.parse_args ()
|
||||
if (len (args) != 1):
|
||||
parser.error ("You must specify VM name!")
|
||||
vmname = args[0]
|
||||
|
||||
qvm_collection = QubesVmCollection()
|
||||
qvm_collection.lock_db_for_reading()
|
||||
qvm_collection.load()
|
||||
qvm_collection.unlock_db()
|
||||
|
||||
vm = qvm_collection.get_vm_by_name(vmname)
|
||||
if vm is None:
|
||||
print "A VM with the name '{0}' does not exist in the system.".format(vmname)
|
||||
exit(1)
|
||||
|
||||
try:
|
||||
vm.force_shutdown()
|
||||
except (IOError, OSError) as err:
|
||||
print "ERROR: {0}".format(err)
|
||||
exit (1)
|
||||
|
||||
|
||||
main()
|
191
dom0/qvm-tools/qvm-ls
Executable file
@ -0,0 +1,191 @@
|
||||
#!/usr/bin/python2.6
|
||||
#
|
||||
# The Qubes OS Project, http://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2010 Joanna Rutkowska <joanna@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
#
|
||||
|
||||
from qubes.qubes import QubesVmCollection
|
||||
from qubes.qubes import QubesException
|
||||
from optparse import OptionParser
|
||||
|
||||
|
||||
fields = {
|
||||
"qid": {"func": "vm.qid"},
|
||||
|
||||
"name": {"func": "('=>' if qvm_collection.get_default_template_vm() is not None\
|
||||
and vm.qid == qvm_collection.get_default_template_vm().qid else '')\
|
||||
+ ('[' if vm.is_templete() else '')\
|
||||
+ ('{' if vm.is_netvm() else '')\
|
||||
+ vm.name \
|
||||
+ (']' if vm.is_templete() else '')\
|
||||
+ ('}' if vm.is_netvm() else '')"},
|
||||
|
||||
"type": {"func": "'Tpl' if vm.is_templete() else \
|
||||
(' Net' if vm.is_netvm() else '')"},
|
||||
|
||||
"updbl" : {"func": "'Yes' if vm.is_updateable() else ''"},
|
||||
|
||||
"template": {"func": "'n/a' if vm.is_templete() or vm.is_netvm() else\
|
||||
qvm_collection[vm.template_vm.qid].name"},
|
||||
|
||||
"netvm": {"func": "'n/a' if vm.is_netvm() else\
|
||||
('*' if vm.uses_default_netvm else '') +\
|
||||
qvm_collection[vm.netvm_vm.qid].name\
|
||||
if vm.netvm_vm is not None else '-'"},
|
||||
|
||||
"ip" : {"func": "vm.ip"},
|
||||
"netmask" : {"func": "vm.netmask"},
|
||||
"gateway" : {"func": "vm.gateway"},
|
||||
|
||||
"xid" : {"func" : "vm.get_xid() if vm.is_running() else '-'"},
|
||||
|
||||
"mem" : {"func" : "(str(vm.get_mem()/1024/1024) + ' MB') if vm.is_running() else '-'"},
|
||||
"cpu" : {"func" : "round (vm.get_cpu_total_load(), 1) if vm.is_running() else '-'"},
|
||||
"disk": {"func" : "str(vm.get_disk_utilization()/(1024*1024)) + ' MB'"},
|
||||
"state": {"func" : "vm.get_power_state()"},
|
||||
|
||||
"priv-curr": {"func" : "str(vm.get_disk_utilization_private_img()/(1024*1024)) + ' MB'"},
|
||||
"priv-max": {"func" : "str(vm.get_private_img_sz()/(1024*1024)) + ' MB'"},
|
||||
"priv-util": {"func" : "str(vm.get_disk_utilization_private_img()*100/vm.get_private_img_sz()) + '%' if vm.get_private_img_sz() != 0 else '-'"},
|
||||
|
||||
"root-curr": {"func" : "str(vm.get_disk_utilization_root_img()/(1024*1024)) + ' MB'"},
|
||||
"root-max": {"func" : "str(vm.get_root_img_sz()/(1024*1024)) + ' MB'"},
|
||||
"root-util": {"func" : "str(vm.get_disk_utilization_root_img()*100/vm.get_root_img_sz()) + '%' if vm.get_root_img_sz() != 0 else '-'"},
|
||||
|
||||
"label" : {"func" : "vm.label.name"},
|
||||
|
||||
"on" : {"func" : "'*' if vm.is_running() else ''"}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
usage = "usage: %prog [options] <vm-name>"
|
||||
parser = OptionParser (usage)
|
||||
|
||||
parser.add_option ("-n", "--network", dest="network",
|
||||
action="store_true", default=False,
|
||||
help="Show network addresses assigned to VMs")
|
||||
|
||||
parser.add_option ("-c", "--cpu", dest="cpu",
|
||||
action="store_true", default=False,
|
||||
help="Show CPU load")
|
||||
|
||||
parser.add_option ("-m", "--mem", dest="mem",
|
||||
action="store_true", default=False,
|
||||
help="Show memory usage")
|
||||
|
||||
parser.add_option ("-d", "--disk", dest="disk",
|
||||
action="store_true", default=False,
|
||||
help="Show VM disk utilization statistics")
|
||||
|
||||
parser.add_option ("-i", "--ids", dest="ids",
|
||||
action="store_true", default=False,
|
||||
help="Show Qubes and Xen id#s")
|
||||
|
||||
|
||||
(options, args) = parser.parse_args ()
|
||||
|
||||
qvm_collection = QubesVmCollection()
|
||||
qvm_collection.lock_db_for_reading()
|
||||
qvm_collection.load()
|
||||
qvm_collection.unlock_db()
|
||||
|
||||
fields_to_display = ["name", "on", "state", "updbl", "type", "template", "netvm", "label" ]
|
||||
|
||||
if (options.ids):
|
||||
fields_to_display += ["qid", "xid"]
|
||||
|
||||
if (options.cpu):
|
||||
fields_to_display += ["cpu"]
|
||||
|
||||
if (options.mem):
|
||||
fields_to_display += ["mem"]
|
||||
|
||||
if (options.network):
|
||||
fields_to_display.remove ("template")
|
||||
fields_to_display += ["ip", "netmask", "gateway"]
|
||||
|
||||
if (options.disk):
|
||||
fields_to_display.remove ("template")
|
||||
fields_to_display.remove ("netvm")
|
||||
fields_to_display += ["priv-curr", "priv-max", "root-curr", "root-max", "disk" ]
|
||||
|
||||
|
||||
vms_list = [vm for vm in qvm_collection.values()]
|
||||
no_vms = len (vms_list)
|
||||
vms_to_display = []
|
||||
# Frist, the NetVMs...
|
||||
for netvm in vms_list:
|
||||
if netvm.is_netvm():
|
||||
vms_to_display.append (netvm)
|
||||
|
||||
# Now, the template, and all its AppVMs...
|
||||
for tvm in vms_list:
|
||||
if tvm.is_templete():
|
||||
vms_to_display.append (tvm)
|
||||
for appvm in vms_list:
|
||||
if appvm.is_appvm() and appvm.template_vm.qid == tvm.qid:
|
||||
vms_to_display.append(appvm)
|
||||
|
||||
assert len(vms_to_display) == no_vms
|
||||
|
||||
# First calculate the maximum width of each field we want to display
|
||||
total_width = 0;
|
||||
for f in fields_to_display:
|
||||
fields[f]["max_width"] = len(f)
|
||||
for vm in vms_to_display:
|
||||
l = len(str(eval(fields[f]["func"])))
|
||||
if l > fields[f]["max_width"]:
|
||||
fields[f]["max_width"] = l
|
||||
total_width += fields[f]["max_width"]
|
||||
|
||||
|
||||
# Display the header
|
||||
s = ""
|
||||
for f in fields_to_display:
|
||||
fmt="{{0:-^{0}}}-+".format(fields[f]["max_width"] + 1)
|
||||
s += fmt.format('-')
|
||||
print s
|
||||
s = ""
|
||||
for f in fields_to_display:
|
||||
fmt="{{0:>{0}}} |".format(fields[f]["max_width"] + 1)
|
||||
s += fmt.format(f)
|
||||
print s
|
||||
s = ""
|
||||
for f in fields_to_display:
|
||||
fmt="{{0:-^{0}}}-+".format(fields[f]["max_width"] + 1)
|
||||
s += fmt.format('-')
|
||||
print s
|
||||
|
||||
# ... and the actual data
|
||||
for vm in vms_to_display:
|
||||
s = ""
|
||||
for f in fields_to_display:
|
||||
fmt="{{0:>{0}}} |".format(fields[f]["max_width"] + 1)
|
||||
s += fmt.format(eval(fields[f]["func"]))
|
||||
print s
|
||||
|
||||
try:
|
||||
vm.verify_files()
|
||||
except QubesException as err:
|
||||
print "WARNING: VM '{0}' has corrupted files!".format(vm.name)
|
||||
|
||||
main()
|
219
dom0/qvm-tools/qvm-prefs
Executable file
@ -0,0 +1,219 @@
|
||||
#!/usr/bin/python2.6
|
||||
#
|
||||
# The Qubes OS Project, http://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2010 Joanna Rutkowska <joanna@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
#
|
||||
|
||||
from qubes.qubes import QubesVmCollection
|
||||
from qubes.qubes import QubesVmLabels
|
||||
from optparse import OptionParser
|
||||
import subprocess
|
||||
|
||||
def do_list(vm):
|
||||
label_width = 18
|
||||
fmt="{{0:<{0}}}: {{1}}".format(label_width)
|
||||
|
||||
print fmt.format ("name", vm.name)
|
||||
print fmt.format ("label", vm.label.name)
|
||||
print fmt.format ("type", vm.type)
|
||||
if vm.is_appvm():
|
||||
print fmt.format ("template", vm.template_vm.name)
|
||||
if vm.netvm_vm is not None:
|
||||
print fmt.format ("netvm", vm.netvm_vm.name)
|
||||
print fmt.format ("updateable?", vm.is_updateable())
|
||||
print fmt.format ("installed by RPM?", vm.installed_by_rpm)
|
||||
print fmt.format ("dir", vm.dir_path)
|
||||
print fmt.format ("config", vm.conf_file)
|
||||
if not vm.is_appvm():
|
||||
print fmt.format ("root img", vm.root_img)
|
||||
if vm.is_appvm():
|
||||
print fmt.format ("root img", vm.template_vm.root_img)
|
||||
print fmt.format ("root COW img", vm.rootcow_img)
|
||||
|
||||
print fmt.format ("private img", vm.private_img)
|
||||
|
||||
|
||||
def set_label(vms, vm, args):
|
||||
if len (args) != 1:
|
||||
print "Missing label name argument!"
|
||||
|
||||
label = args[0]
|
||||
if label not in QubesVmLabels:
|
||||
print "Wrong label name, supported values are the following:"
|
||||
for l in QubesVmLabels.values():
|
||||
print "* {0}".format(l.name)
|
||||
exit (1)
|
||||
|
||||
vm.label = QubesVmLabels[label]
|
||||
subprocess.check_call (["ln", "-sf", vm.label.icon_path, vm.icon_path])
|
||||
|
||||
|
||||
def set_netvm(vms, vm, args):
|
||||
if len (args) != 1:
|
||||
print "Missing netvm name argument!"
|
||||
print "Possible values:"
|
||||
print "1) default"
|
||||
print "2) none"
|
||||
print "3) <vmaname>"
|
||||
return
|
||||
|
||||
netvm = args[0]
|
||||
if netvm == "none":
|
||||
netvm_vm = None
|
||||
vm.uses_default_netvm = False
|
||||
elif netvm == "default":
|
||||
netvm_vm = vms.get_default_netvm_vm()
|
||||
vm.uses_default_netvm = True
|
||||
else:
|
||||
netvm_vm = vms.get_vm_by_name (netvm)
|
||||
if netvm_vm is None:
|
||||
print "A VM with the name '{0}' does not exist in the system.".format(netvm)
|
||||
exit(1)
|
||||
if not netvm_vm.is_netvm():
|
||||
print "VM '{0}' is not a NetVM".format(netvm)
|
||||
exit (1)
|
||||
vm.uses_default_netvm = False
|
||||
|
||||
vm.netvm_vm = netvm_vm
|
||||
|
||||
|
||||
def set_updateable(vms, vm, args):
|
||||
if vm.is_updateable():
|
||||
print "VM '{0}' is already set 'updateable', no action required.".format(vm.name)
|
||||
return True
|
||||
|
||||
if vm.is_running():
|
||||
print "Cannot change 'updateable' attribute of a running VM. Shut it down first."
|
||||
return False
|
||||
|
||||
if vm.is_appvm():
|
||||
# Check if the Template is *non* updateable...
|
||||
if not vm.template_vm.is_updateable():
|
||||
print "VM '{0}': Setting 'updateable' attribute to True.".format(vm.name)
|
||||
vm.set_updateable()
|
||||
else:
|
||||
print "The Template VM ('{0}') is marked as 'updateable' itself!".format(vm.template_vm.name)
|
||||
print "Cannot make the AppVM updateable too, as this might cause COW-backed storage incoherency."
|
||||
print "If you want to make this AppVM updateable, you must first make the Template VM nonupdateable."
|
||||
return False
|
||||
|
||||
if vm.is_templete():
|
||||
# Make sure that all the AppVMs are non-updateable...
|
||||
for appvm in vm.appvms.values():
|
||||
if appvm.is_updateable():
|
||||
print "At least one of the AppVMs ('{0}') of this Template VM is also marked 'updateable'.".format(appvm.name)
|
||||
print "Cannot make the Template VM updateable too, as this might cause COW-backed storage incoherency."
|
||||
print "If you want to make this Template VM updateable, you must first make all its decedent AppVMs nonupdateable."
|
||||
return False
|
||||
|
||||
|
||||
print "VM '{0}': Setting 'updateable' attribute to True.".format(vm.name)
|
||||
vm.set_updateable()
|
||||
|
||||
return True
|
||||
|
||||
def set_nonupdateable(vms, vm, args):
|
||||
if not vm.is_updateable():
|
||||
print "VM '{0}' is already set 'nonupdateable', no action required.".format(vm.name)
|
||||
return True
|
||||
|
||||
if vm.is_running():
|
||||
print "Cannot change 'updateable' attribute of a running VM. Shut it down first."
|
||||
return False
|
||||
|
||||
if vm.is_netvm():
|
||||
print "Why, on earth, would you want to make a NetVM 'nonupdateable'?"
|
||||
return False
|
||||
|
||||
|
||||
print "VM '{0}': Setting 'updateable' attribute to False.".format(vm.name)
|
||||
vm.set_nonupdateable()
|
||||
return True
|
||||
|
||||
properties = {
|
||||
"updateable": set_updateable,
|
||||
"nonupdateable": set_nonupdateable,
|
||||
"label" : set_label,
|
||||
"netvm" : set_netvm,
|
||||
}
|
||||
|
||||
|
||||
def do_set(vms, vm, property, args):
|
||||
if property not in properties.keys():
|
||||
print "ERROR: Wrong property name: '{0}'".format(property)
|
||||
return False
|
||||
|
||||
return properties[property](vms, vm, args)
|
||||
|
||||
|
||||
def main():
|
||||
usage = "usage: %prog -l [options] <vm-name>\n"\
|
||||
"usage: %prog -s [options] <vm-name> <property> [...]\n"\
|
||||
"List/set various per-VM properties."
|
||||
|
||||
parser = OptionParser (usage)
|
||||
parser.add_option ("-l", "--list", action="store_true", dest="do_list", default=False)
|
||||
parser.add_option ("-s", "--set", action="store_true", dest="do_set", default=False)
|
||||
|
||||
(options, args) = parser.parse_args ()
|
||||
if (len (args) < 1):
|
||||
parser.error ("You must provide at least the vmname!")
|
||||
|
||||
vmname = args[0]
|
||||
|
||||
if options.do_list and options.do_set:
|
||||
print "You cannot provide -l and -s at the same time!"
|
||||
exit (1)
|
||||
|
||||
|
||||
|
||||
if options.do_set:
|
||||
qvm_collection = QubesVmCollection()
|
||||
qvm_collection.lock_db_for_writing()
|
||||
qvm_collection.load()
|
||||
else:
|
||||
qvm_collection = QubesVmCollection()
|
||||
qvm_collection.lock_db_for_reading()
|
||||
qvm_collection.load()
|
||||
qvm_collection.unlock_db()
|
||||
|
||||
vm = qvm_collection.get_vm_by_name(vmname)
|
||||
if vm is None or vm.qid not in qvm_collection:
|
||||
print "A VM with the name '{0}' does not exist in the system.".format(vmname)
|
||||
exit(1)
|
||||
|
||||
if options.do_set:
|
||||
if len (args) < 2:
|
||||
print "You must specify the property you wish to set..."
|
||||
print "Available properties:"
|
||||
for p in properties.keys():
|
||||
print "--> '{0}'".format(p)
|
||||
exit (1)
|
||||
|
||||
property = args[1]
|
||||
do_set(qvm_collection, vm, property, args[2:])
|
||||
qvm_collection.save()
|
||||
qvm_collection.unlock_db()
|
||||
|
||||
|
||||
else:
|
||||
# do_list
|
||||
do_list(vm)
|
||||
|
||||
main()
|
101
dom0/qvm-tools/qvm-remove
Executable file
@ -0,0 +1,101 @@
|
||||
#!/usr/bin/python2.6
|
||||
#
|
||||
# The Qubes OS Project, http://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2010 Joanna Rutkowska <joanna@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
#
|
||||
|
||||
from qubes.qubes import QubesVmCollection
|
||||
from optparse import OptionParser;
|
||||
|
||||
def main():
|
||||
usage = "usage: %prog [options] <vm-name>"
|
||||
parser = OptionParser (usage)
|
||||
parser.add_option ("-q", "--quiet", action="store_false", dest="verbose", default=True)
|
||||
parser.add_option ("--just-db", action="store_true", dest="remove_from_db_only", default=False,
|
||||
help="Remove only from the Qubes Xen DB, do not remove any files")
|
||||
(options, args) = parser.parse_args ()
|
||||
if (len (args) != 1):
|
||||
parser.error ("You must specify VM name!")
|
||||
vmname = args[0]
|
||||
|
||||
qvm_collection = QubesVmCollection()
|
||||
qvm_collection.lock_db_for_writing()
|
||||
qvm_collection.load()
|
||||
vm = qvm_collection.get_vm_by_name(vmname)
|
||||
if vm is None or vm.qid not in qvm_collection:
|
||||
print "A VM with the name '{0}' does not exist in the system.".format(vmname)
|
||||
exit(1)
|
||||
|
||||
if vm.is_templete():
|
||||
dependent_vms = qvm_collection.get_vms_based_on(vm.qid)
|
||||
if len(dependent_vms) > 0:
|
||||
print "The following AppVMs use '{0}' as a template:".format(vmname)
|
||||
for vm in dependent_vms:
|
||||
print "{name:<12} (qid={qid})".format(qid=vm.qid, name=vm.name)
|
||||
print "Please remove those VMs first, or use the --force option."
|
||||
exit (1)
|
||||
if qvm_collection.default_template_qid == vm.qid:
|
||||
qvm_collection.default_template_qid = None
|
||||
|
||||
if vm.is_netvm():
|
||||
if qvm_collection.default_netvm_qid == vm.qid:
|
||||
qvm_collection.default_netvm_qid = None
|
||||
|
||||
|
||||
if vm.is_running():
|
||||
print "Cannot remove a running VM, stop it first"
|
||||
exit (1)
|
||||
|
||||
if vm.installed_by_rpm and not options.remove_from_db_only:
|
||||
if options.verbose:
|
||||
print "This VM has been installed by RPM, use rpm -e <pkg name> to remove it!"
|
||||
exit (1)
|
||||
|
||||
try:
|
||||
if options.verbose:
|
||||
print "--> Removing from Xen Storage..."
|
||||
vm.remove_from_xen_storage()
|
||||
except (IOError, OSError) as err:
|
||||
print "Warning: {0}".format(err)
|
||||
# Do not exit, perhaps the VM was not in the Xen store
|
||||
# so just remove it from Qubes DB
|
||||
|
||||
try:
|
||||
if vm.installed_by_rpm:
|
||||
if options.verbose:
|
||||
print "--> VM installed by RPM, leaving all the files on disk"
|
||||
else:
|
||||
if options.verbose:
|
||||
print "--> Removing all the files on disk..."
|
||||
#TODO: ask for confirmation, perhaps?
|
||||
vm.remove_from_disk()
|
||||
|
||||
|
||||
|
||||
except (IOError, OSError) as err:
|
||||
print "Warning: {0}".format(err)
|
||||
# Do not exit, perhaps the VM files were somehow removed
|
||||
# so just remove it from Qubes DB
|
||||
|
||||
|
||||
qvm_collection.pop(vm.qid)
|
||||
qvm_collection.save()
|
||||
qvm_collection.unlock_db()
|
||||
|
||||
main()
|
227
dom0/qvm-tools/qvm-run
Executable file
@ -0,0 +1,227 @@
|
||||
#!/usr/bin/python2.6
|
||||
#
|
||||
# The Qubes OS Project, http://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2010 Joanna Rutkowska <joanna@invisiblethingslab.com>
|
||||
# Copyright (C) 2010 Rafal Wojtczuk <rafal@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
#
|
||||
|
||||
from qubes.qubes import QubesVmCollection
|
||||
from qubes.qubes import QubesException
|
||||
from optparse import OptionParser
|
||||
import subprocess
|
||||
import socket
|
||||
import errno
|
||||
import dbus
|
||||
import time
|
||||
|
||||
qubes_guid_path = "/usr/bin/qubes_guid"
|
||||
qubes_clipd_path = "/usr/bin/qclipd"
|
||||
qubes_qfilexchgd_path= "/usr/bin/qfilexchgd"
|
||||
notify_object = None
|
||||
|
||||
# how long (in sec) to wait for VMs to shutdown
|
||||
# before killing them (when used with --wait option)
|
||||
shutdown_counter_max = 30
|
||||
|
||||
def tray_notify(str, label, timeout = 3000):
|
||||
notify_object.Notify("Qubes", 0, label.icon, "Qubes", str, [], [], timeout, dbus_interface="org.freedesktop.Notifications")
|
||||
|
||||
def tray_notify_error(str, timeout = 3000):
|
||||
notify_object.Notify("Qubes", 0, "dialog-error", "Qubes", str, [], [], timeout, dbus_interface="org.freedesktop.Notifications")
|
||||
|
||||
|
||||
def vm_run_cmd(vm, cmd, options):
|
||||
if options.shutdown:
|
||||
if options.verbose:
|
||||
print "Shutting down VM: '{0}'...".format(vm.name)
|
||||
subprocess.call (["/usr/sbin/xm", "shutdown", vm.name])
|
||||
return
|
||||
|
||||
if options.verbose:
|
||||
print "Running command on VM: '{0}'...".format(vm.name)
|
||||
|
||||
if not vm.is_running():
|
||||
if not options.auto:
|
||||
print "VM '{0}' is not running, please start it first, or use the '--auto' switch"
|
||||
exit (1)
|
||||
try:
|
||||
if options.verbose:
|
||||
print "Starting the VM '{0}'...".format(vm.name)
|
||||
if options.tray:
|
||||
tray_notify ("Starting the '{0}' VM...".format(vm.name), label=vm.label)
|
||||
xid = vm.start(verbose=options.verbose)
|
||||
except (IOError, OSError, QubesException) as err:
|
||||
print "ERROR: {0}".format(err)
|
||||
if options.tray:
|
||||
tray_notify_error ("Error while starting the '{0}' VM: {1}".format(vm.name, err))
|
||||
exit (1)
|
||||
except (MemoryError) as err:
|
||||
print "ERROR: {0}".format(err)
|
||||
print "Close one or more running VMs and try again."
|
||||
if options.tray:
|
||||
subprocess.call(["kdialog", "--error", "Not enough memory to start '{0}' VM! Close one or more running VMs and try again.".format(vm.name)])
|
||||
exit (1)
|
||||
|
||||
if options.verbose:
|
||||
print "--> Starting Qubes GUId..."
|
||||
|
||||
retcode = subprocess.call ([qubes_guid_path, "-d", str(xid), "-c", vm.label.color, "-e", cmd, "-i", vm.label.icon])
|
||||
if (retcode != 0) :
|
||||
print "ERROR: Cannot start qubes_guid!"
|
||||
if options.tray:
|
||||
tray_notify_error ("ERROR: Cannot start qubes_guid!")
|
||||
exit (1)
|
||||
else: # VM already running...
|
||||
guid_is_running = True
|
||||
xid = vm.get_xid()
|
||||
s = socket.socket (socket.AF_UNIX)
|
||||
try:
|
||||
s.connect ("/var/run/qubes/cmd_socket.{0}".format(xid))
|
||||
except (IOError, OSError) as e:
|
||||
if e.errno in [errno.ENOENT,errno.ECONNREFUSED]:
|
||||
guid_is_running = False
|
||||
else:
|
||||
print "ERROR: unix-connect: {0}".format(e)
|
||||
if options.tray:
|
||||
tray_notify_error ("ERROR: Cannot connect to GUI daemon for this VM!")
|
||||
exit(1)
|
||||
if guid_is_running:
|
||||
s.send (cmd)
|
||||
s.close()
|
||||
else:
|
||||
retcode = subprocess.call ([qubes_guid_path, "-d", str(xid), "-c", vm.label.color, "-e", cmd, "-i", vm.label.icon])
|
||||
if (retcode != 0) :
|
||||
print "ERROR: Cannot start qubes_guid!"
|
||||
if options.tray:
|
||||
tray_notify_error ("ERROR: Cannot start the GUI daemon for this VM!")
|
||||
exit (1)
|
||||
|
||||
def main():
|
||||
usage = "usage: %prog [options] [<vm-name>] [<cmd>]"
|
||||
parser = OptionParser (usage)
|
||||
parser.add_option ("-q", "--quiet", action="store_false", dest="verbose", default=True)
|
||||
parser.add_option ("-a", "--auto", action="store_true", dest="auto", default=False,
|
||||
help="Auto start the VM if not running")
|
||||
parser.add_option ("-u", "--user", action="store", dest="user", default="user",
|
||||
help="Run command in a VM as a specified user")
|
||||
parser.add_option ("--tray", action="store_true", dest="tray", default=False,
|
||||
help="Use tray notifications instead of stdout" )
|
||||
|
||||
parser.add_option ("--all", action="store_true", dest="run_on_all_running", default=False,
|
||||
help="Run command on all currently running VMs")
|
||||
|
||||
parser.add_option ("--exclude", action="append", dest="exclude_list",
|
||||
help="When --all is used: exclude this VM name (might be repeated)")
|
||||
|
||||
parser.add_option ("--wait", action="store_true", dest="wait_for_shutdown", default=False,
|
||||
help="Wait for the VM(s) to shutdown")
|
||||
|
||||
parser.add_option ("--shutdown", action="store_true", dest="shutdown", default=False,
|
||||
help="Do 'xm shutdown' for the VM(s) (can be combined this with --all and --wait)")
|
||||
|
||||
(options, args) = parser.parse_args ()
|
||||
|
||||
|
||||
if options.run_on_all_running:
|
||||
if len(args) < 1 and not options.shutdown:
|
||||
parser.error ("You must provide a command to execute on all the VMs.")
|
||||
if len(args) > 1 or (options.shutdown and len(args) > 0):
|
||||
parser.error ("To many arguments...")
|
||||
cmdstr = args[0] if not options.shutdown else None
|
||||
else:
|
||||
if len (args) < 1 and options.shutdown:
|
||||
parser.error ("You must specify the VM name to shutdown.")
|
||||
if len (args) < 2 and not options.shutdown:
|
||||
parser.error ("You must specify the VM name and the command to execute in the VM.")
|
||||
if len (args) > 2 or (options.shutdown and len(args) > 1):
|
||||
parser.error ("To many arguments...")
|
||||
vmname = args[0]
|
||||
cmdstr = args[1] if not options.shutdown else None
|
||||
|
||||
if options.tray:
|
||||
global notify_object
|
||||
notify_object = dbus.SessionBus().get_object("org.freedesktop.Notifications", "/org/freedesktop/Notifications")
|
||||
|
||||
qvm_collection = QubesVmCollection()
|
||||
qvm_collection.lock_db_for_reading()
|
||||
qvm_collection.load()
|
||||
qvm_collection.unlock_db()
|
||||
|
||||
vms_list = []
|
||||
if options.run_on_all_running:
|
||||
all_vms = [vm for vm in qvm_collection.values()]
|
||||
for vm in all_vms:
|
||||
if options.exclude_list is not None and vm.name in options.exclude_list:
|
||||
continue
|
||||
if vm.qid == 0:
|
||||
continue
|
||||
if vm.is_running():
|
||||
vms_list.append (vm)
|
||||
else:
|
||||
vm = qvm_collection.get_vm_by_name(vmname)
|
||||
if vm is None:
|
||||
print "A VM with the name '{0}' does not exist in the system!".format(vmname)
|
||||
exit(1)
|
||||
vms_list.append(vm)
|
||||
|
||||
if options.shutdown:
|
||||
cmd = None
|
||||
else:
|
||||
cmd = "{user}:{cmd}".format(user=options.user, cmd=cmdstr)
|
||||
|
||||
for vm in vms_list:
|
||||
vm_run_cmd(vm, cmd, options)
|
||||
|
||||
|
||||
if options.wait_for_shutdown:
|
||||
if options.verbose:
|
||||
print "Waiting for the VM(s) to shutdown..."
|
||||
shutdown_counter = 0
|
||||
|
||||
while len (vms_list):
|
||||
if options.verbose:
|
||||
print "Waiting for VMs: ", [vm.name for vm in vms_list]
|
||||
for vm in vms_list:
|
||||
if not vm.is_running():
|
||||
vms_list.remove (vm)
|
||||
if shutdown_counter > shutdown_counter_max:
|
||||
# kill the VM
|
||||
if options.verbose:
|
||||
print "Killing the (apparently hanging) VM '{0}'...".format(vm.name)
|
||||
vm.force_shutdown()
|
||||
#vms_list.remove(vm)
|
||||
|
||||
shutdown_counter += 1
|
||||
time.sleep (1)
|
||||
exit (0) # there is no point in executing the other daemons in the case of --wait
|
||||
|
||||
retcode = subprocess.call([qubes_clipd_path])
|
||||
if retcode != 0:
|
||||
print "ERROR: Cannot start qclipd!"
|
||||
if options.tray:
|
||||
tray_notify ("ERROR: Cannot start the Qubes Clipboard Notifier!")
|
||||
|
||||
retcode = subprocess.call([qubes_qfilexchgd_path])
|
||||
if retcode != 0:
|
||||
print "ERROR: Cannot start qfilexchgd!"
|
||||
if options.tray:
|
||||
tray_notify ("ERROR: Cannot start the Qubes Inter-VM File Exchange Daemon!")
|
||||
|
||||
|
||||
main()
|
50
dom0/qvm-tools/qvm-set-default-netvm
Executable file
@ -0,0 +1,50 @@
|
||||
#!/usr/bin/python2.6
|
||||
#
|
||||
# The Qubes OS Project, http://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2010 Joanna Rutkowska <joanna@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
#
|
||||
|
||||
from qubes.qubes import QubesVmCollection
|
||||
from optparse import OptionParser;
|
||||
|
||||
def main():
|
||||
usage = "usage: %prog <netvm-name>"
|
||||
parser = OptionParser (usage)
|
||||
(options, args) = parser.parse_args ()
|
||||
if (len (args) != 1):
|
||||
parser.error ("Missing argument!")
|
||||
vmname = args[0]
|
||||
|
||||
qvm_collection = QubesVmCollection()
|
||||
qvm_collection.lock_db_for_writing()
|
||||
qvm_collection.load()
|
||||
vm = qvm_collection.get_vm_by_name(vmname)
|
||||
if vm is None or vm.qid not in qvm_collection:
|
||||
print "A VM with the name '{0}' does not exist in the system.".format(vmname)
|
||||
exit(1)
|
||||
|
||||
if not vm.is_netvm():
|
||||
print "VM '{0}' is not a NetVM".format(vmname)
|
||||
exit (1)
|
||||
|
||||
qvm_collection.set_default_netvm_vm(vm)
|
||||
qvm_collection.save()
|
||||
qvm_collection.unlock_db()
|
||||
|
||||
main()
|
50
dom0/qvm-tools/qvm-set-default-template
Executable file
@ -0,0 +1,50 @@
|
||||
#!/usr/bin/python2.6
|
||||
#
|
||||
# The Qubes OS Project, http://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2010 Joanna Rutkowska <joanna@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
#
|
||||
|
||||
from qubes.qubes import QubesVmCollection
|
||||
from optparse import OptionParser;
|
||||
|
||||
def main():
|
||||
usage = "usage: %prog <template-vm-name>"
|
||||
parser = OptionParser (usage)
|
||||
(options, args) = parser.parse_args ()
|
||||
if (len (args) != 1):
|
||||
parser.error ("Missing argument!")
|
||||
vmname = args[0]
|
||||
|
||||
qvm_collection = QubesVmCollection()
|
||||
qvm_collection.lock_db_for_writing()
|
||||
qvm_collection.load()
|
||||
vm = qvm_collection.get_vm_by_name(vmname)
|
||||
if vm is None or vm.qid not in qvm_collection:
|
||||
print "A VM with the name '{0}' does not exist in the system.".format(vmname)
|
||||
exit(1)
|
||||
|
||||
if not vm.is_templete():
|
||||
print "VM '{0}' is not a TemplateVM".format(vmname)
|
||||
exit (1)
|
||||
|
||||
qvm_collection.set_default_template_vm(vm)
|
||||
qvm_collection.save()
|
||||
qvm_collection.unlock_db()
|
||||
|
||||
main()
|
72
dom0/qvm-tools/qvm-start
Executable file
@ -0,0 +1,72 @@
|
||||
#!/usr/bin/python2.6
|
||||
#
|
||||
# The Qubes OS Project, http://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2010 Joanna Rutkowska <joanna@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
#
|
||||
|
||||
from qubes.qubes import QubesVmCollection
|
||||
from qubes.qubes import QubesException
|
||||
from optparse import OptionParser
|
||||
import subprocess
|
||||
|
||||
qubes_guid_path = "/usr/bin/qubes_guid"
|
||||
|
||||
def main():
|
||||
usage = "usage: %prog [options] <vm-name>"
|
||||
parser = OptionParser (usage)
|
||||
parser.add_option ("-q", "--quiet", action="store_false", dest="verbose", default=True)
|
||||
parser.add_option ("--no-guid", action="store_true", dest="noguid", default=False,
|
||||
help="Do not start the GUId")
|
||||
parser.add_option ("--console", action="store_true", dest="debug_console", default=False,
|
||||
help="Attach debugging console to the newly started VM")
|
||||
|
||||
(options, args) = parser.parse_args ()
|
||||
if (len (args) != 1):
|
||||
parser.error ("You must specify VM name!")
|
||||
vmname = args[0]
|
||||
|
||||
qvm_collection = QubesVmCollection()
|
||||
qvm_collection.lock_db_for_reading()
|
||||
qvm_collection.load()
|
||||
qvm_collection.unlock_db()
|
||||
|
||||
vm = qvm_collection.get_vm_by_name(vmname)
|
||||
if vm is None:
|
||||
print "A VM with the name '{0}' does not exist in the system.".format(vmname)
|
||||
exit(1)
|
||||
|
||||
try:
|
||||
vm.verify_files()
|
||||
xid = vm.start(debug_console=options.debug_console, verbose=options.verbose)
|
||||
except (IOError, OSError, QubesException) as err:
|
||||
print "ERROR: {0}".format(err)
|
||||
exit (1)
|
||||
|
||||
if options.noguid:
|
||||
exit (0)
|
||||
if options.verbose:
|
||||
print "--> Starting Qubes GUId..."
|
||||
|
||||
retcode = subprocess.call ([qubes_guid_path, "-d", str(xid), "-c", vm.label.color, "-i", vm.label.icon])
|
||||
if (retcode != 0) :
|
||||
print "ERROR: Cannot start qubes_guid!"
|
||||
exit (1)
|
||||
|
||||
|
||||
main()
|
14
netvm/fstab
Normal file
@ -0,0 +1,14 @@
|
||||
|
||||
#
|
||||
# /etc/fstab
|
||||
# Created by anaconda on Thu Dec 3 11:26:49 2009
|
||||
#
|
||||
# Accessible filesystems, by reference, are maintained under '/dev/disk'
|
||||
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
|
||||
#
|
||||
/dev/mapper/dmroot / ext4 defaults,noatime 1 1
|
||||
/dev/mapper/dmswap swap swap defaults 0 0
|
||||
tmpfs /dev/shm tmpfs defaults 0 0
|
||||
devpts /dev/pts devpts gid=5,mode=620 0 0
|
||||
sysfs /sys sysfs defaults 0 0
|
||||
proc /proc proc defaults 0 0
|
17
netvm/iptables
Normal file
@ -0,0 +1,17 @@
|
||||
# Generated by iptables-save v1.4.5 on Thu Apr 1 10:55:18 2010
|
||||
*nat
|
||||
:PREROUTING ACCEPT [3:696]
|
||||
:POSTROUTING ACCEPT [1:67]
|
||||
:OUTPUT ACCEPT [1:67]
|
||||
-A POSTROUTING -s 10.1.0.0/16 -j MASQUERADE
|
||||
COMMIT
|
||||
# Completed on Thu Apr 1 10:55:18 2010
|
||||
# Generated by iptables-save v1.4.5 on Thu Apr 1 10:55:18 2010
|
||||
*filter
|
||||
:INPUT ACCEPT [0:0]
|
||||
:FORWARD ACCEPT [0:0]
|
||||
:OUTPUT ACCEPT [0:0]
|
||||
-A INPUT -i br0 -p udp -m udp --dport 68 -j DROP
|
||||
-A INPUT -i vif+ -p udp -m udp --dport 68 -j DROP
|
||||
COMMIT
|
||||
# Completed on Thu Apr 1 10:55:18 2010
|
55
netvm/qubes_core
Executable file
@ -0,0 +1,55 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# chkconfig: 345 90 90
|
||||
# description: Executes Qubes core scripts at VM boot
|
||||
#
|
||||
# Source function library.
|
||||
. /etc/rc.d/init.d/functions
|
||||
|
||||
start()
|
||||
{
|
||||
echo -n $"Executing Qubes Core scripts NetVM:"
|
||||
|
||||
if ! [ -x /usr/bin/xenstore-read ] ; then
|
||||
echo "ERROR: /usr/bin/xenstore-read not found!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
name=$(/usr/bin/xenstore-read name)
|
||||
hostname $name
|
||||
|
||||
# Setup gateway for all the VMs this netVM is serviceing...
|
||||
brctl addbr br0
|
||||
gateway=$(/usr/bin/xenstore-read qubes_netvm_gateway)
|
||||
netmask=$(/usr/bin/xenstore-read qubes_netvm_netmask)
|
||||
network=$(/usr/bin/xenstore-read qubes_netvm_network)
|
||||
ifconfig br0 $gateway netmask $netmask up
|
||||
echo "1" > /proc/sys/net/ipv4/ip_forward
|
||||
dnsmasq --listen-address $gateway --bind-interfaces
|
||||
#now done by iptables rc script
|
||||
# iptables -t nat -A POSTROUTING -s $network/$netmask -j MASQUERADE
|
||||
|
||||
success
|
||||
echo ""
|
||||
return 0
|
||||
}
|
||||
|
||||
stop()
|
||||
{
|
||||
return 0
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
start
|
||||
;;
|
||||
stop)
|
||||
stop
|
||||
;;
|
||||
*)
|
||||
echo $"Usage: $0 {start|stop}"
|
||||
exit 3
|
||||
;;
|
||||
esac
|
||||
|
||||
exit $RETVAL
|
162
rpm_spec/core-appvm.spec
Normal file
@ -0,0 +1,162 @@
|
||||
#
|
||||
# The Qubes OS Project, http://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2010 Joanna Rutkowska <joanna@invisiblethingslab.com>
|
||||
# Copyright (C) 2010 Rafal Wojtczuk <rafal@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
#
|
||||
|
||||
%{!?version: %define version %(cat version_vm)}
|
||||
|
||||
Name: qubes-core-appvm
|
||||
Version: %{version}
|
||||
Release: 1
|
||||
Summary: The Qubes core files for AppVM
|
||||
|
||||
Group: Qubes
|
||||
Vendor: Invisible Things Lab
|
||||
License: GPL
|
||||
URL: http://www.qubes-os.org
|
||||
Requires: /usr/bin/xenstore-read
|
||||
Provides: qubes-core-vm
|
||||
|
||||
%define _builddir %(pwd)/appvm
|
||||
|
||||
%define kde_service_dir /usr/share/kde4/services/ServiceMenus
|
||||
|
||||
%description
|
||||
The Qubes core files for installation inside a Qubes AppVM.
|
||||
|
||||
%pre
|
||||
|
||||
mkdir -p $RPM_BUILD_ROOT/var/lib/qubes
|
||||
[ -e $RPM_BUILD_ROOT/etc/fstab ] && mv $RPM_BUILD_ROOT/etc/fstab $RPM_BUILD_ROOT/var/lib/qubes/fstab.orig
|
||||
|
||||
%build
|
||||
make clean all
|
||||
|
||||
%install
|
||||
|
||||
mkdir -p $RPM_BUILD_ROOT/etc
|
||||
cp fstab $RPM_BUILD_ROOT/etc/fstab
|
||||
mkdir -p $RPM_BUILD_ROOT/etc/init.d
|
||||
cp qubes_core $RPM_BUILD_ROOT/etc/init.d/
|
||||
mkdir -p $RPM_BUILD_ROOT/var/lib/qubes
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/bin
|
||||
cp qubes_add_pendrive_script qubes_penctl qvm-copy-to-vm qvm-copy-to-vm.kde $RPM_BUILD_ROOT/usr/bin
|
||||
mkdir -p $RPM_BUILD_ROOT/%{kde_service_dir}
|
||||
cp qvm-copy.desktop $RPM_BUILD_ROOT/%{kde_service_dir}
|
||||
mkdir -p $RPM_BUILD_ROOT/etc/udev/rules.d
|
||||
cp qubes.rules $RPM_BUILD_ROOT/etc/udev/rules.d
|
||||
mkdir -p $RPM_BUILD_ROOT/etc/sysconfig
|
||||
cp iptables $RPM_BUILD_ROOT/etc/sysconfig/
|
||||
mkdir -p $RPM_BUILD_ROOT/mnt/incoming
|
||||
mkdir -p $RPM_BUILD_ROOT/mnt/outgoing
|
||||
|
||||
%post
|
||||
|
||||
if [ "$1" != 1 ] ; then
|
||||
# do this whole %post thing only when updating for the first time...
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "--> Disabling SELinux..."
|
||||
sed -e s/^SELINUX=.*$/SELINUX=disabled/ </etc/selinux/config >/etc/selinux/config.processed
|
||||
mv /etc/selinux/config.processed /etc/selinux/config
|
||||
setenforce 0
|
||||
|
||||
echo "--> Turning off unnecessary services..."
|
||||
# FIXME: perhaps there is more elegant way to do this?
|
||||
for f in /etc/init.d/*
|
||||
do
|
||||
srv=`basename $f`
|
||||
[ $srv = 'functions' ] && continue
|
||||
[ $srv = 'killall' ] && continue
|
||||
[ $srv = 'halt' ] && continue
|
||||
chkconfig $srv off
|
||||
done
|
||||
|
||||
echo "--> Enabling essential services..."
|
||||
chkconfig rsyslog on
|
||||
chkconfig haldaemon on
|
||||
chkconfig messagebus on
|
||||
chkconfig cups on
|
||||
chkconfig iptables on
|
||||
chkconfig --add qubes_core || echo "WARNING: Cannot add service qubes_core!"
|
||||
chkconfig qubes_core on || echo "WARNING: Cannot enable service qubes_core!"
|
||||
|
||||
|
||||
sed -i s/^id:.:initdefault:/id:3:initdefault:/ /etc/inittab
|
||||
|
||||
# Remove most of the udev scripts to speed up the VM boot time
|
||||
# Just leave the xen* scripts, that are needed if this VM was
|
||||
# ever used as a net backend (e.g. as a VPN domain in the future)
|
||||
echo "--> Removing unnecessary udev scripts..."
|
||||
mkdir -p /var/lib/qubes/removed-udev-scripts
|
||||
for f in /etc/udev/rules.d/*
|
||||
do
|
||||
if [ $(basename $f) == "xen-backend.rules" ] ; then
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ $(basename $f) == "xend.rules" ] ; then
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ $(basename $f) == "qubes.rules" ] ; then
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ $(basename $f) == "90-hal.rules" ] ; then
|
||||
continue
|
||||
fi
|
||||
|
||||
|
||||
mv $f /var/lib/qubes/removed-udev-scripts/
|
||||
done
|
||||
|
||||
mkdir -p /rw
|
||||
#rm -f /etc/mtab
|
||||
echo "--> Removing HWADDR setting from /etc/sysconfig/network-scripts/ifcfg-eth0"
|
||||
mv /etc/sysconfig/network-scripts/ifcfg-eth0 /etc/sysconfig/network-scripts/ifcfg-eth0.orig
|
||||
grep -v HWADDR /etc/sysconfig/network-scripts/ifcfg-eth0.orig > /etc/sysconfig/network-scripts/ifcfg-eth0
|
||||
|
||||
%preun
|
||||
if [ "$1" = 0 ] ; then
|
||||
# no more packages left
|
||||
chkconfig qubes_core off
|
||||
mv /var/lib/qubes/fstab.orig /etc/fstab
|
||||
mv /var/lib/qubes/removed-udev-scripts/* /etc/udev/rules.d/
|
||||
fi
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%files
|
||||
%defattr(-,root,root,-)
|
||||
/etc/fstab
|
||||
/etc/init.d/qubes_core
|
||||
/usr/bin/qvm-copy-to-vm
|
||||
/usr/bin/qvm-copy-to-vm.kde
|
||||
%{kde_service_dir}/qvm-copy.desktop
|
||||
%attr(4755,root,root) /usr/bin/qubes_penctl
|
||||
/usr/bin/qubes_add_pendrive_script
|
||||
/etc/udev/rules.d/qubes.rules
|
||||
/etc/sysconfig/iptables
|
||||
%dir /var/lib/qubes
|
||||
%dir /mnt/incoming
|
||||
%dir /mnt/outgoing
|
156
rpm_spec/core-dom0.spec
Normal file
@ -0,0 +1,156 @@
|
||||
#
|
||||
# This is the SPEC file for creating binary RPMs for the Dom0.
|
||||
#
|
||||
#
|
||||
# The Qubes OS Project, http://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2010 Joanna Rutkowska <joanna@invisiblethingslab.com>
|
||||
# Copyright (C) 2010 Rafal Wojtczuk <rafal@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
#
|
||||
|
||||
%{!?python_sitearch: %define python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)")}
|
||||
|
||||
%{!?version: %define version %(cat version_dom0)}
|
||||
|
||||
Name: qubes-core-dom0
|
||||
Version: %{version}
|
||||
Release: 1
|
||||
Summary: The Qubes core files (Dom0-side)
|
||||
|
||||
Group: Qubes
|
||||
Vendor: Invisible Things Lab
|
||||
License: GPL
|
||||
URL: http://www.qubes-os.org
|
||||
Requires: python, xen-runtime, pciutils, python-inotify, python-daemon, kernel-qubes-dom0
|
||||
|
||||
%define _builddir %(pwd)/dom0
|
||||
|
||||
%description
|
||||
The Qubes core files for installation on Dom0.
|
||||
|
||||
%install
|
||||
|
||||
mkdir -p $RPM_BUILD_ROOT/etc/init.d
|
||||
cp init.d/qubes_core $RPM_BUILD_ROOT/etc/init.d/
|
||||
cp init.d/qubes_netvm $RPM_BUILD_ROOT/etc/init.d/
|
||||
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/bin/
|
||||
cp qvm-tools/qvm-* $RPM_BUILD_ROOT/usr/bin
|
||||
cp clipboard_notifier/qclipd $RPM_BUILD_ROOT/usr/bin
|
||||
cp pendrive_swapper/qfilexchgd $RPM_BUILD_ROOT/usr/bin
|
||||
|
||||
mkdir -p $RPM_BUILD_ROOT%{python_sitearch}/qubes
|
||||
cp qvm-core/qubes.py $RPM_BUILD_ROOT%{python_sitearch}/qubes
|
||||
cp qvm-core/__init__.py $RPM_BUILD_ROOT%{python_sitearch}/qubes
|
||||
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/lib/qubes
|
||||
cp aux-tools/patch_appvm_initramfs.sh $RPM_BUILD_ROOT/usr/lib/qubes
|
||||
cp aux-tools/unbind_pci_device.sh $RPM_BUILD_ROOT/usr/lib/qubes
|
||||
cp aux-tools/unbind_all_network_devices $RPM_BUILD_ROOT/usr/lib/qubes
|
||||
cp aux-tools/convert_apptemplate2vm.sh $RPM_BUILD_ROOT/usr/lib/qubes
|
||||
cp aux-tools/convert_dirtemplate2vm.sh $RPM_BUILD_ROOT/usr/lib/qubes
|
||||
cp aux-tools/create_apps_for_appvm.sh $RPM_BUILD_ROOT/usr/lib/qubes
|
||||
cp aux-tools/remove_appvm_appmenus.sh $RPM_BUILD_ROOT/usr/lib/qubes
|
||||
cp pendrive_swapper/qubes_pencmd $RPM_BUILD_ROOT/usr/lib/qubes
|
||||
|
||||
mkdir -p $RPM_BUILD_ROOT/var/lib/qubes
|
||||
mkdir -p $RPM_BUILD_ROOT/var/lib/qubes/vm-templates
|
||||
mkdir -p $RPM_BUILD_ROOT/var/lib/qubes/appvms
|
||||
|
||||
mkdir -p $RPM_BUILD_ROOT/var/lib/qubes/backup
|
||||
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/share/qubes/icons
|
||||
cp icons/*.png $RPM_BUILD_ROOT/usr/share/qubes/icons
|
||||
|
||||
|
||||
%post
|
||||
if [ "$1" != 1 ] ; then
|
||||
# do this whole %post thing only when updating for the first time...
|
||||
exit 0
|
||||
fi
|
||||
|
||||
#echo "Enabling essential services..."
|
||||
chkconfig haldaemon on
|
||||
chkconfig messagebus on
|
||||
chkconfig xenstored on
|
||||
chkconfig xend on
|
||||
chkconfig xenconsoled on
|
||||
|
||||
chkconfig --add qubes_core || echo "WARNING: Cannot add service qubes_core!"
|
||||
chkconfig --add qubes_netvm || echo "WARNING: Cannot add service qubes_netvm!"
|
||||
|
||||
chkconfig qubes_core on || echo "WARNING: Cannot enable service qubes_core!"
|
||||
chkconfig qubes_netvm on || echo "WARNING: Cannot enable service qubes_netvm!"
|
||||
|
||||
if ! [ -e /var/lib/qubes/qubes.xml ]; then
|
||||
# echo "Initializing Qubes DB..."
|
||||
umask 007; sg qubes -c qvm-init-storage
|
||||
fi
|
||||
for i in /usr/share/qubes/icons/*.png ; do
|
||||
xdg-icon-resource install --novendor --size 48 $i
|
||||
done
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%pre
|
||||
if ! grep -q ^qubes: /etc/group ; then
|
||||
groupadd qubes
|
||||
fi
|
||||
|
||||
%preun
|
||||
if [ "$1" = 0 ] ; then
|
||||
for i in /usr/share/qubes/icons/*.png ; do
|
||||
xdg-icon-resource uninstall --novendor --size 48 $i
|
||||
done
|
||||
fi
|
||||
|
||||
%postun
|
||||
if [ "$1" = 0 ] ; then
|
||||
# no more packages left
|
||||
chgrp root /etc/xen
|
||||
chmod 700 /etc/xen
|
||||
groupdel qubes
|
||||
fi
|
||||
|
||||
%files
|
||||
%defattr(-,root,root,-)
|
||||
/etc/init.d/qubes_core
|
||||
/etc/init.d/qubes_netvm
|
||||
/usr/bin/qvm-*
|
||||
/usr/bin/qclipd
|
||||
/usr/bin/qfilexchgd
|
||||
%{python_sitearch}/qubes/qubes.py
|
||||
%{python_sitearch}/qubes/qubes.pyc
|
||||
%{python_sitearch}/qubes/qubes.pyo
|
||||
%{python_sitearch}/qubes/__init__.py
|
||||
%{python_sitearch}/qubes/__init__.pyc
|
||||
%{python_sitearch}/qubes/__init__.pyo
|
||||
/usr/lib/qubes/patch_appvm_initramfs.sh
|
||||
/usr/lib/qubes/unbind_pci_device.sh
|
||||
/usr/lib/qubes/unbind_all_network_devices
|
||||
/usr/lib/qubes/convert_apptemplate2vm.sh
|
||||
/usr/lib/qubes/convert_dirtemplate2vm.sh
|
||||
/usr/lib/qubes/create_apps_for_appvm.sh
|
||||
/usr/lib/qubes/remove_appvm_appmenus.sh
|
||||
/usr/lib/qubes/qubes_pencmd
|
||||
%attr(770,root,qubes) %dir /var/lib/qubes
|
||||
%attr(770,root,qubes) %dir /var/lib/qubes/vm-templates
|
||||
%attr(770,root,qubes) %dir /var/lib/qubes/appvms
|
||||
%attr(770,root,qubes) %dir /var/lib/qubes/backup
|
||||
%dir /usr/share/qubes/icons/*.png
|
142
rpm_spec/core-netvm.spec
Normal file
@ -0,0 +1,142 @@
|
||||
#
|
||||
# The Qubes OS Project, http://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2010 Joanna Rutkowska <joanna@invisiblethingslab.com>
|
||||
# Copyright (C) 2010 Rafal Wojtczuk <rafal@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
#
|
||||
|
||||
%{!?version: %define version %(cat version_vm)}
|
||||
|
||||
Name: qubes-core-netvm
|
||||
Version: %{version}
|
||||
Release: 1
|
||||
Summary: The Qubes core files for NetVM
|
||||
|
||||
Group: Qubes
|
||||
Vendor: Invisible Things Lab
|
||||
License: GPL
|
||||
URL: http://www.qubes-os.org
|
||||
Requires: /usr/bin/xenstore-read
|
||||
Provides: qubes-core-vm
|
||||
|
||||
%define _builddir %(pwd)/netvm
|
||||
|
||||
%description
|
||||
The Qubes core files for installation inside a Qubes NetVM.
|
||||
|
||||
%pre
|
||||
|
||||
mkdir -p $RPM_BUILD_ROOT/var/lib/qubes
|
||||
[ -e $RPM_BUILD_ROOT/etc/fstab ] && mv $RPM_BUILD_ROOT/etc/fstab $RPM_BUILD_ROOT/var/lib/qubes/fstab.orig
|
||||
|
||||
%build
|
||||
|
||||
%install
|
||||
|
||||
mkdir -p $RPM_BUILD_ROOT/etc/sysconfig
|
||||
cp iptables $RPM_BUILD_ROOT/etc/sysconfig
|
||||
mkdir -p $RPM_BUILD_ROOT/etc
|
||||
cp fstab $RPM_BUILD_ROOT/etc/fstab
|
||||
mkdir -p $RPM_BUILD_ROOT/etc/init.d
|
||||
cp qubes_core $RPM_BUILD_ROOT/etc/init.d/
|
||||
mkdir -p $RPM_BUILD_ROOT/var/lib/qubes
|
||||
|
||||
%post
|
||||
|
||||
if [ "$1" != 1 ] ; then
|
||||
# do this whole %post thing only when updating for the first time...
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "--> Disabling SELinux..."
|
||||
sed -e s/^SELINUX=.*$/SELINUX=disabled/ </etc/selinux/config >/etc/selinux/config.processed
|
||||
mv /etc/selinux/config.processed /etc/selinux/config
|
||||
setenforce 0
|
||||
|
||||
echo "--> Turning off unnecessary services..."
|
||||
# FIXME: perhaps there is more elegant way to do this?
|
||||
for f in /etc/init.d/*
|
||||
do
|
||||
srv=`basename $f`
|
||||
[ $srv = 'functions' ] && continue
|
||||
[ $srv = 'killall' ] && continue
|
||||
[ $srv = 'halt' ] && continue
|
||||
chkconfig $srv off
|
||||
done
|
||||
|
||||
echo "--> Enabling essential services..."
|
||||
chkconfig iptables on
|
||||
chkconfig rsyslog on
|
||||
chkconfig haldaemon on
|
||||
chkconfig messagebus on
|
||||
chkconfig NetworkManager on
|
||||
chkconfig --add qubes_core || echo "WARNING: Cannot add service qubes_core!"
|
||||
chkconfig qubes_core on || echo "WARNING: Cannot enable service qubes_core!"
|
||||
|
||||
|
||||
sed -i s/^id:.:initdefault:/id:3:initdefault:/ /etc/inittab
|
||||
|
||||
# Remove most of the udev scripts to speed up the VM boot time
|
||||
# Just leave the xen* scripts, that are needed if this VM was
|
||||
# ever used as a net backend (e.g. as a VPN domain in the future)
|
||||
echo "--> Removing unnecessary udev scripts..."
|
||||
mkdir -p /var/lib/qubes/removed-udev-scripts
|
||||
for f in /etc/udev/rules.d/*
|
||||
do
|
||||
if [ $(basename $f) == "xen-backend.rules" ] ; then
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ $(basename $f) == "xend.rules" ] ; then
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ $(basename $f) == "qubes.rules" ] ; then
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ $(basename $f) == "90-hal.rules" ] ; then
|
||||
continue
|
||||
fi
|
||||
|
||||
|
||||
mv $f /var/lib/qubes/removed-udev-scripts/
|
||||
done
|
||||
|
||||
#rm -f /etc/mtab
|
||||
#echo "--> Removing HWADDR setting from /etc/sysconfig/network-scripts/ifcfg-eth0"
|
||||
#mv /etc/sysconfig/network-scripts/ifcfg-eth0 /etc/sysconfig/network-scripts/ifcfg-eth0.orig
|
||||
#grep -v HWADDR /etc/sysconfig/network-scripts/ifcfg-eth0.orig > /etc/sysconfig/network-scripts/ifcfg-eth0
|
||||
|
||||
%preun
|
||||
if [ "$1" = 0 ] ; then
|
||||
# no more packages left
|
||||
chkconfig qubes_core off
|
||||
mv /var/lib/qubes/fstab.orig /etc/fstab
|
||||
mv /var/lib/qubes/removed-udev-scripts/* /etc/udev/rules.d/
|
||||
fi
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%files
|
||||
%defattr(-,root,root,-)
|
||||
/etc/fstab
|
||||
/etc/sysconfig/iptables
|
||||
/etc/init.d/qubes_core
|
||||
%dir /var/lib/qubes
|
78
rpm_spec/dom0-cleanup.spec
Normal file
@ -0,0 +1,78 @@
|
||||
#
|
||||
# The Qubes OS Project, http://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2010 Joanna Rutkowska <joanna@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
#
|
||||
|
||||
Name: qubes-dom0-cleanup
|
||||
Version: 0.2.2
|
||||
Release: 1
|
||||
Summary: Additional tools that cleans up some unnecessary stuff in Qubes's Dom0
|
||||
|
||||
Group: Qubes
|
||||
Vendor: Invisible Things Lab
|
||||
License: GPL
|
||||
URL: http://www.qubes-os.org
|
||||
Requires: qubes-core-dom0
|
||||
|
||||
%define _builddir %(pwd)/dom0
|
||||
|
||||
%description
|
||||
Additional tools that cleans up some unnecessary stuff in Qubes's Dom0
|
||||
|
||||
%install
|
||||
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/lib/qubes
|
||||
cp aux-tools/check_and_remove_appmenu.sh $RPM_BUILD_ROOT/usr/lib/qubes
|
||||
cp aux-tools/remove_dom0_appmenus.sh $RPM_BUILD_ROOT/usr/lib/qubes
|
||||
|
||||
%post
|
||||
echo "--> Turning off unnecessary services..."
|
||||
# FIXME: perhaps there is more elegant way to do this?
|
||||
for f in /etc/init.d/*
|
||||
do
|
||||
srv=`basename $f`
|
||||
[ $srv = 'functions' ] && continue
|
||||
[ $srv = 'killall' ] && continue
|
||||
[ $srv = 'halt' ] && continue
|
||||
chkconfig $srv off
|
||||
done
|
||||
|
||||
#echo "--> Enabling essential services..."
|
||||
chkconfig abrtd on
|
||||
chkconfig haldaemon on
|
||||
chkconfig messagebus on
|
||||
chkconfig xenstored on
|
||||
chkconfig xend on
|
||||
chkconfig xenconsoled on
|
||||
chkconfig qubes_core on || echo "WARNING: Cannot enable service qubes_core!"
|
||||
chkconfig qubes_netvm on || echo "WARNING: Cannot enable service qubes_core!"
|
||||
|
||||
/usr/lib/qubes/remove_dom0_appmenus.sh
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%postun
|
||||
|
||||
mv /var/lib/qubes/backup/removed-apps/* /usr/share/applications
|
||||
xdg-desktop-menu forceupdate
|
||||
|
||||
%files
|
||||
/usr/lib/qubes/check_and_remove_appmenu.sh
|
||||
/usr/lib/qubes/remove_dom0_appmenus.sh
|
1
version_dom0
Normal file
@ -0,0 +1 @@
|
||||
1.0.0
|
1
version_vm
Normal file
@ -0,0 +1 @@
|
||||
1.0.0
|