From: Richard Purdie <richard.purdie@linuxfoundation.org>
To: Ross Burton <ross.burton@intel.com>
Cc: openembedded-devel@lists.openembedded.org,
openembedded-core@lists.openembedded.org
Subject: Re: [PATCH 1/5] systemd.bbclass: helper class for recipes with systemd units
Date: Mon, 11 Feb 2013 14:43:12 +0000 [thread overview]
Message-ID: <1360593792.6793.74.camel@ted> (raw)
In-Reply-To: <a32b33801c899dce34b072ad1d9d9ede30e8b598.1360360346.git.ross.burton@intel.com>
On Fri, 2013-02-08 at 22:43 +0000, Ross Burton wrote:
> This class adds postinst/prerm scripts to start/stop/enable/disable the services
> as relevant, and some magic to ensure the service files are installed.
>
> Based on (but not the same as) the systemd.bbclass in meta-systemd, so thanks to
> the following for their work there:
>
> Enrico Scholz <enrico.scholz@sigma-chemnitz.de>
> Khem Raj <raj.khem@gmail.com>
> Martin Jansa <Martin.Jansa@gmail.com>
> Andreas Müller <schnitzeltony@googlemail.com>
> Koen Kooi <koen@dominion.thruhere.net>
>
> Signed-off-by: Ross Burton <ross.burton@intel.com>
> ---
> meta/classes/systemd.bbclass | 158 ++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 158 insertions(+)
> create mode 100644 meta/classes/systemd.bbclass
>
> diff --git a/meta/classes/systemd.bbclass b/meta/classes/systemd.bbclass
> new file mode 100644
> index 0000000..e0ea65c
> --- /dev/null
> +++ b/meta/classes/systemd.bbclass
> @@ -0,0 +1,158 @@
> +# The list of packages that should have systemd packaging scripts added. For
> +# each entry, optionally have a SYSTEMD_SERVICE_[package] that lists the service
> +# files in this package. If this variable isn't set, [package].service is used.
> +SYSTEMD_PACKAGES ?= "${PN}"
> +
> +# Whether to enable or disable the services on installation.
> +SYSTEMD_AUTO_ENABLE ??= "enable"
> +
> +# This class will be included in any recipe that supports systemd init scripts,
> +# even if the systemd DISTRO_FEATURE isn't enabled. As such don't make any
> +# changes directly but check the DISTRO_FEATURES first.
> +python __anonymous() {
> + if oe.utils.contains ('DISTRO_FEATURES', 'systemd', True, False, d):
> + d.appendVar("DEPENDS", " systemd-systemctl-native")
> + # Set a variable so that update-rcd.bbclass knows we're active and can
> + # disable itself.
> + d.setVar("SYSTEMD_BBCLASS_ENABLED", "1")
> +}
> +systemd_postinst() {
> +OPTS=""
> +
> +if [ -n "$D" ]; then
> + OPTS="--root=$D"
> +fi
> +
> +systemctl $OPTS ${SYSTEMD_AUTO_ENABLE} ${SYSTEMD_SERVICE}
> +
> +if [ -z "$D" -a "${SYSTEMD_AUTO_ENABLE}" = "enable" ]; then
> + systemctl start ${SYSTEMD_SERVICE}
> +fi
> +}
> +
> +systemd_prerm() {
> +if [ -z "$D" ]; then
> + systemctl stop ${SYSTEMD_SERVICE}
> +fi
> +
> +systemctl disable ${SYSTEMD_SERVICE}
> +}
> +
> +def systemd_populate_packages(d):
> + def get_package_var(d, var, pkg):
> + val = (d.getVar('%s_%s' % (var, pkg), True) or "").strip()
> + if val == "":
> + val = (d.getVar(var, True) or "").strip()
> + return val
> +
> +
> + # Add a runtime dependency on systemd to pkg
> + def systemd_add_rdepends(pkg):
> + rdepends = d.getVar('RDEPENDS_' + pkg, True) or ""
> + if not 'systemd' in rdepends.split():
> + rdepends = '%s %s' % (rdepends, 'systemd')
> + d.setVar('RDEPENDS_' + pkg, rdepends)
> +
> +
> + def systemd_generate_package_scripts(pkg):
> + bb.debug(1, 'adding systemd calls to postinst/postrm for %s' % pkg)
> +
> + # Add pkg to the overrides so that it finds the SYSTEMD_SERVICE_pkg
> + # variable.
> + localdata = d.createCopy()
> + localdata.prependVar("OVERRIDES", pkg + ":")
> + bb.data.update_data(localdata)
> +
> + postinst = d.getVar('pkg_postinst_%s' % pkg, True)
> + if not postinst:
> + postinst = '#!/bin/sh\n'
> + postinst += localdata.getVar('systemd_postinst', True)
> + d.setVar('pkg_postinst_%s' % pkg, postinst)
> +
> + prerm = d.getVar('pkg_prerm_%s' % pkg, True)
> + if not prerm:
> + prerm = '#!/bin/sh\n'
> + prerm += localdata.getVar('systemd_prerm', True)
> + d.setVar('pkg_prerm_%s' % pkg, prerm)
> +
> +
> + # Add files to FILES_*-systemd if existent and not already done
> + def systemd_append_file(pkg_systemd, file_append):
> + appended = False
> + if os.path.exists(oe.path.join(d.getVar("D", True), file_append)):
> + var_name = "FILES_" + pkg_systemd
> + files = d.getVar(var_name, False) or ""
> + if file_append not in files.split():
> + d.appendVar(var_name, " " + file_append)
> + appended = True
> + return appended
> +
> + # Add systemd files to FILES_*-systemd, parse for Also= and follow recursive
> + def systemd_add_files_and_parse(pkg_systemd, path, service, keys):
> + # avoid infinite recursion
> + if systemd_append_file(pkg_systemd, oe.path.join(path, service)):
> + fullpath = oe.path.join(d.getVar("D", True), path, service)
> + if service.find('.service') != -1:
> + # for *.service add *@.service
> + service_base = service.replace('.service', '')
> + systemd_add_files_and_parse(pkg_systemd, path, service_base + '@.service', keys)
> + if service.find('.socket') != -1:
> + # for *.socket add *.service and *@.service
> + service_base = service.replace('.socket', '')
> + systemd_add_files_and_parse(pkg_systemd, path, service_base + '.service', keys)
> + systemd_add_files_and_parse(pkg_systemd, path, service_base + '@.service', keys)
> + for key in keys.split():
> + # recurse all dependencies found in keys ('Also';'Conflicts';..) and add to files
> + cmd = "grep %s %s | sed 's,%s=,,g' | tr ',' '\\n'" % (key, fullpath, key)
> + pipe = os.popen(cmd, 'r')
> + line = pipe.readline()
> + while line:
> + line = line.replace('\n', '')
> + systemd_add_files_and_parse(pkg_systemd, path, line, keys)
> + line = pipe.readline()
> + pipe.close()
> +
> + # Check service-files and call systemd_add_files_and_parse for each entry
> + def systemd_check_services():
> + base_libdir = d.getVar('base_libdir', True)
> + searchpaths = [oe.path.join(d.getVar("sysconfdir", True), "systemd", "system"),]
> + searchpaths.append(oe.path.join(d.getVar("base_libdir", True), "systemd", "system"))
> + searchpaths.append(oe.path.join(d.getVar("libdir", True), "systemd", "system"))
> + searchpaths.append(oe.path.join(d.getVar("libdir", True), "systemd", "user"))
> + systemd_packages = d.getVar('SYSTEMD_PACKAGES', True)
> + has_exactly_one_service = len(systemd_packages.split()) == 1
> + if has_exactly_one_service:
> + has_exactly_one_service = len(get_package_var(d, 'SYSTEMD_SERVICE', systemd_packages).split()) == 1
> +
> + keys = 'Also' # Conflicts??
> + if has_exactly_one_service:
> + # single service gets also the /dev/null dummies
> + keys = 'Also Conflicts'
> + # scan for all in SYSTEMD_SERVICE[]
> + for pkg_systemd in systemd_packages.split():
> + for service in get_package_var(d, 'SYSTEMD_SERVICE', pkg_systemd).split():
> + path_found = ''
> + for path in searchpaths:
> + if os.path.exists(oe.path.join(d.getVar("D", True), path, service)):
> + path_found = path
> + break
> + if path_found != '':
> + systemd_add_files_and_parse(pkg_systemd, path_found, service, keys)
> + else:
> + raise bb.build.FuncFailed, "\n\nSYSTEMD_SERVICE_%s value %s does not exist" % \
> + (pkg_systemd, service)
> +
> + # Run all modifications once when creating package
> + if os.path.exists(d.getVar("D", True)):
> + for pkg in d.getVar('SYSTEMD_PACKAGES', True).split():
> + if d.getVar('SYSTEMD_SERVICE_' + pkg, True):
> + systemd_generate_package_scripts(pkg)
> + systemd_add_rdepends(pkg)
> + systemd_check_services()
> +
> +
> +python populate_packages_prepend () {
> + if oe.utils.contains ('DISTRO_FEATURES', 'systemd', True, False, d):
> + systemd_populate_packages (d)
> +}
I know this has been a long time in the works so I'll merge but could
you follow up with a change:
PACKAGESPLITFUNCS_prepend = "systemd_populate_packages "
and just put the
oe.utils.contains ('DISTRO_FEATURES', 'systemd', True, False, d) into
systemd_populate_packages with a return? You'll need to drop the d as a
parameter and turn it into a python xxxx() { style function. The nice
thing is this then shows up nicely on the profiles too. I'm aiming to
stamp out use of populate_packages_prepend entirely.
Cheers,
Richard
WARNING: multiple messages have this Message-ID (diff)
From: Richard Purdie <richard.purdie@linuxfoundation.org>
To: Ross Burton <ross.burton@intel.com>
Cc: openembedded-devel@lists.openembedded.org,
openembedded-core@lists.openembedded.org
Subject: Re: [OE-core] [PATCH 1/5] systemd.bbclass: helper class for recipes with systemd units
Date: Mon, 11 Feb 2013 14:43:12 +0000 [thread overview]
Message-ID: <1360593792.6793.74.camel@ted> (raw)
In-Reply-To: <a32b33801c899dce34b072ad1d9d9ede30e8b598.1360360346.git.ross.burton@intel.com>
On Fri, 2013-02-08 at 22:43 +0000, Ross Burton wrote:
> This class adds postinst/prerm scripts to start/stop/enable/disable the services
> as relevant, and some magic to ensure the service files are installed.
>
> Based on (but not the same as) the systemd.bbclass in meta-systemd, so thanks to
> the following for their work there:
>
> Enrico Scholz <enrico.scholz@sigma-chemnitz.de>
> Khem Raj <raj.khem@gmail.com>
> Martin Jansa <Martin.Jansa@gmail.com>
> Andreas Müller <schnitzeltony@googlemail.com>
> Koen Kooi <koen@dominion.thruhere.net>
>
> Signed-off-by: Ross Burton <ross.burton@intel.com>
> ---
> meta/classes/systemd.bbclass | 158 ++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 158 insertions(+)
> create mode 100644 meta/classes/systemd.bbclass
>
> diff --git a/meta/classes/systemd.bbclass b/meta/classes/systemd.bbclass
> new file mode 100644
> index 0000000..e0ea65c
> --- /dev/null
> +++ b/meta/classes/systemd.bbclass
> @@ -0,0 +1,158 @@
> +# The list of packages that should have systemd packaging scripts added. For
> +# each entry, optionally have a SYSTEMD_SERVICE_[package] that lists the service
> +# files in this package. If this variable isn't set, [package].service is used.
> +SYSTEMD_PACKAGES ?= "${PN}"
> +
> +# Whether to enable or disable the services on installation.
> +SYSTEMD_AUTO_ENABLE ??= "enable"
> +
> +# This class will be included in any recipe that supports systemd init scripts,
> +# even if the systemd DISTRO_FEATURE isn't enabled. As such don't make any
> +# changes directly but check the DISTRO_FEATURES first.
> +python __anonymous() {
> + if oe.utils.contains ('DISTRO_FEATURES', 'systemd', True, False, d):
> + d.appendVar("DEPENDS", " systemd-systemctl-native")
> + # Set a variable so that update-rcd.bbclass knows we're active and can
> + # disable itself.
> + d.setVar("SYSTEMD_BBCLASS_ENABLED", "1")
> +}
> +systemd_postinst() {
> +OPTS=""
> +
> +if [ -n "$D" ]; then
> + OPTS="--root=$D"
> +fi
> +
> +systemctl $OPTS ${SYSTEMD_AUTO_ENABLE} ${SYSTEMD_SERVICE}
> +
> +if [ -z "$D" -a "${SYSTEMD_AUTO_ENABLE}" = "enable" ]; then
> + systemctl start ${SYSTEMD_SERVICE}
> +fi
> +}
> +
> +systemd_prerm() {
> +if [ -z "$D" ]; then
> + systemctl stop ${SYSTEMD_SERVICE}
> +fi
> +
> +systemctl disable ${SYSTEMD_SERVICE}
> +}
> +
> +def systemd_populate_packages(d):
> + def get_package_var(d, var, pkg):
> + val = (d.getVar('%s_%s' % (var, pkg), True) or "").strip()
> + if val == "":
> + val = (d.getVar(var, True) or "").strip()
> + return val
> +
> +
> + # Add a runtime dependency on systemd to pkg
> + def systemd_add_rdepends(pkg):
> + rdepends = d.getVar('RDEPENDS_' + pkg, True) or ""
> + if not 'systemd' in rdepends.split():
> + rdepends = '%s %s' % (rdepends, 'systemd')
> + d.setVar('RDEPENDS_' + pkg, rdepends)
> +
> +
> + def systemd_generate_package_scripts(pkg):
> + bb.debug(1, 'adding systemd calls to postinst/postrm for %s' % pkg)
> +
> + # Add pkg to the overrides so that it finds the SYSTEMD_SERVICE_pkg
> + # variable.
> + localdata = d.createCopy()
> + localdata.prependVar("OVERRIDES", pkg + ":")
> + bb.data.update_data(localdata)
> +
> + postinst = d.getVar('pkg_postinst_%s' % pkg, True)
> + if not postinst:
> + postinst = '#!/bin/sh\n'
> + postinst += localdata.getVar('systemd_postinst', True)
> + d.setVar('pkg_postinst_%s' % pkg, postinst)
> +
> + prerm = d.getVar('pkg_prerm_%s' % pkg, True)
> + if not prerm:
> + prerm = '#!/bin/sh\n'
> + prerm += localdata.getVar('systemd_prerm', True)
> + d.setVar('pkg_prerm_%s' % pkg, prerm)
> +
> +
> + # Add files to FILES_*-systemd if existent and not already done
> + def systemd_append_file(pkg_systemd, file_append):
> + appended = False
> + if os.path.exists(oe.path.join(d.getVar("D", True), file_append)):
> + var_name = "FILES_" + pkg_systemd
> + files = d.getVar(var_name, False) or ""
> + if file_append not in files.split():
> + d.appendVar(var_name, " " + file_append)
> + appended = True
> + return appended
> +
> + # Add systemd files to FILES_*-systemd, parse for Also= and follow recursive
> + def systemd_add_files_and_parse(pkg_systemd, path, service, keys):
> + # avoid infinite recursion
> + if systemd_append_file(pkg_systemd, oe.path.join(path, service)):
> + fullpath = oe.path.join(d.getVar("D", True), path, service)
> + if service.find('.service') != -1:
> + # for *.service add *@.service
> + service_base = service.replace('.service', '')
> + systemd_add_files_and_parse(pkg_systemd, path, service_base + '@.service', keys)
> + if service.find('.socket') != -1:
> + # for *.socket add *.service and *@.service
> + service_base = service.replace('.socket', '')
> + systemd_add_files_and_parse(pkg_systemd, path, service_base + '.service', keys)
> + systemd_add_files_and_parse(pkg_systemd, path, service_base + '@.service', keys)
> + for key in keys.split():
> + # recurse all dependencies found in keys ('Also';'Conflicts';..) and add to files
> + cmd = "grep %s %s | sed 's,%s=,,g' | tr ',' '\\n'" % (key, fullpath, key)
> + pipe = os.popen(cmd, 'r')
> + line = pipe.readline()
> + while line:
> + line = line.replace('\n', '')
> + systemd_add_files_and_parse(pkg_systemd, path, line, keys)
> + line = pipe.readline()
> + pipe.close()
> +
> + # Check service-files and call systemd_add_files_and_parse for each entry
> + def systemd_check_services():
> + base_libdir = d.getVar('base_libdir', True)
> + searchpaths = [oe.path.join(d.getVar("sysconfdir", True), "systemd", "system"),]
> + searchpaths.append(oe.path.join(d.getVar("base_libdir", True), "systemd", "system"))
> + searchpaths.append(oe.path.join(d.getVar("libdir", True), "systemd", "system"))
> + searchpaths.append(oe.path.join(d.getVar("libdir", True), "systemd", "user"))
> + systemd_packages = d.getVar('SYSTEMD_PACKAGES', True)
> + has_exactly_one_service = len(systemd_packages.split()) == 1
> + if has_exactly_one_service:
> + has_exactly_one_service = len(get_package_var(d, 'SYSTEMD_SERVICE', systemd_packages).split()) == 1
> +
> + keys = 'Also' # Conflicts??
> + if has_exactly_one_service:
> + # single service gets also the /dev/null dummies
> + keys = 'Also Conflicts'
> + # scan for all in SYSTEMD_SERVICE[]
> + for pkg_systemd in systemd_packages.split():
> + for service in get_package_var(d, 'SYSTEMD_SERVICE', pkg_systemd).split():
> + path_found = ''
> + for path in searchpaths:
> + if os.path.exists(oe.path.join(d.getVar("D", True), path, service)):
> + path_found = path
> + break
> + if path_found != '':
> + systemd_add_files_and_parse(pkg_systemd, path_found, service, keys)
> + else:
> + raise bb.build.FuncFailed, "\n\nSYSTEMD_SERVICE_%s value %s does not exist" % \
> + (pkg_systemd, service)
> +
> + # Run all modifications once when creating package
> + if os.path.exists(d.getVar("D", True)):
> + for pkg in d.getVar('SYSTEMD_PACKAGES', True).split():
> + if d.getVar('SYSTEMD_SERVICE_' + pkg, True):
> + systemd_generate_package_scripts(pkg)
> + systemd_add_rdepends(pkg)
> + systemd_check_services()
> +
> +
> +python populate_packages_prepend () {
> + if oe.utils.contains ('DISTRO_FEATURES', 'systemd', True, False, d):
> + systemd_populate_packages (d)
> +}
I know this has been a long time in the works so I'll merge but could
you follow up with a change:
PACKAGESPLITFUNCS_prepend = "systemd_populate_packages "
and just put the
oe.utils.contains ('DISTRO_FEATURES', 'systemd', True, False, d) into
systemd_populate_packages with a return? You'll need to drop the d as a
parameter and turn it into a python xxxx() { style function. The nice
thing is this then shows up nicely on the profiles too. I'm aiming to
stamp out use of populate_packages_prepend entirely.
Cheers,
Richard
next prev parent reply other threads:[~2013-02-11 14:59 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-02-08 22:43 [PATCH 0/5] systemd class, and more enabling Ross Burton
2013-02-08 22:43 ` [PATCH 1/5] systemd.bbclass: helper class for recipes with systemd units Ross Burton
2013-02-11 14:43 ` Richard Purdie [this message]
2013-02-11 14:43 ` [OE-core] " Richard Purdie
2013-02-08 22:43 ` [PATCH 2/5] update-rc.d: don't do anything if systemd.bbclass is inherited Ross Burton
2013-02-08 22:43 ` [PATCH 3/5] connman: Enabling with systemd Ross Burton
2013-02-08 22:43 ` [PATCH 4/5] avahi: " Ross Burton
2013-02-08 22:43 ` [PATCH 5/5] wpa-supplicant: " Ross Burton
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1360593792.6793.74.camel@ted \
--to=richard.purdie@linuxfoundation.org \
--cc=openembedded-core@lists.openembedded.org \
--cc=openembedded-devel@lists.openembedded.org \
--cc=ross.burton@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.