commit ad522026d3bca0acb779acaefd31aa80a5e5fd16 Author: Marek Marczykowski Date: Sat Mar 16 18:23:22 2013 +0100 Initial commit: appmenus handling code, icons diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8cbc7ae --- /dev/null +++ b/Makefile @@ -0,0 +1,40 @@ +RPMS_DIR=rpm/ + +VERSION := $(shell cat version) +VERSION_VAIO_FIXES := $(shell cat version_vaio_fixes) + +DIST_DOM0 ?= fc18 + +help: + @echo "make rpms -- generate binary rpm packages" + @echo "make rpms-dom0 -- generate binary rpm packages for Dom0" + @echo "make update-repo-current -- copy newly generated rpms to qubes yum repo" + @echo "make update-repo-current-testing -- same, but to -current-testing repo" + @echo "make update-repo-unstable -- same, but to -testing repo" + @echo "make update-repo-installer -- copy dom0 rpms to installer repo" + @echo "make clean -- cleanup" + +rpms: rpms-dom0 + +rpms-vm: + @true + +rpms-dom0: + rpmbuild --define "_rpmdir $(RPMS_DIR)" -bb rpm_spec/core-dom0-linux.spec + rpm --addsign \ + $(RPMS_DIR)/x86_64/qubes-core-dom0-linux-$(VERSION)*.rpm + +update-repo-current: + ln -f $(RPMS_DIR)/x86_64/qubes-core-dom0-linux-$(VERSION)*$(DIST_DOM0)*.rpm ../yum/current-release/current/dom0/rpm/ + +update-repo-current-testing: + ln -f $(RPMS_DIR)/x86_64/qubes-core-dom0-linux-$(VERSION)*$(DIST_DOM0)*.rpm ../yum/current-release/current-testing/dom0/rpm/ + +update-repo-unstable: + ln -f $(RPMS_DIR)/x86_64/qubes-core-dom0-linux-$(VERSION)*$(DIST_DOM0)*.rpm ../yum/current-release/unstable/dom0/rpm/ + +update-repo-installer: + ln -f $(RPMS_DIR)/x86_64/qubes-core-dom0-linux-*$(VERSION)*$(DIST_DOM0)*.rpm ../installer/yum/qubes-dom0/rpm/ + +clean: + @true diff --git a/appmenus-files/qubes-appmenu-select.desktop b/appmenus-files/qubes-appmenu-select.desktop new file mode 100644 index 0000000..29f3ee1 --- /dev/null +++ b/appmenus-files/qubes-appmenu-select.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Version=1.0 +Type=Application +Exec=qubes-vm-settings %VMNAME% applications +Icon=/usr/share/qubes/icons/qubes.png +Terminal=false +Name=%VMNAME%: Add more shortcuts... +GenericName=%VMNAME%: Add more shortcuts... +StartupNotify=false +Categories=System; diff --git a/appmenus-files/qubes-dispvm-firefox.desktop b/appmenus-files/qubes-dispvm-firefox.desktop new file mode 100644 index 0000000..6e36ffd --- /dev/null +++ b/appmenus-files/qubes-dispvm-firefox.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Version=1.0 +Type=Application +Exec=sh -c 'echo firefox | /usr/lib/qubes/qfile-daemon-dvm qubes.VMShell dom0 DEFAULT red' +Icon=/usr/share/qubes/icons/dispvm-red.png +Terminal=false +Name=DispVM: Firefox web browser +GenericName=DispVM: Web browser +StartupNotify=false +Categories=Network; diff --git a/appmenus-files/qubes-dispvm.directory b/appmenus-files/qubes-dispvm.directory new file mode 100644 index 0000000..9b5544d --- /dev/null +++ b/appmenus-files/qubes-dispvm.directory @@ -0,0 +1,5 @@ +[Desktop Entry] +Encoding=UTF-8 +Type=Directory +Name=DisposableVM +Icon=/usr/share/qubes/icons/dispvm-red.png diff --git a/appmenus-files/qubes-servicevm.directory.template b/appmenus-files/qubes-servicevm.directory.template new file mode 100644 index 0000000..74ce62f --- /dev/null +++ b/appmenus-files/qubes-servicevm.directory.template @@ -0,0 +1,5 @@ +[Desktop Entry] +Encoding=UTF-8 +Type=Directory +Name=ServiceVM: %VMNAME% +Icon=%VMDIR%/icon.png diff --git a/appmenus-files/qubes-start.desktop b/appmenus-files/qubes-start.desktop new file mode 100644 index 0000000..63db9f3 --- /dev/null +++ b/appmenus-files/qubes-start.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Version=1.0 +Type=Application +Exec=qvm-start --quiet --tray %VMNAME% +Icon=%VMDIR%/icon.png +Terminal=false +Name=%VMNAME%: Start +GenericName=%VMNAME%: Start +StartupNotify=false +Categories=System; diff --git a/appmenus-files/qubes-templatevm.directory.template b/appmenus-files/qubes-templatevm.directory.template new file mode 100644 index 0000000..596fffa --- /dev/null +++ b/appmenus-files/qubes-templatevm.directory.template @@ -0,0 +1,5 @@ +[Desktop Entry] +Encoding=UTF-8 +Type=Directory +Name=Template: %VMNAME% +Icon=/usr/share/qubes/icons/template.png diff --git a/appmenus-files/qubes-vm.directory.template b/appmenus-files/qubes-vm.directory.template new file mode 100644 index 0000000..6825d20 --- /dev/null +++ b/appmenus-files/qubes-vm.directory.template @@ -0,0 +1,5 @@ +[Desktop Entry] +Encoding=UTF-8 +Type=Directory +Name=Domain: %VMNAME% +Icon=%VMDIR%/icon.png diff --git a/appmenus-scripts/convert-apptemplate2vm.sh b/appmenus-scripts/convert-apptemplate2vm.sh new file mode 100755 index 0000000..b5ab146 --- /dev/null +++ b/appmenus-scripts/convert-apptemplate2vm.sh @@ -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 + + diff --git a/appmenus-scripts/convert-dirtemplate2vm.sh b/appmenus-scripts/convert-dirtemplate2vm.sh new file mode 100755 index 0000000..9d1972b --- /dev/null +++ b/appmenus-scripts/convert-dirtemplate2vm.sh @@ -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 + + diff --git a/appmenus-scripts/create-apps-for-appvm.sh b/appmenus-scripts/create-apps-for-appvm.sh new file mode 100755 index 0000000..a7c46e9 --- /dev/null +++ b/appmenus-scripts/create-apps-for-appvm.sh @@ -0,0 +1,62 @@ +#!/bin/sh +# +# The Qubes OS Project, http://www.qubes-os.org +# +# Copyright (C) 2010 Joanna Rutkowska +# +# 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 +VMTYPE=$3 +if [ -z "$VMTYPE" ]; then + VMTYPE=appvms +fi +VMDIR=/var/lib/qubes/$VMTYPE/$VMNAME +APPSDIR=$VMDIR/apps + +if [ $# -lt 2 ]; then + echo "usage: $0 [appvms|vm-templates|servicevms]" + exit +fi +mkdir -p $APPSDIR + +if [ "$SRCDIR" != "none" ]; then + echo "--> Converting Appmenu Templates..." + if [ -r "$VMDIR/whitelisted-appmenus.list" ]; then + cat $VMDIR/whitelisted-appmenus.list | xargs -I{} /usr/libexec/qubes-appmenus/convert-apptemplate2vm.sh $SRCDIR/{} $APPSDIR $VMNAME $VMDIR + else + find $SRCDIR -name "*.desktop" $CHECK_WHITELISTED -exec /usr/libexec/qubes-appmenus/convert-apptemplate2vm.sh {} $APPSDIR $VMNAME $VMDIR \; + fi + /usr/libexec/qubes-appmenus/convert-apptemplate2vm.sh /usr/share/qubes-appmenus/qubes-appmenu-select.desktop $APPSDIR $VMNAME $VMDIR + + if [ "$VMTYPE" = "vm-templates" ]; then + DIR_TEMPLATE=/usr/share/qubes-appmenus/qubes-templatevm.directory.template + elif [ "$VMTYPE" = "servicevms" ]; then + DIR_TEMPLATE=/usr/share/qubes-appmenus/qubes-servicevm.directory.template + else + DIR_TEMPLATE=/usr/share/qubes-appmenus/qubes-vm.directory.template + fi + /usr/libexec/qubes-appmenus/convert-dirtemplate2vm.sh $DIR_TEMPLATE $APPSDIR/$VMNAME-vm.directory $VMNAME $VMDIR +fi + +echo "--> Adding Apps to the Menu..." +xdg-desktop-menu install $APPSDIR/*.directory $APPSDIR/*.desktop + +if [ -n "$KDE_SESSION_UID" ]; then + kbuildsycoca4 +fi diff --git a/appmenus-scripts/qubes-core-appmenus.py b/appmenus-scripts/qubes-core-appmenus.py new file mode 100644 index 0000000..47433de --- /dev/null +++ b/appmenus-scripts/qubes-core-appmenus.py @@ -0,0 +1,163 @@ +#!/usr/bin/python2 +# +# The Qubes OS Project, http://www.qubes-os.org +# +# Copyright (C) 2010 Joanna Rutkowska +# Copyright (C) 2013 Marek Marczykowski +# +# 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 subprocess +import sys +import os.path +import shutil + +from qubes.qubes import QubesVm,QubesHVm,QubesTemplateVm +from qubes.qubes import QubesException,QubesHost,QubesVmLabels +from qubes.qubes import vm_files,system_path,dry_run + +vm_files['appmenus_templates_subdir'] = 'apps.templates' +vm_files['appmenus_template_templates_subdir'] = 'apps-template.templates' +vm_files['appmenus_whitelist'] = 'whitelisted-appmenus.list' + +system_path['appmenu_start_hvm_template'] = '/usr/share/qubes-appmenus/qubes-start.desktop' +system_path['appmenu_create_cmd'] = '/usr/libexec/qubes-appmenus/create-apps-for-appvm.sh' +system_path['appmenu_remove_cmd'] = '/usr/libexec/qubes-appmenus/remove-appvm-appmenus.sh' + + +def QubesVm_get_attrs_config(self, attrs): + attrs["appmenus_templates_dir"] = { "eval": \ + 'os.path.join(self.dir_path, vm_files["appmenus_templates_subdir"]) if self.updateable else ' + \ + 'self.template.appmenus_templates_dir if self.template is not None else None' } + return attrs + +def QubesTemplateVm_get_attrs_config(self, attrs): + attrs['appmenus_templates_dir'] = { 'eval': 'os.path.join(self.dir_path, vm_files["appmenus_templates_subdir"])' } + return attrs + +def QubesVm_appmenus_create(self, verbose=False, source_template = None): + if source_template is None: + source_template = self.template + + if self.internal: + return + + vmtype = None + if self.is_netvm(): + vmtype = 'servicevms' + elif self.is_template(): + vmtype = 'vm-templates' + else: + vmtype = 'appvms' + + try: + if source_template is not None: + subprocess.check_call ([system_path["appmenu_create_cmd"], source_template.appmenus_templates_dir, self.name, vmtype]) + elif self.appmenus_templates_dir is not None: + subprocess.check_call ([system_path["appmenu_create_cmd"], self.appmenus_templates_dir, self.name, vmtype]) + else: + # Only add apps to menu + subprocess.check_call ([system_path["appmenu_create_cmd"], "none", self.name, vmtype]) + except subprocess.CalledProcessError: + print >> sys.stderr, "Ooops, there was a problem creating appmenus for {0} VM!".format (self.name) + +def QubesVm_appmenus_remove(self): + vmtype = None + if self.is_netvm(): + vmtype = 'servicevms' + elif self.is_template(): + vmtype = 'vm-templates' + else: + vmtype = 'appvms' + subprocess.check_call ([system_path["appmenu_remove_cmd"], self.name, vmtype]) + +def QubesVm_pre_rename(self, new_name): + self.appmenus_remove() + +def QubesVm_post_rename(self, old_name): + old_dirpath = os.path.join(os.path.dirname(self.dir_path), old_name) + if self.appmenus_templates_dir is not None: + self.appmenus_templates_dir = self.appmenus_templates_dir.replace(old_dirpath, self.dir_path) + + self.appmenus_create() + +def QubesVm_create_on_disk(self, verbose, source_template): + + if isinstance(self, QubesHVm): + if verbose: + print >> sys.stderr, "--> Creating appmenus directory: {0}".format(self.appmenus_templates_dir) + os.mkdir (self.appmenus_templates_dir) + shutil.copy (system_path["appmenu_start_hvm_template"], self.appmenus_templates_dir) + return + + source_whitelist_filename = 'vm-' + vm_files["appmenus_whitelist"] + if self.is_netvm(): + source_whitelist_filename = 'netvm-' + vm_files["appmenus_whitelist"] + if os.path.exists(os.path.join(source_template.dir_path, source_whitelist_filename)): + if verbose: + print >> sys.stderr, "--> Creating default whitelisted apps list: {0}".\ + format(self.dir_path + '/' + vm_files["whitelisted_appmenus"]) + shutil.copy(os.path.join(source_template.dir_path, source_whitelist_filename), + os.path.join(self.dir_path, vm_files["whitelisted_appmenus"])) + + if self.updateable: + if verbose: + print >> sys.stderr, "--> Copying the template's appmenus templates dir:\n{0} ==>\n{1}".\ + format(source_template.appmenus_templates_dir, self.appmenus_templates_dir) + shutil.copytree (source_template.appmenus_templates_dir, self.appmenus_templates_dir) + + # Create appmenus + self.appmenus_create(verbose=verbose) + +def QubesVm_clone_disk_files(self, src_vm, verbose): + if src_vm.updateable and src_vm.appmenus_templates_dir is not None and self.appmenus_templates_dir is not None: + if verbose: + print >> sys.stderr, "--> Copying the template's appmenus templates dir:\n{0} ==>\n{1}".\ + format(src_vm.appmenus_templates_dir, self.appmenus_templates_dir) + shutil.copytree (src_vm.appmenus_templates_dir, self.appmenus_templates_dir) + + for whitelist in ( + vm_files["appmenus_whitelist"], + 'vm-' + vm_files["appmenus_whitelist"], + 'netvm-' + vm_files["appmenus_whitelist"]): + if os.path.exists(os.path.join(src_vm.dir_path, whitelist)): + if verbose: + print >> sys.stderr, "--> Copying whitelisted apps list: {0}".\ + format(whitelist) + shutil.copy(os.path.join(src_vm.dir_path, whitelist), + os.path.join(self.dir_path, whitelist)) + + # Create appmenus + self.appmenus_create(verbose=verbose) + +def QubesVm_remove_from_disk(self): + self.appmenus_remove() + +# new methods +QubesVm.appmenus_create = QubesVm_appmenus_create +QubesVm.appmenus_remove = QubesVm_appmenus_remove + +# hooks for existing methods +QubesVm.hooks_get_attrs_config.append(QubesVm_get_attrs_config) +QubesVm.hooks_clone_disk_files.append(QubesVm_clone_disk_files) +QubesVm.hooks_pre_rename.append(QubesVm_pre_rename) +QubesVm.hooks_post_rename.append(QubesVm_post_rename) +QubesVm.hooks_create_on_disk.append(QubesVm_create_on_disk) +QubesVm.hooks_clone_disk_files.append(QubesVm_clone_disk_files) +QubesVm.hooks_remove_from_disk.append(QubesVm_remove_from_disk) + +QubesTemplateVm.hooks_get_attrs_config.append(QubesTemplateVm_get_attrs_config) diff --git a/appmenus-scripts/qubes-receive-appmenus b/appmenus-scripts/qubes-receive-appmenus new file mode 100755 index 0000000..7e06567 --- /dev/null +++ b/appmenus-scripts/qubes-receive-appmenus @@ -0,0 +1,220 @@ +#!/usr/bin/python +# +# The Qubes OS Project, http://www.qubes-os.org +# +# Copyright (C) 2011 Marek Marczykowski +# +# 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 subprocess +import re +import os +import sys +import fnmatch +import shutil +from optparse import OptionParser +from qubes.qubes import QubesVmCollection,QubesException + +# fields required to be present (and verified) in retrieved desktop file +required_fields = [ "Name", "Exec" ] + +#limits +appmenus_line_size = 1024 +appmenus_line_count = 100000 + +# regexps for sanitization of retrieved values +std_re = re.compile(r"^[/a-zA-Z0-9.,&() -]*$") +fields_regexp = { + "Name": std_re, + "GenericName": std_re, + "Comment": std_re, + "Categories": re.compile(r"^[a-zA-Z0-9/.; -]*$"), + "Exec": re.compile(r"^[a-zA-Z0-9%>/:.= -]*$"), +} + +def get_appmenus(vm): + global appmenus_line_count + global appmenus_line_size + untrusted_appmenulist = [] + if vm is None: + while appmenus_line_count > 0: + untrusted_line = sys.stdin.readline(appmenus_line_size) + if untrusted_line == "": + break; + untrusted_appmenulist.append(untrusted_line.strip()) + appmenus_line_count -= 1 + if appmenus_line_count == 0: + raise QubesException("Line count limit exceeded") + else: + p = vm.run('QUBESRPC qubes.GetAppmenus dom0', passio_popen=True) + while appmenus_line_count > 0: + untrusted_line = p.stdout.readline(appmenus_line_size) + if untrusted_line == "": + break; + untrusted_appmenulist.append(untrusted_line.strip()) + appmenus_line_count -= 1 + p.wait() + if p.returncode != 0: + raise QubesException("Error getting application list") + if appmenus_line_count == 0: + raise QubesException("Line count limit exceeded") + + row_no = 0 + appmenus = {} + line_rx = re.compile(r"([a-zA-Z0-9-.]+.desktop):([a-zA-Z0-9-]+(?:\[[a-zA-Z@_]+\])?)=(.*)") + ignore_rx = re.compile(r".*([a-zA-Z0-9-.]+.desktop):(#.*|\s+)$") + for untrusted_line in untrusted_appmenulist: + # Ignore blank lines and comments + if len(untrusted_line) == 0 or ignore_rx.match(untrusted_line): + continue + # use search instead of match to skip file path + untrusted_m = line_rx.search(untrusted_line) + if untrusted_m: + untrusted_key = untrusted_m.group(2) + untrusted_value = untrusted_m.group(3) + # Look only at predefined keys + if fields_regexp.has_key(untrusted_key): + if fields_regexp[untrusted_key].match(untrusted_value): + # now values are sanitized + key = untrusted_key + value = untrusted_value + filename = untrusted_m.group(1) + + if not appmenus.has_key(filename): + appmenus[filename] = {} + + appmenus[filename][key]=value + else: + print >>sys.stderr, "Warning: ignoring key %s: %s" % (untrusted_key, untrusted_value) + # else: ignore this key + else: + print >>sys.stderr, "Warning: ignoring line: %s" % (untrusted_line); + + return appmenus + + +def create_template(path, values): + + # check if all required fields are present + for key in required_fields: + if not values.has_key(key): + print >>sys.stderr, "Warning: not creating/updating '%s' because of missing '%s' key" % (path, key) + return + + desktop_file = open(path, "w") + desktop_file.write("[Desktop Entry]\n") + desktop_file.write("Version=1.0\n") + desktop_file.write("Type=Application\n") + desktop_file.write("Terminal=false\n") + desktop_file.write("X-Qubes-VmName=%VMNAME%\n") + desktop_file.write("Icon=%VMDIR%/icon.png\n") + for key in ["Name", "GenericName" ]: + if values.has_key(key): + desktop_file.write("{0}=%VMNAME%: {1}\n".format(key, values[key])) + + for key in [ "Comment", "Categories" ]: + if values.has_key(key): + desktop_file.write("{0}={1}\n".format(key, values[key])) + + desktop_file.write("Exec=qvm-run -q --tray -a %VMNAME% '{0}'\n".format(values['Exec'])) + desktop_file.close() + + +def main(): + + env_vmname = os.environ.get("QREXEC_REMOTE_DOMAIN") + usage = "usage: %prog [options] \n"\ + "Updates desktop file templates for given StandaloneVM or TemplateVM" + + parser = OptionParser (usage) + parser.add_option ("-v", "--verbose", action="store_true", dest="verbose", default=False) + parser.add_option ("--force-root", action="store_true", dest="force_root", default=False, + help="Force to run, even with root privileges") + + (options, args) = parser.parse_args () + if (len (args) != 1) and env_vmname is None: + parser.error ("You must specify at least the VM name!") + + if env_vmname: + vmname=env_vmname + else: + vmname=args[0] + + if os.geteuid() == 0: + if not options.force_root: + print >> sys.stderr, "*** Running this tool as root is strongly discouraged, this will lead you in permissions problems." + print >> sys.stderr, "Retry as unprivileged user." + print >> sys.stderr, "... or use --force-root to continue anyway." + exit(1) + + 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 >>sys.stderr, "ERROR: A VM with the name '{0}' does not exist in the system.".format(vmname) + exit(1) + + if vm.template is not None: + print >>sys.stderr, "ERROR: To sync appmenus for template based VM, do it on template instead" + exit(1) + + if not vm.is_running(): + print >>sys.stderr, "ERROR: Appmenus can be retrieved only from running VM - start it first" + exit(1) + + new_appmenus = {} + if env_vmname is None: + new_appmenus = get_appmenus(vm) + else: + options.verbose = False + new_appmenus = get_appmenus(None) + + if len(new_appmenus) == 0: + print >>sys.stderr, "ERROR: No appmenus received, terminating" + exit(1) + + if not os.path.exists(vm.appmenus_templates_dir): + os.mkdir(vm.appmenus_templates_dir) + + # Create new/update existing templates + if options.verbose: + print >> sys.stderr, "--> Got {0} appmenus, storing to disk".format(str(len(new_appmenus))) + for appmenu_file in new_appmenus.keys(): + if options.verbose: + if os.path.exists(vm.appmenus_templates_dir + '/' + appmenu_file): + print >> sys.stderr, "---> Updating {0}".format(appmenu_file) + else: + print >> sys.stderr, "---> Creating {0}".format(appmenu_file) + create_template(vm.appmenus_templates_dir + '/' + appmenu_file, new_appmenus[appmenu_file]) + + # Delete appmenus of remove applications + if options.verbose: + print >> sys.stderr, "--> Cleaning old files" + for appmenu_file in os.listdir(vm.appmenus_templates_dir): + if not fnmatch.fnmatch(appmenu_file, '*.desktop'): + continue + + if not new_appmenus.has_key(appmenu_file): + if options.verbose: + print >> sys.stderr, "---> Removing {0}".format(appmenu_file) + os.unlink(vm.appmenus_templates_dir + '/' + appmenu_file) + +main() diff --git a/appmenus-scripts/qubes.SyncAppMenus b/appmenus-scripts/qubes.SyncAppMenus new file mode 100644 index 0000000..bbb5540 --- /dev/null +++ b/appmenus-scripts/qubes.SyncAppMenus @@ -0,0 +1 @@ +/usr/lib/qubes/qubes-receive-appmenus diff --git a/appmenus-scripts/qubes.SyncAppMenus.policy b/appmenus-scripts/qubes.SyncAppMenus.policy new file mode 100644 index 0000000..0f00b0b --- /dev/null +++ b/appmenus-scripts/qubes.SyncAppMenus.policy @@ -0,0 +1,6 @@ +## Note that policy parsing stops at the first match, +## so adding anything below "$anyvm $anyvm action" line will have no effect + +## Please use a single # to start your custom comments + +$anyvm dom0 allow diff --git a/appmenus-scripts/remove-appvm-appmenus.sh b/appmenus-scripts/remove-appvm-appmenus.sh new file mode 100755 index 0000000..c7a7a85 --- /dev/null +++ b/appmenus-scripts/remove-appvm-appmenus.sh @@ -0,0 +1,23 @@ +#!/bin/sh +VMNAME=$1 +VMTYPE=$2 +if [ -z "$VMTYPE" ]; then + VMTYPE=appvms +fi +VMDIR=/var/lib/qubes/$VMTYPE/$VMNAME +APPSDIR=$VMDIR/apps + +if [ $# -lt 1 ]; then + echo "usage: $0 [appvms|vm-templates|servicevms]" + exit +fi + +if ls $APPSDIR/*.directory $APPSDIR/*.desktop > /dev/null 2>&1; then + xdg-desktop-menu uninstall $APPSDIR/*.directory $APPSDIR/*.desktop + rm -f $APPSDIR/*.desktop $APPSDIR/*.directory + rm -f $HOME/.config/menus/applications-merged/user-$VMNAME-vm.menu +fi + +if [ -n "$KDE_SESSION_UID" ]; then + kbuildsycoca4 +fi diff --git a/icons/black.png b/icons/black.png new file mode 100644 index 0000000..9095231 Binary files /dev/null and b/icons/black.png differ diff --git a/icons/blue.png b/icons/blue.png new file mode 100644 index 0000000..6a19410 Binary files /dev/null and b/icons/blue.png differ diff --git a/icons/credits-crystal-icons b/icons/credits-crystal-icons new file mode 100644 index 0000000..92a54bb --- /dev/null +++ b/icons/credits-crystal-icons @@ -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. diff --git a/icons/credits-gnome-icons b/icons/credits-gnome-icons new file mode 100644 index 0000000..867d280 --- /dev/null +++ b/icons/credits-gnome-icons @@ -0,0 +1 @@ +dom0-update-avail icon from gnome-packagekit project distributed under GPLv2 diff --git a/icons/credits-padlock-icons b/icons/credits-padlock-icons new file mode 100644 index 0000000..9098c41 --- /dev/null +++ b/icons/credits-padlock-icons @@ -0,0 +1 @@ +Color padlock images downloaded from www.openclipart.org diff --git a/icons/dispvm-black.png b/icons/dispvm-black.png new file mode 100644 index 0000000..2896be7 Binary files /dev/null and b/icons/dispvm-black.png differ diff --git a/icons/dispvm-blue.png b/icons/dispvm-blue.png new file mode 100644 index 0000000..77fc3e3 Binary files /dev/null and b/icons/dispvm-blue.png differ diff --git a/icons/dispvm-gray.png b/icons/dispvm-gray.png new file mode 100644 index 0000000..dfd79c2 Binary files /dev/null and b/icons/dispvm-gray.png differ diff --git a/icons/dispvm-green.png b/icons/dispvm-green.png new file mode 100644 index 0000000..55325f1 Binary files /dev/null and b/icons/dispvm-green.png differ diff --git a/icons/dispvm-orange.png b/icons/dispvm-orange.png new file mode 100644 index 0000000..68197f6 Binary files /dev/null and b/icons/dispvm-orange.png differ diff --git a/icons/dispvm-padlock-layers.xcf b/icons/dispvm-padlock-layers.xcf new file mode 100644 index 0000000..36cf2fb Binary files /dev/null and b/icons/dispvm-padlock-layers.xcf differ diff --git a/icons/dispvm-purple.png b/icons/dispvm-purple.png new file mode 100644 index 0000000..71a9877 Binary files /dev/null and b/icons/dispvm-purple.png differ diff --git a/icons/dispvm-red.png b/icons/dispvm-red.png new file mode 100644 index 0000000..43f397d Binary files /dev/null and b/icons/dispvm-red.png differ diff --git a/icons/dispvm-yellow.png b/icons/dispvm-yellow.png new file mode 100644 index 0000000..5fa5326 Binary files /dev/null and b/icons/dispvm-yellow.png differ diff --git a/icons/dom0-update-avail.png b/icons/dom0-update-avail.png new file mode 100644 index 0000000..95a86cb Binary files /dev/null and b/icons/dom0-update-avail.png differ diff --git a/icons/gray.png b/icons/gray.png new file mode 100644 index 0000000..3a979eb Binary files /dev/null and b/icons/gray.png differ diff --git a/icons/green.png b/icons/green.png new file mode 100644 index 0000000..fb0f549 Binary files /dev/null and b/icons/green.png differ diff --git a/icons/netvm.png b/icons/netvm.png new file mode 100644 index 0000000..bafb6c6 Binary files /dev/null and b/icons/netvm.png differ diff --git a/icons/orange.png b/icons/orange.png new file mode 100644 index 0000000..1ec4231 Binary files /dev/null and b/icons/orange.png differ diff --git a/icons/purple.png b/icons/purple.png new file mode 100644 index 0000000..0076bfa Binary files /dev/null and b/icons/purple.png differ diff --git a/icons/qubes.png b/icons/qubes.png new file mode 100644 index 0000000..996640c Binary files /dev/null and b/icons/qubes.png differ diff --git a/icons/red.png b/icons/red.png new file mode 100644 index 0000000..240f7fc Binary files /dev/null and b/icons/red.png differ diff --git a/icons/template.png b/icons/template.png new file mode 100644 index 0000000..996640c Binary files /dev/null and b/icons/template.png differ diff --git a/icons/yellow.png b/icons/yellow.png new file mode 100644 index 0000000..878cc60 Binary files /dev/null and b/icons/yellow.png differ diff --git a/rpm_spec/core-dom0-linux.spec b/rpm_spec/core-dom0-linux.spec new file mode 100644 index 0000000..e731d0e --- /dev/null +++ b/rpm_spec/core-dom0-linux.spec @@ -0,0 +1,128 @@ +# +# This is the SPEC file for creating binary RPMs for the Dom0. +# +# +# The Qubes OS Project, http://www.qubes-os.org +# +# Copyright (C) 2013 Marek Marczykowski +# +# 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)} + +%define _dracutmoddir /usr/lib/dracut/modules.d +%if %{fedora} < 17 +%define _dracutmoddir /usr/share/dracut/modules.d +%endif + +Name: qubes-core-dom0-linux +Version: %{version} +Release: 1%{?dist} +Summary: Linux-specific files for Qubes dom0 + +Group: Qubes +Vendor: Invisible Things Lab +License: GPL +URL: http://www.qubes-os.org + +BuildRequires: ImageMagick +Requires: qubes-core-dom0 + +%define _builddir %(pwd) + +%description +Linux customizations required to use system as Qubes dom0. +Additionally some graphical elements for every Linux desktop envirnment (icons, +appmenus etc). + +%prep +# we operate on the current directory, so no need to unpack anything +# symlink is to generate useful debuginfo packages +rm -f %{name}-%{version} +ln -sf . %{name}-%{version} +%setup -T -D + +%build +python -m compileall appmenus-scripts +python -O -m compileall appmenus-scripts + +%install +mkdir -p $RPM_BUILD_ROOT%{python_sitearch}/qubes/modules +cp appmenus-scripts/qubes-core-appmenus.py $RPM_BUILD_ROOT%{python_sitearch}/qubes/modules/10appmenus.py +cp appmenus-scripts/qubes-core-appmenus.pyc $RPM_BUILD_ROOT%{python_sitearch}/qubes/modules/10appmenus.pyc +cp appmenus-scripts/qubes-core-appmenus.pyo $RPM_BUILD_ROOT%{python_sitearch}/qubes/modules/10appmenus.pyo + +mkdir -p $RPM_BUILD_ROOT/usr/libexec/qubes-appmenus +cp appmenus-scripts/*.sh $RPM_BUILD_ROOT/usr/libexec/qubes-appmenus/ +cp appmenus-scripts/qubes-receive-appmenus $RPM_BUILD_ROOT/usr/libexec/qubes-appmenus/ + +mkdir -p $RPM_BUILD_ROOT/etc/qubes-rpc/policy +cp appmenus-scripts/qubes.SyncAppMenus $RPM_BUILD_ROOT/etc/qubes-rpc/ +cp appmenus-scripts/qubes.SyncAppMenus.policy $RPM_BUILD_ROOT/etc/qubes-rpc/policy/ + +mkdir -p $RPM_BUILD_ROOT/usr/share/qubes/icons +for icon in icons/*.png; do + convert -resize 48 $icon $RPM_BUILD_ROOT/usr/share/qubes/$icon +done + +mkdir -p $RPM_BUILD_ROOT/usr/share/qubes-appmenus/ +cp appmenus-files/* $RPM_BUILD_ROOT/usr/share/qubes-appmenus/ + +%post + +for i in /usr/share/qubes/icons/*.png ; do + xdg-icon-resource install --novendor --size 48 $i +done + +xdg-desktop-menu install /usr/share/qubes-appmenus/qubes-dispvm.directory /usr/share/qubes-appmenus/qubes-dispvm-firefox.desktop + +%preun +if [ "$1" = 0 ] ; then + # no more packages left + + for i in /usr/share/qubes/icons/*.png ; do + xdg-icon-resource uninstall --novendor --size 48 $i + done + + xdg-desktop-menu uninstall /usr/share/qubes-appmenus/qubes-dispvm.directory /usr/share/qubes-appmenus/qubes-dispvm-firefox.desktop +fi + + +%files +/etc/qubes-rpc/policy/qubes.SyncAppMenus.policy +/etc/qubes-rpc/qubes.SyncAppMenus +%{python_sitearch}/qubes/modules/10appmenus.py +%{python_sitearch}/qubes/modules/10appmenus.pyc +%{python_sitearch}/qubes/modules/10appmenus.pyo +/usr/libexec/qubes-appmenus/convert-apptemplate2vm.sh +/usr/libexec/qubes-appmenus/convert-dirtemplate2vm.sh +/usr/libexec/qubes-appmenus/create-apps-for-appvm.sh +/usr/libexec/qubes-appmenus/qubes-receive-appmenus +/usr/libexec/qubes-appmenus/remove-appvm-appmenus.sh +/usr/share/qubes-appmenus/qubes-appmenu-select.desktop +/usr/share/qubes-appmenus/qubes-dispvm-firefox.desktop +/usr/share/qubes-appmenus/qubes-dispvm.directory +/usr/share/qubes-appmenus/qubes-servicevm.directory.template +/usr/share/qubes-appmenus/qubes-start.desktop +/usr/share/qubes-appmenus/qubes-templatevm.directory.template +/usr/share/qubes-appmenus/qubes-vm.directory.template +/usr/share/qubes/icons/*.png + +%changelog + diff --git a/version b/version new file mode 100644 index 0000000..49d5957 --- /dev/null +++ b/version @@ -0,0 +1 @@ +0.1