Ver Fonte

Merge branch 'fc31'

* fc31:
  rpm: switch deps to python3-setuptools on CentOS too
  debian: switch to python3
  Use spaces in xdg-icon script
  Convert other scripts to python3
  Convert qubesagent module to python3
  Minor codestyle fix in qubesadmin/firewall.py
  Require python setuptools
  Update python2 dependencies to python3 and clean deprecated requirements
Marek Marczykowski-Górecki há 4 anos atrás
pai
commit
3c47a7890f

+ 1 - 1
Makefile

@@ -11,7 +11,7 @@ BINDIR ?= /usr/bin
 LIBDIR ?= /usr/lib
 LIBDIR ?= /usr/lib
 SYSLIBDIR ?= /lib
 SYSLIBDIR ?= /lib
 
 
-PYTHON ?= /usr/bin/python2
+PYTHON ?= /usr/bin/python3
 PYTHON_SITEARCH = $(shell python2 -c 'import distutils.sysconfig; print distutils.sysconfig.get_python_lib(1)')
 PYTHON_SITEARCH = $(shell python2 -c 'import distutils.sysconfig; print distutils.sysconfig.get_python_lib(1)')
 PYTHON2_SITELIB = $(shell python2 -c 'import distutils.sysconfig; print distutils.sysconfig.get_python_lib()')
 PYTHON2_SITELIB = $(shell python2 -c 'import distutils.sysconfig; print distutils.sysconfig.get_python_lib()')
 PYTHON3_SITELIB = $(shell python3 -c 'import distutils.sysconfig; print(distutils.sysconfig.get_python_lib())')
 PYTHON3_SITELIB = $(shell python3 -c 'import distutils.sysconfig; print(distutils.sysconfig.get_python_lib())')

+ 6 - 6
archlinux/PKGBUILD

@@ -61,10 +61,10 @@ build() {
 # * core systemd services and drop-ins
 # * core systemd services and drop-ins
 # * basic network functionality (setting IP address, DNS, default gateway)
 # * basic network functionality (setting IP address, DNS, default gateway)
 package_qubes-vm-core() {
 package_qubes-vm-core() {
-    depends=("qubes-vm-utils>=3.1.3" python2 python2-xdg ethtool ntp net-tools
+    depends=("qubes-vm-utils>=3.1.3" python2 python3-xdg ethtool ntp net-tools
              gnome-packagekit imagemagick fakeroot notification-daemon dconf
              gnome-packagekit imagemagick fakeroot notification-daemon dconf
-             zenity qubes-libvchan "qubes-db-vm>=3.2.1" haveged python2-gobject
-             python2-dbus xdg-utils notification-daemon gawk sed procps-ng librsvg
+             zenity qubes-libvchan "qubes-db-vm>=3.2.1" haveged python3-gobject
+             python3-dbus xdg-utils notification-daemon gawk sed procps-ng librsvg
              socat
              socat
              )
              )
     optdepends=(gnome-keyring gnome-settings-daemon python2-nautilus gpk-update-viewer qubes-vm-networking qubes-vm-keyring)
     optdepends=(gnome-keyring gnome-settings-daemon python2-nautilus gpk-update-viewer qubes-vm-networking qubes-vm-keyring)
@@ -74,7 +74,7 @@ package_qubes-vm-core() {
     # shellcheck disable=SC2154
     # shellcheck disable=SC2154
     make -C qrexec install DESTDIR="$pkgdir" SBINDIR=/usr/bin LIBDIR=/usr/lib SYSLIBDIR=/usr/lib
     make -C qrexec install DESTDIR="$pkgdir" SBINDIR=/usr/bin LIBDIR=/usr/lib SYSLIBDIR=/usr/lib
 
 
-    PYTHON=python2 make install-corevm DESTDIR="$pkgdir" SBINDIR=/usr/bin LIBDIR=/usr/lib SYSLIBDIR=/usr/lib SYSTEM_DROPIN_DIR=/usr/lib/systemd/system USER_DROPIN_DIR=/usr/lib/systemd/user DIST=archlinux
+    make install-corevm DESTDIR="$pkgdir" SBINDIR=/usr/bin LIBDIR=/usr/lib SYSLIBDIR=/usr/lib SYSTEM_DROPIN_DIR=/usr/lib/systemd/system USER_DROPIN_DIR=/usr/lib/systemd/user DIST=archlinux
 
 
     # Remove things non wanted in archlinux
     # Remove things non wanted in archlinux
     rm -r "$pkgdir/etc/yum"*
     rm -r "$pkgdir/etc/yum"*
@@ -122,13 +122,13 @@ EOF
 #
 #
 package_qubes-vm-networking() {
 package_qubes-vm-networking() {
     pkgdesc="Qubes OS tools allowing to use a Qubes VM as a NetVM/ProxyVM"
     pkgdesc="Qubes OS tools allowing to use a Qubes VM as a NetVM/ProxyVM"
-    depends=(qubes-vm-core "qubes-vm-utils>=3.1.3" python2 ethtool net-tools
+    depends=(qubes-vm-core "qubes-vm-utils>=3.1.3" python3 ethtool net-tools
              "qubes-db-vm>=3.2.1" networkmanager iptables tinyproxy nftables
              "qubes-db-vm>=3.2.1" networkmanager iptables tinyproxy nftables
              )
              )
     install=PKGBUILD-networking.install
     install=PKGBUILD-networking.install
 
 
     # shellcheck disable=SC2154
     # shellcheck disable=SC2154
-    PYTHON=python2 make install-netvm DESTDIR="$pkgdir" SBINDIR=/usr/bin LIBDIR=/usr/lib SYSLIBDIR=/usr/lib SYSTEM_DROPIN_DIR=/usr/lib/systemd/system USER_DROPIN_DIR=/usr/lib/systemd/user DIST=archlinux
+    make install-netvm DESTDIR="$pkgdir" SBINDIR=/usr/bin LIBDIR=/usr/lib SYSLIBDIR=/usr/lib SYSTEM_DROPIN_DIR=/usr/lib/systemd/system USER_DROPIN_DIR=/usr/lib/systemd/user DIST=archlinux
 
 
 }
 }
 
 

+ 9 - 9
debian/control

@@ -7,7 +7,7 @@ Build-Depends:
     libqubes-rpc-filecopy-dev (>= 3.1.3),
     libqubes-rpc-filecopy-dev (>= 3.1.3),
     libvchan-xen-dev,
     libvchan-xen-dev,
     python,
     python,
-    python-setuptools,
+    python3-setuptools,
     debhelper,
     debhelper,
     quilt,
     quilt,
     libxen-dev,
     libxen-dev,
@@ -39,12 +39,12 @@ Depends:
     procps,
     procps,
     util-linux,
     util-linux,
     e2fsprogs,
     e2fsprogs,
-    python2.7,
-    python-daemon,
-    python-qubesdb,
-    python-gi,
-    python-xdg,
-    python-dbus,
+    python3-daemon,
+    python3-distutils,
+    python3-qubesdb,
+    python3-gi,
+    python3-xdg,
+    python3-dbus,
     qubes-utils (>= 3.1.3),
     qubes-utils (>= 3.1.3),
     qubes-core-qrexec,
     qubes-core-qrexec,
     qubesdb-vm,
     qubesdb-vm,
@@ -54,7 +54,7 @@ Depends:
     xen-utils-common,
     xen-utils-common,
     xen-utils-guest,
     xen-utils-guest,
     xenstore-utils,
     xenstore-utils,
-    ${python:Depends},
+    ${python3:Depends},
     ${shlibs:Depends},
     ${shlibs:Depends},
     ${misc:Depends}
     ${misc:Depends}
 Recommends:
 Recommends:
@@ -128,7 +128,7 @@ Depends:
     socat,
     socat,
     tinyproxy,
     tinyproxy,
     iproute2,
     iproute2,
-    ${python:Depends},
+    ${python3:Depends},
     ${misc:Depends}
     ${misc:Depends}
 Suggests:
 Suggests:
     nftables,
     nftables,

+ 2 - 2
debian/qubes-core-agent.install

@@ -107,8 +107,8 @@ usr/bin/qvm-connect-tcp
 usr/bin/qvm-console
 usr/bin/qvm-console
 usr/bin/qvm-sync-clock
 usr/bin/qvm-sync-clock
 usr/bin/xenstore-watch-qubes
 usr/bin/xenstore-watch-qubes
-usr/lib/python2.7/dist-packages/qubesagent-*.egg-info/*
-usr/lib/python2.7/dist-packages/qubesagent/*
+usr/lib/python3/dist-packages/qubesagent-*.egg-info/*
+usr/lib/python3/dist-packages/qubesagent/*
 usr/lib/qubes-bind-dirs.d/30_cron.conf
 usr/lib/qubes-bind-dirs.d/30_cron.conf
 usr/lib/qubes/close-window
 usr/lib/qubes/close-window
 usr/lib/qubes/init/bind-dirs.sh
 usr/lib/qubes/init/bind-dirs.sh

+ 1 - 1
debian/rules

@@ -9,7 +9,7 @@ include /usr/share/dpkg/default.mk
 export DESTDIR=$(shell pwd)/debian/tmp
 export DESTDIR=$(shell pwd)/debian/tmp
 
 
 %:
 %:
-	dh $@ --with systemd,python2 --with=config-package
+	dh $@ --with systemd,python3 --with=config-package
 
 
 override_dh_auto_build:
 override_dh_auto_build:
 	make all
 	make all

+ 1 - 1
misc/qubes-desktop-run

@@ -1,4 +1,4 @@
-#!/usr/bin/python2
+#!/usr/bin/python3
 
 
 from qubesagent.xdg import launch
 from qubesagent.xdg import launch
 import sys
 import sys

+ 5 - 5
misc/qubes-session-autostart

@@ -1,9 +1,9 @@
-#!/usr/bin/python2
+#!/usr/bin/python3
 # -*- coding: utf-8 -*-
 # -*- coding: utf-8 -*-
 #
 #
 # The Qubes OS Project, http://www.qubes-os.org
 # The Qubes OS Project, http://www.qubes-os.org
 #
 #
-# Copyright (C) 2015  Marek Marczykowski-Górecki
+# Copyright (C) 2015-2019  Marek Marczykowski-Górecki
 #                                        <marmarek@invisiblethingslab.com>
 #                                        <marmarek@invisiblethingslab.com>
 #
 #
 # This program is free software; you can redistribute it and/or
 # This program is free software; you can redistribute it and/or
@@ -21,7 +21,6 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 #
 #
 #
 #
-import subprocess
 import sys
 import sys
 
 
 from xdg.DesktopEntry import DesktopEntry
 from xdg.DesktopEntry import DesktopEntry
@@ -78,8 +77,9 @@ def process_autostart(environments):
                 if entry_should_be_started(entry, environments):
                 if entry_should_be_started(entry, environments):
                     launch(entry_path, wait=False)
                     launch(entry_path, wait=False)
             except Exception as e:
             except Exception as e:
-                print >>sys.stderr, "Failed to process '{}': {}".format(
-                    entry_name, str(e)
+                print("Failed to process '{}': {}".format(
+                    entry_name, str(e)),
+                    file=sys.stderr
                 )
                 )
 
 
 def main():
 def main():

+ 1 - 1
misc/qvm-features-request

@@ -1,4 +1,4 @@
-#!/usr/bin/python2
+#!/usr/bin/python3
 # vim: fileencoding=utf-8
 # vim: fileencoding=utf-8
 
 
 #
 #

+ 1 - 1
qubes-rpc/qrun-in-vm

@@ -1,4 +1,4 @@
-#!/usr/bin/python2
+#!/usr/bin/python3
 # Send the command to the remote side, and then transfer stdin from local to
 # Send the command to the remote side, and then transfer stdin from local to
 # remote and stdout from remote to local.
 # remote and stdout from remote to local.
 #
 #

+ 8 - 8
qubes-rpc/xdg-icon

@@ -1,4 +1,4 @@
-#!/usr/bin/python2
+#!/usr/bin/python3
 import xdg.IconTheme
 import xdg.IconTheme
 import sys
 import sys
 import os
 import os
@@ -7,15 +7,15 @@ themes = ['Humanity', 'Adwaita', 'gnome', 'oxygen']
 themes = themes + sorted([d for d in os.listdir("/usr/share/icons") if d not in themes and os.path.isdir("/usr/share/icons/" + d)])
 themes = themes + sorted([d for d in os.listdir("/usr/share/icons") if d not in themes and os.path.isdir("/usr/share/icons/" + d)])
 
 
 if len(sys.argv) < 3:
 if len(sys.argv) < 3:
-	print "Usage:", sys.argv[0], "ICON SIZE"
-	sys.exit(1)
+    print("Usage:", sys.argv[0], "ICON SIZE")
+    sys.exit(1)
 
 
 for theme in themes:
 for theme in themes:
-	icon = xdg.IconTheme.getIconPath(sys.argv[1], theme = theme, size = int(sys.argv[2]))
-	if icon is not None:
-		break
+    icon = xdg.IconTheme.getIconPath(sys.argv[1], theme = theme, size = int(sys.argv[2]))
+    if icon is not None:
+        break
 
 
 if icon is None:
 if icon is None:
-	sys.exit(1)
+    sys.exit(1)
 
 
-print icon
+print(icon)

+ 46 - 46
qubesagent/firewall.py

@@ -1,4 +1,3 @@
-#!/usr/bin/python2 -O
 # vim: fileencoding=utf-8
 # vim: fileencoding=utf-8
 
 
 #
 #
@@ -51,13 +50,13 @@ class FirewallWorker(object):
         self.log.addHandler(logging.StreamHandler(sys.stderr))
         self.log.addHandler(logging.StreamHandler(sys.stderr))
 
 
     def init(self):
     def init(self):
-        '''Create appropriate chains/tables'''
+        """Create appropriate chains/tables"""
         raise NotImplementedError
         raise NotImplementedError
 
 
     def sd_notify(self, state):
     def sd_notify(self, state):
-        '''Send notification to systemd, if available'''
+        """Send notification to systemd, if available"""
         # based on sdnotify python module
         # based on sdnotify python module
-        if not 'NOTIFY_SOCKET' in os.environ:
+        if 'NOTIFY_SOCKET' not in os.environ:
             return
             return
         addr = os.environ['NOTIFY_SOCKET']
         addr = os.environ['NOTIFY_SOCKET']
         if addr[0] == '@':
         if addr[0] == '@':
@@ -71,39 +70,40 @@ class FirewallWorker(object):
             pass
             pass
 
 
     def cleanup(self):
     def cleanup(self):
-        '''Remove tables/chains - reverse work done by init'''
+        """Remove tables/chains - reverse work done by init"""
         raise NotImplementedError
         raise NotImplementedError
 
 
     def apply_rules(self, source_addr, rules):
     def apply_rules(self, source_addr, rules):
-        '''Apply rules in given source address'''
+        """Apply rules in given source address"""
         raise NotImplementedError
         raise NotImplementedError
 
 
     def run_firewall_dir(self):
     def run_firewall_dir(self):
-        '''Run scripts dir contents, before user script'''
+        """Run scripts dir contents, before user script"""
         script_dir_paths = ['/etc/qubes/qubes-firewall.d',
         script_dir_paths = ['/etc/qubes/qubes-firewall.d',
-                      '/rw/config/qubes-firewall.d']
+                            '/rw/config/qubes-firewall.d']
         for script_dir_path in script_dir_paths:
         for script_dir_path in script_dir_paths:
-           if not os.path.isdir(script_dir_path):
-               continue
-           for d_script in sorted(os.listdir(script_dir_path)):
-               d_script_path = os.path.join(script_dir_path, d_script)
-               if os.path.isfile(d_script_path) and \
-                       os.access(d_script_path, os.X_OK):
-                   subprocess.call([d_script_path])
+            if not os.path.isdir(script_dir_path):
+                continue
+            for d_script in sorted(os.listdir(script_dir_path)):
+                d_script_path = os.path.join(script_dir_path, d_script)
+                if os.path.isfile(d_script_path) and \
+                        os.access(d_script_path, os.X_OK):
+                    subprocess.call([d_script_path])
 
 
     def run_user_script(self):
     def run_user_script(self):
-        '''Run user script in /rw/config'''
+        """Run user script in /rw/config"""
         user_script_path = '/rw/config/qubes-firewall-user-script'
         user_script_path = '/rw/config/qubes-firewall-user-script'
         if os.path.isfile(user_script_path) and \
         if os.path.isfile(user_script_path) and \
                 os.access(user_script_path, os.X_OK):
                 os.access(user_script_path, os.X_OK):
             subprocess.call([user_script_path])
             subprocess.call([user_script_path])
 
 
     def read_rules(self, target):
     def read_rules(self, target):
-        '''Read rules from QubesDB and return them as a list of dicts'''
+        """Read rules from QubesDB and return them as a list of dicts"""
         entries = self.qdb.multiread('/qubes-firewall/{}/'.format(target))
         entries = self.qdb.multiread('/qubes-firewall/{}/'.format(target))
         assert isinstance(entries, dict)
         assert isinstance(entries, dict)
         # drop full path
         # drop full path
-        entries = dict(((k.split('/')[3], v) for k, v in entries.items()))
+        entries = dict(((k.split('/')[3], v.decode())
+                        for k, v in entries.items()))
         if 'policy' not in entries:
         if 'policy' not in entries:
             raise RuleParseError('No \'policy\' defined')
             raise RuleParseError('No \'policy\' defined')
         policy = entries.pop('policy')
         policy = entries.pop('policy')
@@ -196,7 +196,7 @@ class FirewallWorker(object):
 
 
 class IptablesWorker(FirewallWorker):
 class IptablesWorker(FirewallWorker):
     supported_rule_opts = ['action', 'proto', 'dst4', 'dst6', 'dsthost',
     supported_rule_opts = ['action', 'proto', 'dst4', 'dst6', 'dsthost',
-        'dstports', 'specialtarget', 'icmptype']
+                           'dstports', 'specialtarget', 'icmptype']
 
 
     def __init__(self):
     def __init__(self):
         super(IptablesWorker, self).__init__()
         super(IptablesWorker, self).__init__()
@@ -207,7 +207,7 @@ class IptablesWorker(FirewallWorker):
 
 
     @staticmethod
     @staticmethod
     def chain_for_addr(addr):
     def chain_for_addr(addr):
-        '''Generate iptables chain name for given source address address'''
+        """Generate iptables chain name for given source address address"""
         return 'qbs-' + addr.replace('.', '-').replace(':', '-')[-20:]
         return 'qbs-' + addr.replace('.', '-').replace(':', '-')[-20:]
 
 
     def run_ipt(self, family, args, **kwargs):
     def run_ipt(self, family, args, **kwargs):
@@ -221,17 +221,17 @@ class IptablesWorker(FirewallWorker):
         # pylint: disable=no-self-use
         # pylint: disable=no-self-use
         if family == 6:
         if family == 6:
             return subprocess.Popen(['ip6tables-restore'] + args,
             return subprocess.Popen(['ip6tables-restore'] + args,
-                stdin=subprocess.PIPE,
-                stdout=subprocess.PIPE,
-                stderr=subprocess.STDOUT)
+                                    stdin=subprocess.PIPE,
+                                    stdout=subprocess.PIPE,
+                                    stderr=subprocess.STDOUT)
         else:
         else:
             return subprocess.Popen(['iptables-restore'] + args,
             return subprocess.Popen(['iptables-restore'] + args,
-                stdin=subprocess.PIPE,
-                stdout=subprocess.PIPE,
-                stderr=subprocess.STDOUT)
+                                    stdin=subprocess.PIPE,
+                                    stdout=subprocess.PIPE,
+                                    stderr=subprocess.STDOUT)
 
 
     def create_chain(self, addr, chain, family):
     def create_chain(self, addr, chain, family):
-        '''
+        """
         Create iptables chain and hook traffic coming from `addr` to it.
         Create iptables chain and hook traffic coming from `addr` to it.
 
 
         :param addr: source IP from which traffic should be handled by the
         :param addr: source IP from which traffic should be handled by the
@@ -239,7 +239,7 @@ class IptablesWorker(FirewallWorker):
         :param chain: name of the chain to create
         :param chain: name of the chain to create
         :param family: address family (4 or 6)
         :param family: address family (4 or 6)
         :return: None
         :return: None
-        '''
+        """
 
 
         self.run_ipt(family, ['-N', chain])
         self.run_ipt(family, ['-N', chain])
         self.run_ipt(family,
         self.run_ipt(family,
@@ -247,7 +247,7 @@ class IptablesWorker(FirewallWorker):
         self.chains[family].add(chain)
         self.chains[family].add(chain)
 
 
     def prepare_rules(self, chain, rules, family):
     def prepare_rules(self, chain, rules, family):
-        '''
+        """
         Helper function to translate rules list into input for iptables-restore
         Helper function to translate rules list into input for iptables-restore
 
 
         :param chain: name of the chain to put rules into
         :param chain: name of the chain to put rules into
@@ -255,7 +255,7 @@ class IptablesWorker(FirewallWorker):
         :param family: address family (4 or 6)
         :param family: address family (4 or 6)
         :return: input for iptables-restore
         :return: input for iptables-restore
         :rtype: str
         :rtype: str
-        '''
+        """
 
 
         iptables = "*filter\n"
         iptables = "*filter\n"
 
 
@@ -359,7 +359,7 @@ class IptablesWorker(FirewallWorker):
         return iptables
         return iptables
 
 
     def apply_rules_family(self, source, rules, family):
     def apply_rules_family(self, source, rules, family):
-        '''
+        """
         Apply rules for given source address.
         Apply rules for given source address.
         Handle only rules for given address family (IPv4 or IPv6).
         Handle only rules for given address family (IPv4 or IPv6).
 
 
@@ -367,7 +367,7 @@ class IptablesWorker(FirewallWorker):
         :param rules: rules list
         :param rules: rules list
         :param family: address family, either 4 or 6
         :param family: address family, either 4 or 6
         :return: None
         :return: None
-        '''
+        """
 
 
         chain = self.chain_for_addr(source)
         chain = self.chain_for_addr(source)
         if chain not in self.chains[family]:
         if chain not in self.chains[family]:
@@ -377,7 +377,7 @@ class IptablesWorker(FirewallWorker):
         try:
         try:
             self.run_ipt(family, ['-F', chain])
             self.run_ipt(family, ['-F', chain])
             p = self.run_ipt_restore(family, ['-n'])
             p = self.run_ipt_restore(family, ['-n'])
-            (output, _) = p.communicate(iptables)
+            (output, _) = p.communicate(iptables.encode())
             if p.returncode != 0:
             if p.returncode != 0:
                 raise RuleApplyError(
                 raise RuleApplyError(
                     'iptables-restore failed: {}'.format(output))
                     'iptables-restore failed: {}'.format(output))
@@ -417,7 +417,7 @@ class IptablesWorker(FirewallWorker):
 
 
 class NftablesWorker(FirewallWorker):
 class NftablesWorker(FirewallWorker):
     supported_rule_opts = ['action', 'proto', 'dst4', 'dst6', 'dsthost',
     supported_rule_opts = ['action', 'proto', 'dst4', 'dst6', 'dsthost',
-        'dstports', 'specialtarget', 'icmptype']
+                           'dstports', 'specialtarget', 'icmptype']
 
 
     def __init__(self):
     def __init__(self):
         super(NftablesWorker, self).__init__()
         super(NftablesWorker, self).__init__()
@@ -428,21 +428,21 @@ class NftablesWorker(FirewallWorker):
 
 
     @staticmethod
     @staticmethod
     def chain_for_addr(addr):
     def chain_for_addr(addr):
-        '''Generate iptables chain name for given source address address'''
+        """Generate iptables chain name for given source address address"""
         return 'qbs-' + addr.replace('.', '-').replace(':', '-')
         return 'qbs-' + addr.replace('.', '-').replace(':', '-')
 
 
     def run_nft(self, nft_input):
     def run_nft(self, nft_input):
         # pylint: disable=no-self-use
         # pylint: disable=no-self-use
         p = subprocess.Popen(['nft', '-f', '/dev/stdin'],
         p = subprocess.Popen(['nft', '-f', '/dev/stdin'],
-            stdin=subprocess.PIPE,
-            stdout=subprocess.PIPE,
-            stderr=subprocess.STDOUT)
-        stdout, _ = p.communicate(nft_input)
+                             stdin=subprocess.PIPE,
+                             stdout=subprocess.PIPE,
+                             stderr=subprocess.STDOUT)
+        stdout, _ = p.communicate(nft_input.encode())
         if p.returncode != 0:
         if p.returncode != 0:
             raise RuleApplyError('nft failed: {}'.format(stdout))
             raise RuleApplyError('nft failed: {}'.format(stdout))
 
 
     def create_chain(self, addr, chain, family):
     def create_chain(self, addr, chain, family):
-        '''
+        """
         Create iptables chain and hook traffic coming from `addr` to it.
         Create iptables chain and hook traffic coming from `addr` to it.
 
 
         :param addr: source IP from which traffic should be handled by the
         :param addr: source IP from which traffic should be handled by the
@@ -450,7 +450,7 @@ class NftablesWorker(FirewallWorker):
         :param chain: name of the chain to create
         :param chain: name of the chain to create
         :param family: address family (4 or 6)
         :param family: address family (4 or 6)
         :return: None
         :return: None
-        '''
+        """
         nft_input = (
         nft_input = (
             'table {family} {table} {{\n'
             'table {family} {table} {{\n'
             '  chain {chain} {{\n'
             '  chain {chain} {{\n'
@@ -469,7 +469,7 @@ class NftablesWorker(FirewallWorker):
         self.chains[family].add(chain)
         self.chains[family].add(chain)
 
 
     def prepare_rules(self, chain, rules, family):
     def prepare_rules(self, chain, rules, family):
-        '''
+        """
         Helper function to translate rules list into input for iptables-restore
         Helper function to translate rules list into input for iptables-restore
 
 
         :param chain: name of the chain to put rules into
         :param chain: name of the chain to put rules into
@@ -477,7 +477,7 @@ class NftablesWorker(FirewallWorker):
         :param family: address family (4 or 6)
         :param family: address family (4 or 6)
         :return: input for iptables-restore
         :return: input for iptables-restore
         :rtype: str
         :rtype: str
-        '''
+        """
 
 
         assert family in (4, 6)
         assert family in (4, 6)
         nft_rules = []
         nft_rules = []
@@ -517,7 +517,6 @@ class NftablesWorker(FirewallWorker):
                         else rule['proto']
                         else rule['proto']
                     nft_rule += ' ip6 nexthdr {}'.format(proto)
                     nft_rule += ' ip6 nexthdr {}'.format(proto)
 
 
-
             if 'dst4' in rule:
             if 'dst4' in rule:
                 nft_rule += ' ip daddr {}'.format(rule['dst4'])
                 nft_rule += ' ip daddr {}'.format(rule['dst4'])
             elif 'dst6' in rule:
             elif 'dst6' in rule:
@@ -587,7 +586,7 @@ class NftablesWorker(FirewallWorker):
             ))
             ))
 
 
     def apply_rules_family(self, source, rules, family):
     def apply_rules_family(self, source, rules, family):
-        '''
+        """
         Apply rules for given source address.
         Apply rules for given source address.
         Handle only rules for given address family (IPv4 or IPv6).
         Handle only rules for given address family (IPv4 or IPv6).
 
 
@@ -595,7 +594,7 @@ class NftablesWorker(FirewallWorker):
         :param rules: rules list
         :param rules: rules list
         :param family: address family, either 4 or 6
         :param family: address family, either 4 or 6
         :return: None
         :return: None
-        '''
+        """
 
 
         chain = self.chain_for_addr(source)
         chain = self.chain_for_addr(source)
         if chain not in self.chains[family]:
         if chain not in self.chains[family]:
@@ -649,5 +648,6 @@ def main():
     with context:
     with context:
         worker.main()
         worker.main()
 
 
+
 if __name__ == '__main__':
 if __name__ == '__main__':
     main()
     main()

+ 9 - 9
qubesagent/test_firewall.py

@@ -14,7 +14,7 @@ class DummyIptablesRestore(object):
         self.returncode = 0
         self.returncode = 0
 
 
     def communicate(self, stdin=None):
     def communicate(self, stdin=None):
-        self._worker_mock.loaded_iptables[self._family] = stdin
+        self._worker_mock.loaded_iptables[self._family] = stdin.decode()
         return ("", None)
         return ("", None)
 
 
 class DummyQubesDB(object):
 class DummyQubesDB(object):
@@ -480,18 +480,18 @@ class TestFirewallWorker(TestCase):
         self.obj = FirewallWorker()
         self.obj = FirewallWorker()
         rules = {
         rules = {
             '10.137.0.1': {
             '10.137.0.1': {
-                'policy': 'accept',
-                '0000': 'proto=tcp dstports=80-80 action=drop',
-                '0001': 'proto=udp specialtarget=dns action=accept',
-                '0002': 'proto=udp action=drop',
+                'policy': b'accept',
+                '0000': b'proto=tcp dstports=80-80 action=drop',
+                '0001': b'proto=udp specialtarget=dns action=accept',
+                '0002': b'proto=udp action=drop',
             },
             },
-            '10.137.0.2': {'policy': 'accept'},
+            '10.137.0.2': {'policy': b'accept'},
             # no policy
             # no policy
-            '10.137.0.3': {'0000': 'proto=tcp action=accept'},
+            '10.137.0.3': {'0000': b'proto=tcp action=accept'},
             # no action
             # no action
             '10.137.0.4': {
             '10.137.0.4': {
-                'policy': 'drop',
-                '0000': 'proto=tcp'
+                'policy': b'drop',
+                '0000': b'proto=tcp'
             },
             },
         }
         }
         for addr, entries in rules.items():
         for addr, entries in rules.items():

+ 14 - 19
rpm_spec/core-agent.spec.in

@@ -124,12 +124,12 @@ Requires:   hostname
 Requires:   xterm
 Requires:   xterm
 # for qubes-desktop-run
 # for qubes-desktop-run
 Requires:   pygobject3-base
 Requires:   pygobject3-base
-Requires:   dbus-python
+Requires:   python3-dbus
 # for qubes-session-autostart, xdg-icon
 # for qubes-session-autostart, xdg-icon
-Requires:   pyxdg
-Requires:   python-daemon
+Requires:   python3-pyxdg
+Requires:   python3-daemon
 # for qvm-feature-request
 # for qvm-feature-request
-Requires:   python2-qubesdb
+Requires:   python3-qubesdb
 Requires:   ImageMagick
 Requires:   ImageMagick
 Requires:   librsvg2-tools
 Requires:   librsvg2-tools
 Requires:   zenity
 Requires:   zenity
@@ -137,11 +137,8 @@ Requires:   dconf
 Requires:   qubes-core-qrexec-vm
 Requires:   qubes-core-qrexec-vm
 Requires:   qubes-libvchan
 Requires:   qubes-libvchan
 Requires:   qubes-db-vm
 Requires:   qubes-db-vm
-%if 0%{?fedora} >= 23
 Requires:   python%{python3_pkgversion}-dnf-plugins-qubes-hooks
 Requires:   python%{python3_pkgversion}-dnf-plugins-qubes-hooks
-%else
-Requires:   python2-dnf-plugins-qubes-hooks
-%endif
+Requires: python%{python3_pkgversion}-setuptools
 Obsoletes:  qubes-core-vm-kernel-placeholder <= 1.0
 Obsoletes:  qubes-core-vm-kernel-placeholder <= 1.0
 Obsoletes:  qubes-upgrade-vm < 3.2
 Obsoletes:  qubes-upgrade-vm < 3.2
 Provides:   qubes-core-vm = %{version}-%{release}
 Provides:   qubes-core-vm = %{version}-%{release}
@@ -156,9 +153,7 @@ BuildRequires: libX11-devel
 BuildRequires: qubes-utils-devel >= 3.1.3
 BuildRequires: qubes-utils-devel >= 3.1.3
 BuildRequires: qubes-libvchan-@BACKEND_VMM@-devel
 BuildRequires: qubes-libvchan-@BACKEND_VMM@-devel
 BuildRequires: pam-devel
 BuildRequires: pam-devel
-%if 0%{?rhel} >= 7
-BuildRequires: python-setuptools
-%endif
+BuildRequires: python%{python3_pkgversion}-setuptools
 BuildRequires: systemd
 BuildRequires: systemd
 Source0: %{name}-%{version}.tar.gz
 Source0: %{name}-%{version}.tar.gz
 
 
@@ -651,7 +646,6 @@ rm -f %{name}-%{version}
 /usr/lib/qubes/init/resize-rootfs-if-needed.sh
 /usr/lib/qubes/init/resize-rootfs-if-needed.sh
 /usr/lib/qubes/init/setup-rw.sh
 /usr/lib/qubes/init/setup-rw.sh
 /usr/lib/qubes/init/setup-rwdev.sh
 /usr/lib/qubes/init/setup-rwdev.sh
-/usr/lib/qubes/init/functions
 %dir /usr/lib/qubes-bind-dirs.d
 %dir /usr/lib/qubes-bind-dirs.d
 /usr/lib/qubes-bind-dirs.d/30_cron.conf
 /usr/lib/qubes-bind-dirs.d/30_cron.conf
 /usr/share/applications/qubes-run-terminal.desktop
 /usr/share/applications/qubes-run-terminal.desktop
@@ -663,13 +657,14 @@ rm -f %{name}-%{version}
 /usr/share/glib-2.0/schemas/20_org.gnome.desktop.wm.preferences.qubes.gschema.override
 /usr/share/glib-2.0/schemas/20_org.gnome.desktop.wm.preferences.qubes.gschema.override
 %{_mandir}/man1/qvm-*.1*
 %{_mandir}/man1/qvm-*.1*
 
 
-%dir %{python2_sitelib}/qubesagent-*-py2.7.egg-info
-%{python2_sitelib}/qubesagent-*-py2.7.egg-info/*
-%dir %{python2_sitelib}/qubesagent
-%{python2_sitelib}/qubesagent/__init__.py*
-%{python2_sitelib}/qubesagent/firewall.py*
-%{python2_sitelib}/qubesagent/test_firewall.py*
-%{python2_sitelib}/qubesagent/xdg.py*
+%dir %{python3_sitelib}/qubesagent-*-py*.egg-info
+%{python3_sitelib}/qubesagent-*-py*.egg-info/*
+%{python3_sitelib}/qubesagent/__pycache__
+%dir %{python3_sitelib}/qubesagent
+%{python3_sitelib}/qubesagent/__init__.py*
+%{python3_sitelib}/qubesagent/firewall.py*
+%{python3_sitelib}/qubesagent/test_firewall.py*
+%{python3_sitelib}/qubesagent/xdg.py*
 
 
 /usr/share/qubes/mime-override/globs
 /usr/share/qubes/mime-override/globs
 /usr/share/qubes/qubes-master-key.asc
 /usr/share/qubes/qubes-master-key.asc