[oe] [meta-oe][RFC 01/27] systemd.bbclass: rework
Andreas Müller
schnitzeltony at googlemail.com
Tue Feb 7 15:12:27 UTC 2012
let systemd.bbclass do more for us and prepare support images without systemd
* introduce a global variable INIT_MANAGER. For images using systemd, this must
contain 'systemd'. This varibale can e.g be set to default in local.conf and
then overridden by distro.
* handle multiple entries in SYSTEMD_SERVICE. Currenly there are no use cases
but networkmanager has potential requirements
* handle multiple entries in SYSTEMD_PACKAGES. Possible use cases are
dhcp/dhcp-relay and ntp/ntpdate
* enhance the checks for SYSTEMD_PACKAGES and SYSTEMD_SERVICE. For package
names only <name-of-an-existing-package>-systemd or ${PN} are allowed. In
case of using ${PN} a warning is spitted. This was introduced to force recipe
maintainers to separate out systemd to own package.
* all systemd packages are automatically created based on SYSTEMD_PACKAGES
* for systemd packets and their base packages RDEPENDS/RRECOMMENDS are
automatically extended. Hereby it is ensured that all packets for proper
systemd operation find their way into the image. Nice side effect:
if in all tasks/images the base packets are include insted of *-systemd it is
only a matter of INIT_MANAGER if systemd-packets are imaged.
* all *.socket and *.service files included by SRC_URI are automatically
installed from WORKDIR.
* remove systemd from DEPENDS. Recipes requiring systemd at buildtime, should
take care themselves.
Signed-off-by: Andreas Müller <schnitzeltony at googlemail.com>
---
meta-oe/classes/systemd.bbclass | 173 +++++++++++++++++++++++++++++++++-----
1 files changed, 150 insertions(+), 23 deletions(-)
diff --git a/meta-oe/classes/systemd.bbclass b/meta-oe/classes/systemd.bbclass
index 094a12c..c843e66 100644
--- a/meta-oe/classes/systemd.bbclass
+++ b/meta-oe/classes/systemd.bbclass
@@ -1,5 +1,6 @@
-DEPENDS_append = " systemd systemd-systemctl-native"
+DEPENDS_append = " systemd-systemctl-native"
+# pre/post-inst/rm for each entry in SYSTEMD_SERVICE
systemd_postinst() {
OPTS=""
@@ -7,34 +8,95 @@ if [ -n "$D" ]; then
OPTS="--root=$D"
fi
-systemctl $OPTS enable ${SYSTEMD_SERVICE}
+for service in ${SYSTEMD_SERVICE} ; do
+ systemctl $OPTS enable $service
+done
if [ -z "$D" ]; then
- systemctl start ${SYSTEMD_SERVICE}
+ for service in ${SYSTEMD_SERVICE} ; do
+ systemctl start $service
+ done
fi
}
systemd_prerm() {
if [ -z "$D" ]; then
- systemctl stop ${SYSTEMD_SERVICE}
+ for service in ${SYSTEMD_SERVICE} ; do
+ systemctl stop $service
+ done
fi
}
systemd_postrm() {
-systemctl disable ${SYSTEMD_SERVICE}
+for service in ${SYSTEMD_SERVICE} ; do
+ systemctl disable $service
+done
}
def systemd_after_parse(d):
- if bb.data.getVar('SYSTEMD_PACKAGES', d) == None:
- if bb.data.getVar('SYSTEMD_SERVICE', d) == None:
- raise bb.build.FuncFailed, "%s inherits systemd but doesn't set SYSTEMD_SERVICE" % bb.data.getVar('FILE', d)
+ def systemd_check_vars():
+ # not for native / only at parse time
+ if d.getVar('BPN', 1) + "-native" != d.getVar('PN', 1) and d.getVar('BB_WORKERCONTEXT', True) is None:
+ bb_filename = d.getVar('FILE')
+ packages = d.getVar('PACKAGES', 1)
+
+ # check SYSTEMD_PACKAGES
+ systemd_pkgs = d.getVar('SYSTEMD_PACKAGES', 1) or ""
+ if systemd_pkgs == "":
+ raise bb.build.FuncFailed, "\n\n%s inherits systemd but doesn't set SYSTEMD_PACKAGES" % bb_filename
+ for pkg_systemd in systemd_pkgs.split():
+ if pkg_systemd.find("-systemd") == -1:
+ if pkg_systemd != d.getVar('PN', 1):
+ raise (bb.build.FuncFailed,
+ "\n\n%s: %s in SYSTEMD_PACKAGES does not match <base-package-using-systemd>-systemd or ${PN} (deprecated)" %
+ (bb_filename, pkg_systemd))
+ else:
+ bb.warn("%s: it is recommended to set SYSTEMD_PACKAGES as <base-package-using-systemd>-systemd" % bb_filename)
+ else:
+ pkg_systemd_base = pkg_systemd.replace('-systemd', '')
+ if pkg_systemd_base not in packages:
+ raise (bb.build.FuncFailed,
+ "\n\n%s: %s in SYSTEMD_PACKAGES does not match <base-package-using-systemd>-systemd or ${PN} (deprecated)" %
+ ( bb_filename, pkg_systemd))
+
+ # check SYSTEMD_SERVICE
+ for pkg_systemd in systemd_pkgs.split():
+ service_pkg = 'SYSTEMD_SERVICE' + "_" + pkg_systemd
+ systemd_services = d.getVar(service_pkg, 1) or d.getVar('SYSTEMD_SERVICE', 1) or ""
+ if systemd_services == "":
+ raise bb.build.FuncFailed, "\n\n%s inherits systemd but doesn't set SYSTEMD_SERVICE / %s" % (bb_filename, service_pkg)
+
+ # prepend packages not already included
+ def systemd_create_package(pkg_systemd):
+ packages = d.getVar('PACKAGES', 1)
+ if not pkg_systemd in packages:
+ packages = "%s %s" % (pkg_systemd, packages)
+ d.setVar('PACKAGES', packages)
+
+
+ systemd_check_vars()
+ systemd_pkgs = d.getVar('SYSTEMD_PACKAGES', 1)
+ for pkg_systemd in systemd_pkgs.split():
+ systemd_create_package(pkg_systemd)
+
python __anonymous() {
- systemd_after_parse(d)
+ systemd_after_parse(d)
+}
+
+# automatically install all *.service and *.socket supplied in SRC_URI
+do_install_append() {
+ install -d ${D}${base_libdir}/systemd/system
+ for service in `find ${WORKDIR} -maxdepth 1 -name '*.service' -o -name '*.socket'` ; do
+ # ensure installing systemd-files only (e.g not avahi *.service)
+ if grep -q '\[Unit\]' $service ; then
+ install -m 644 $service ${D}${base_libdir}/systemd/system
+ fi
+ done
}
python populate_packages_prepend () {
- def systemd_package(pkg):
+ def systemd_prepost_instrm(pkg):
bb.debug(1, 'adding systemd calls to postinst/postrm for %s' % pkg)
localdata = bb.data.createCopy(d)
overrides = bb.data.getVar("OVERRIDES", localdata, 1)
@@ -45,7 +107,7 @@ python populate_packages_prepend () {
systemd postinst is appended here because pkg_postinst may require to
execute on the target. Not doing so may cause systemd postinst invoked
twice to cause unwanted warnings.
- """
+ """
postinst = bb.data.getVar('pkg_postinst', localdata, 1)
if not postinst:
postinst = '#!/bin/sh\n'
@@ -58,23 +120,88 @@ python populate_packages_prepend () {
prerm += bb.data.getVar('systemd_prerm', localdata, 1)
bb.data.setVar('pkg_prerm_%s' % pkg, prerm, d)
- postrm = bb.data.getVar('pkg_postrm', localdata, 1)
- if not postrm:
- postrm = '#!/bin/sh\n'
- postrm += bb.data.getVar('systemd_postrm', localdata, 1)
+ postrm = bb.data.getVar('pkg_postrm', localdata, 1)
+ if not postrm:
+ postrm = '#!/bin/sh\n'
+ postrm += bb.data.getVar('systemd_postrm', localdata, 1)
bb.data.setVar('pkg_postrm_%s' % pkg, postrm, d)
rdepends = explode_deps(bb.data.getVar('RDEPENDS_' + pkg, d, 0) or bb.data.getVar('RDEPENDS', d, 0) or "")
rdepends.append("systemd")
bb.data.setVar('RDEPENDS_' + pkg, " " + " ".join(rdepends), d)
+ """ Setup rdepends / rrecommmends as:
+
+ -----------------------------
+ | pkg_systemd_base: 'foo' |
+ -----------------------------
+ | ^
+ | | --------------
+ rrecommends | | rdepends | 'systemd' |
+ | | ->--------------
+ V | / rdepends
+ ------------------------------/
+ | pkg_systemd: 'foo-systemd' |
+ ------------------------------
+ """
+ def systemd_rdepend_rrecommends(pkg_systemd):
+ pn_pkg = d.getVar('PN', 1)
+ # RDEPENDS_${pkg_systemd} += pkg_systemd_base systemd
+ rdepends = explode_deps(d.getVar('RDEPENDS_' + pkg_systemd, 1) or "")
+ if not 'systemd' in rdepends:
+ rdepends.append('systemd')
+ pkg_systemd_base = pkg_systemd.replace('-systemd', '')
+ # not rdepending myself / avoid double entries
+ if pkg_systemd != pn_pkg and not pkg_systemd_base in rdepends:
+ rdepends.append(pkg_systemd_base)
+ d.setVar('RDEPENDS_' + pkg_systemd, " " + " ".join(rdepends))
+ # default: just a suggestion - to be discussed?
+ initmanager = d.getVar('INIT_MANAGER', 1) or 'systemd'
+ # RRECOMMENDS_${pkg_systemd_base} += pkg_systemd systemd
+ if initmanager == 'systemd':
+ rrecommends = explode_deps(d.getVar('RRECOMMENDS_' + pkg_systemd_base, 1) or "")
+ # not rrecommending myself / avoid double entries
+ if pkg_systemd != pn_pkg and not pkg_systemd in rrecommends:
+ rrecommends.append(pkg_systemd)
+ d.setVar('RRECOMMENDS_' + pkg_systemd_base, " " + " ".join(rrecommends))
+
+ # append systemd files to FILES_*-systemd
+ def systemd_files(pkg_systemd):
+ systemd_services = d.getVar('SYSTEMD_SERVICE' + "_" + pkg_systemd, 1) or d.getVar('SYSTEMD_SERVICE', 1)
+ files_append = ""
+ if len(systemd_pkgs.split()) == 1:
+ # distribute complete ${base_libdir}/systemd/system/ to ${SYSTEMD_PACKAGES}
+ files_append = '${base_libdir}/systemd/system/'
+ else:
+ # distribute files set in SYSTEMD_SERVICE to ${SYSTEMD_PACKAGES}
+ for service in systemd_services.split():
+ files_append += " ${base_libdir}/systemd/system/" + service
+
+ var_name = "FILES_" + pkg_systemd
+ files = d.getVar(var_name, 0) or ""
+ d.setVar(var_name, "%s %s" % (files, files_append))
+
+
+ systemd_pkgs = d.getVar('SYSTEMD_PACKAGES', 1)
+ for pkg_systemd in systemd_pkgs.split():
+ systemd_prepost_instrm(pkg_systemd)
+ systemd_rdepend_rrecommends(pkg_systemd)
+ systemd_files(pkg_systemd)
- pkgs = bb.data.getVar('SYSTEMD_PACKAGES', d, 1)
- if pkgs == None:
- pkgs = bb.data.getVar('PN', d, 1)
- packages = (bb.data.getVar('PACKAGES', d, 1) or "").split()
- if not pkgs in packages and packages != []:
- pkgs = packages[0]
- for pkg in pkgs.split():
- systemd_package(pkg)
+ # temporary debug output found in do_package.log
+ pn_pkg = d.getVar('PN', 1)
+ print 'base-package info:'
+ print 'DEPENDS: %s' % d.getVar('DEPENDS', 1)
+ print 'PACKAGES: %s' % d.getVar('PACKAGES', 1)
+ print 'RDEPENDS_%s: %s' % (pn_pkg, d.getVar('RDEPENDS_' + pn_pkg, 1))
+ print 'RRECOMMENDS_%s: %s' % (pn_pkg, d.getVar('RRECOMMENDS_' + pn_pkg, 1))
+ print 'systemd-(base-)-packages info:'
+ for pkg_systemd in systemd_pkgs.split():
+ pkg_systemd_base = pkg_systemd.replace('-systemd', '')
+ print 'RDEPENDS_%s: %s' % (pkg_systemd_base, d.getVar('RDEPENDS_' + pkg_systemd_base, 1))
+ print 'RDEPENDS_%s: %s' % (pkg_systemd, d.getVar('RDEPENDS_' + pkg_systemd, 1))
+ print 'RRECOMMENDS_%s: %s' % (pkg_systemd_base, d.getVar('RRECOMMENDS_' + pkg_systemd_base, 1))
+ print 'RRECOMMENDS_%s: %s' % (pkg_systemd, d.getVar('RRECOMMENDS_' + pkg_systemd, 1))
+ print 'FILES_%s: %s' % (pkg_systemd_base, d.getVar('FILES_' + pkg_systemd_base, 1))
+ print 'FILES_%s: %s' % (pkg_systemd, d.getVar('FILES_' + pkg_systemd, 1))
}
--
1.7.6.4
More information about the Openembedded-devel
mailing list