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
|