Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 23 Jan 2020 11:12:28 +0000 (UTC)
From:      Michael Gmelin <grembo@FreeBSD.org>
To:        ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org
Subject:   svn commit: r523920 - in head/sysutils/iocage: . files
Message-ID:  <202001231112.00NBCS51087954@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: grembo
Date: Thu Jan 23 11:12:28 2020
New Revision: 523920
URL: https://svnweb.freebsd.org/changeset/ports/523920

Log:
  Fix accidental removal of devfs_rulesets on jail stop
  
  Pulls in a bugfix[0] that has been merged upstream[1].
  
  This bug caused manually configured devfs_rulesets to get deleted on jail
  stop, causing jails to come up with a default devfs rules on next start,
  which can be a nuisance or even dangerous, depending on the specific setup.
  
  Also adds a minimum devfs_ruleset id for dynamically created devfs rulesets
  and fixes a devfs_ruleset resource leak when using plugins.
  
  Take maintainership, as suggested by araujo@ (thanks for taking care of that
  port for so long!).
  
  [0]https://github.com/iocage/iocage/pull/1106
  [1]https://github.com/iocage/iocage/commit/753b2f35731423597d7f51f33427b6d619fcd0b5
  
  PR:		243510
  Approved by:	araujo (maintainer)
  MFH:		2020Q1

Added:
  head/sysutils/iocage/files/patch-iocage__lib_ioc__common.py   (contents, props changed)
  head/sysutils/iocage/files/patch-iocage__lib_ioc__json.py   (contents, props changed)
  head/sysutils/iocage/files/patch-iocage__lib_ioc__start.py   (contents, props changed)
Modified:
  head/sysutils/iocage/Makefile

Modified: head/sysutils/iocage/Makefile
==============================================================================
--- head/sysutils/iocage/Makefile	Thu Jan 23 11:01:25 2020	(r523919)
+++ head/sysutils/iocage/Makefile	Thu Jan 23 11:12:28 2020	(r523920)
@@ -2,11 +2,11 @@
 
 PORTNAME=	iocage
 PORTVERSION=	1.2
-PORTREVISION=	3
+PORTREVISION=	4
 CATEGORIES=	sysutils python
 PKGNAMEPREFIX=	${PYTHON_PKGNAMEPREFIX}
 
-MAINTAINER=	araujo@FreeBSD.org
+MAINTAINER=	grembo@FreeBSD.org
 COMMENT=	FreeBSD jail manager written in Python3
 
 LICENSE=	BSD2CLAUSE

Added: head/sysutils/iocage/files/patch-iocage__lib_ioc__common.py
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sysutils/iocage/files/patch-iocage__lib_ioc__common.py	Thu Jan 23 11:12:28 2020	(r523920)
@@ -0,0 +1,73 @@
+Originates here
+https://github.com/iocage/iocage/commit/753b2f35731423597d7f51f33427b6d619fcd0b5
+https://github.com/iocage/iocage/pull/1106
+and most likely can be removed on the next release of iocage.
+--- iocage_lib/ioc_common.py.orig	2019-09-26 07:23:24 UTC
++++ iocage_lib/ioc_common.py
+@@ -44,6 +44,9 @@ import iocage_lib.ioc_exceptions
+ import iocage_lib.ioc_exec
+ 
+ INTERACTIVE = False
++# 4 is a magic number for default and doesn't refer
++# to the actual ruleset 4 in devfs.rules(!)
++IOCAGE_DEVFS_RULESET = 4
+ 
+ 
+ def callback(_log, callback_exception):
+@@ -737,7 +740,7 @@ def generate_devfs_ruleset(conf, paths=N
+     Will add a per jail devfs ruleset with the specified rules,
+     specifying defaults that equal devfs_ruleset 4
+     """
+-    ruleset = conf['devfs_ruleset']
++    configured_ruleset = conf['devfs_ruleset']
+     devfs_includes = []
+     devfs_rulesets = su.run(
+         ['devfs', 'rule', 'showsets'],
+@@ -745,22 +748,26 @@ def generate_devfs_ruleset(conf, paths=N
+     )
+     ruleset_list = [int(i) for i in devfs_rulesets.stdout.splitlines()]
+ 
+-    if ruleset != '4':
+-        if int(ruleset) in ruleset_list:
+-            return str(ruleset)
+-
+-        logit({
+-            "level": "INFO",
+-            "message": f'* Ruleset {ruleset} does not exist, using defaults'
+-        },
+-            _callback=callback,
+-            silent=silent)
+-
+-    ruleset = 5  # 0-4 is always reserved
++    ruleset = int(conf["min_dyn_devfs_ruleset"])
+     while ruleset in ruleset_list:
+         ruleset += 1
+     ruleset = str(ruleset)
+ 
++    # Custom devfs_ruleset configured, clone to dynamic ruleset
++    if int(configured_ruleset) != IOCAGE_DEVFS_RULESET:
++        if int(configured_ruleset) not in ruleset_list:
++            return (True, configured_ruleset, '0')
++        rules = su.run(
++            ['devfs', 'rule', '-s', configured_ruleset, 'show'],
++            stdout=su.PIPE, universal_newlines=True
++        )
++        for rule in rules.stdout.splitlines():
++            su.run(['devfs', 'rule', '-s', ruleset, 'add'] +
++                   rule.split(' ')[1:], stdout=su.PIPE)
++
++        return (True, configured_ruleset, ruleset)
++
++    # Create default ruleset
+     devfs_dict = dict((dev, None) for dev in (
+         'hide', 'null', 'zero', 'crypto', 'random', 'urandom', 'ptyp*',
+         'ptyq*', 'ptyr*', 'ptys*', 'ptyP*', 'ptyQ*', 'ptyR*', 'ptyS*', 'ptyl*',
+@@ -812,7 +819,7 @@ def generate_devfs_ruleset(conf, paths=N
+ 
+         su.run(['devfs', 'rule', '-s', ruleset] + path, stdout=su.PIPE)
+ 
+-    return ruleset
++    return (False, configured_ruleset, ruleset)
+ 
+ 
+ def runscript(script):

Added: head/sysutils/iocage/files/patch-iocage__lib_ioc__json.py
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sysutils/iocage/files/patch-iocage__lib_ioc__json.py	Thu Jan 23 11:12:28 2020	(r523920)
@@ -0,0 +1,74 @@
+Originates here
+https://github.com/iocage/iocage/commit/753b2f35731423597d7f51f33427b6d619fcd0b5
+https://github.com/iocage/iocage/pull/1106
+and most likely can be removed on the next release of iocage.
+--- iocage_lib/ioc_json.py.orig	2019-09-26 07:23:24 UTC
++++ iocage_lib/ioc_json.py
+@@ -671,7 +671,7 @@ class IOCConfiguration(IOCZFS):
+     @staticmethod
+     def get_version():
+         """Sets the iocage configuration version."""
+-        version = '26'
++        version = '27'
+ 
+         return version
+ 
+@@ -1104,6 +1104,10 @@ class IOCConfiguration(IOCZFS):
+             if conf.get(option) == 'none':
+                 conf[option] = 'auto'
+ 
++        # Version 27 key
++        if not conf.get('min_dyn_devfs_ruleset'):
++            conf['min_dyn_devfs_ruleset'] = '1000'
++
+         if not default:
+             conf.update(jail_conf)
+ 
+@@ -1321,7 +1325,7 @@ class IOCConfiguration(IOCZFS):
+             'vnet2_mac': 'none',
+             'vnet3_mac': 'none',
+             'vnet_default_interface': 'auto',
+-            'devfs_ruleset': '4',
++            'devfs_ruleset': str(iocage_lib.ioc_common.IOCAGE_DEVFS_RULESET),
+             'exec_start': '/bin/sh /etc/rc',
+             'exec_stop': '/bin/sh /etc/rc.shutdown',
+             'exec_prestart': '/usr/bin/true',
+@@ -1432,6 +1436,7 @@ class IOCConfiguration(IOCZFS):
+             'nat_forwards': 'none',
+             'plugin_name': 'none',
+             'plugin_repository': 'none',
++            'min_dyn_devfs_ruleset': '1000',
+         }
+ 
+     def check_default_config(self):
+@@ -2369,6 +2374,7 @@ class IOCJson(IOCConfiguration):
+             'nat_forwards': ('string', ),
+             'plugin_name': ('string', ),
+             'plugin_repository': ('string', ),
++            'min_dyn_devfs_ruleset': ('string', ),
+         }
+ 
+         zfs_props = {
+@@ -2648,6 +2654,22 @@ class IOCJson(IOCConfiguration):
+                                 silent=self.silent,
+                                 exception=ioc_exceptions.ValidationFailed
+                             )
++                elif key in ('devfs_ruleset', 'min_dyn_devfs_ruleset'):
++                    try:
++                        intval = int(value)
++                        if intval <= 0:
++                            raise ValueError()
++                        conf[key] = str(intval)
++                    except ValueError:
++                        iocage_lib.ioc_common.logit(
++                            {
++                                'level': 'EXCEPTION',
++                                'message': f'Invalid {key} value: {value}'
++                            },
++                            _callback=self.callback,
++                            silent=self.silent,
++                            exception=ioc_exceptions.ValidationFailed
++                        )
+ 
+                 return value, conf
+             else:

Added: head/sysutils/iocage/files/patch-iocage__lib_ioc__start.py
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sysutils/iocage/files/patch-iocage__lib_ioc__start.py	Thu Jan 23 11:12:28 2020	(r523920)
@@ -0,0 +1,104 @@
+Originates here
+https://github.com/iocage/iocage/commit/753b2f35731423597d7f51f33427b6d619fcd0b5
+https://github.com/iocage/iocage/pull/1106
+and most likely can be removed on the next release of iocage.
+--- iocage_lib/ioc_start.py.orig	2019-09-26 07:23:24 UTC
++++ iocage_lib/ioc_start.py
+@@ -145,7 +145,6 @@ class IOCStart(object):
+         allow_quotas = self.conf["allow_quotas"]
+         allow_socket_af = self.conf["allow_socket_af"]
+         allow_vmm = self.conf["allow_vmm"]
+-        devfs_ruleset = iocage_lib.ioc_common.generate_devfs_ruleset(self.conf)
+         exec_prestart = self.conf["exec_prestart"]
+         exec_poststart = self.conf["exec_poststart"]
+         exec_clean = self.conf["exec_clean"]
+@@ -486,16 +485,8 @@ class IOCStart(object):
+             _callback=self.callback,
+             silent=self.silent)
+ 
+-        if wants_dhcp and self.conf['type'] != 'pluginv2' \
+-                and self.conf['devfs_ruleset'] != '4':
+-            iocage_lib.ioc_common.logit({
+-                "level": "WARNING",
+-                "message": f"  {self.uuid} is not using the devfs_ruleset"
+-                           f" of 4, not generating a ruleset for the jail,"
+-                           " DHCP may not work."
+-            },
+-                _callback=self.callback,
+-                silent=self.silent)
++        devfs_paths = None
++        devfs_includes = None
+ 
+         if self.conf['type'] == 'pluginv2' and os.path.isfile(
+             os.path.join(self.path, f'{self.conf["plugin_name"]}.json')
+@@ -509,17 +500,51 @@ class IOCStart(object):
+                     plugin_name = self.conf['plugin_name']
+                     plugin_devfs = devfs_json[
+                         "devfs_ruleset"][f"plugin_{plugin_name}"]
+-                    plugin_devfs_paths = plugin_devfs['paths']
+-
+-                    plugin_devfs_includes = None if 'includes' not in \
++                    devfs_paths = plugin_devfs['paths']
++                    devfs_includes = None if 'includes' not in \
+                         plugin_devfs else plugin_devfs['includes']
+ 
+-                    devfs_ruleset = \
+-                        iocage_lib.ioc_common.generate_devfs_ruleset(
+-                            self.conf,
+-                            paths=plugin_devfs_paths,
+-                            includes=plugin_devfs_includes
+-                        )
++        # Generate dynamic devfs ruleset from configured one
++        (manual_devfs_config, configured_devfs_ruleset, devfs_ruleset) \
++            = iocage_lib.ioc_common.generate_devfs_ruleset(
++                self.conf, devfs_paths, devfs_includes)
++
++        if int(devfs_ruleset) <= 0:
++            iocage_lib.ioc_common.logit({
++                "level": "ERROR",
++                "message": f"{self.uuid} devfs_ruleset"
++                           f" {configured_devfs_ruleset} does not exist!"
++                           " - Not starting jail"
++            },
++                _callback=self.callback,
++                silent=self.silent)
++            return
++
++        # Manually configured devfs_ruleset doesn't support all iocage features
++        if manual_devfs_config:
++            if devfs_paths is not None or devfs_includes is not None:
++                iocage_lib.ioc_common.logit({
++                    "level": "WARNING",
++                    "message": f"  {self.uuid} is not using the devfs_ruleset"
++                               " of "
++                               f"{iocage_lib.ioc_common.IOCAGE_DEVFS_RULESET}"
++                               ", devices and includes from plugin not added"
++                               ", some features of the plugin may not work."
++                },
++                    _callback=self.callback,
++                    silent=self.silent)
++
++            if wants_dhcp and self.conf['type'] != 'pluginv2':
++                iocage_lib.ioc_common.logit({
++                    "level": "WARNING",
++                    "message": f"  {self.uuid} is not using the devfs_ruleset"
++                               " of "
++                               f"{iocage_lib.ioc_common.IOCAGE_DEVFS_RULESET}"
++                               ", not generating a ruleset for the jail,"
++                               " DHCP may not work."
++                },
++                    _callback=self.callback,
++                    silent=self.silent)
+ 
+         parameters = [
+             fdescfs, _allow_mlock, tmpfs,
+@@ -619,6 +644,9 @@ class IOCStart(object):
+         iocage_lib.ioc_common.logit({
+             'level': 'INFO',
+             'message': f'  + Using devfs_ruleset: {devfs_ruleset}'
++                       + (' (cloned from devfs_ruleset '
++                          f'{configured_devfs_ruleset})' if manual_devfs_config
++                          else ' (iocage generated default)')
+         },
+             _callback=self.callback,
+             silent=self.silent)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202001231112.00NBCS51087954>