summaryrefslogtreecommitdiff
path: root/buildstream/plugins/elements/dpkg_deploy.py
diff options
context:
space:
mode:
Diffstat (limited to 'buildstream/plugins/elements/dpkg_deploy.py')
-rw-r--r--buildstream/plugins/elements/dpkg_deploy.py271
1 files changed, 0 insertions, 271 deletions
diff --git a/buildstream/plugins/elements/dpkg_deploy.py b/buildstream/plugins/elements/dpkg_deploy.py
deleted file mode 100644
index c87357cbe..000000000
--- a/buildstream/plugins/elements/dpkg_deploy.py
+++ /dev/null
@@ -1,271 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright (C) 2017 Codethink Limited
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library 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
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library. If not, see <http://www.gnu.org/licenses/>.
-#
-# Authors:
-# Jonathan Maw <jonathan.maw@codethink.co.uk>
-
-"""Dpkg deployment element
-
-A :mod:`ScriptElement <buildstream.scriptelement>` implementation for creating
-debian packages
-
-Default Configuration
-~~~~~~~~~~~~~~~~~~~~~
-
-The dpkg_deploy default configuration:
- .. literalinclude:: ../../../buildstream/plugins/elements/dpkg_deploy.yaml
- :language: yaml
-
-Public Data
-~~~~~~~~~~~
-
-This plugin uses the public data of the element indicated by `config.input`
-to generate debian packages.
-
-split-rules
------------
-
-This plugin consumes the input element's split-rules to identify which file
-goes in which package, e.g.
-
-.. code:: yaml
-
- public:
- split-rules:
- foo:
- - /sbin/foo
- - /usr/bin/bar
- bar:
- - /etc/quux
-
-dpkg-data
----------
-
-control
-'''''''
-
-The control field is used to generate the control file for each package, e.g.
-
-.. code:: yaml
-
- public:
- dpkg-data:
- foo:
- control: |
- Source: foo
- Section: blah
- Build-depends: bar (>= 1337), baz
- ...
-
-name
-''''
-
-If the "name" field is present, the generated package will use that field to
-determine its name.
-If "name" is not present, the generated package will be named
-<element_name>-<package_name>
-
-i.e. in an element named foo:
-
-.. code:: yaml
-
- public:
- dpkg-data:
- bar:
- name: foobar
-
-will be named "foobar", while the following data:
-
-.. code:: yaml
-
- public:
- dpkg-data:
- bar:
- ...
-
-will create a package named "foo-bar"
-
-package-scripts
----------------
-
-preinst, postinst, prerm and postrm scripts will be generated
-based on data in pacakge-scripts, if it exists. The scripts are formatted as
-raw text, e.g.
-
-.. code:: yaml
-
- public:
- package-scripts:
- foo:
- preinst: |
- #!/usr/bin/bash
- /sbin/ldconfig
- bar:
- postinst: |
- #!/usr/bin/bash
- /usr/share/fonts/generate_fonts.sh
-
-"""
-
-import hashlib
-import os
-import re
-from buildstream import ScriptElement, Scope, utils
-
-
-def md5sum_file(path):
- hash_md5 = hashlib.md5()
- with open(path, "rb") as f:
- for chunk in iter(lambda: f.read(4096), b""):
- hash_md5.update(chunk)
- return hash_md5.hexdigest()
-
-
-# Element implementation for the 'dpkg_deploy' kind.
-class DpkgDeployElement(ScriptElement):
- def configure(self, node):
- prefixes = ["pre-", "", "post-"]
- groups = ["build-commands"]
-
- self.node_validate(node, [
- 'pre-build-commands', 'build-commands', 'post-build-commands',
- 'base', 'input'
- ])
-
- self.__input = self.node_subst_member(node, 'input')
- self.layout_add(self.node_subst_member(node, 'base'), "/")
- self.layout_add(None, '/buildstream')
- self.layout_add(self.__input,
- self.get_variable('build-root'))
- self.unedited_cmds = {}
- for group in groups:
- cmds = []
- if group not in node:
- raise ElementError("{}: Unexpectedly missing command group '{}'"
- .format(self, group))
- for prefix in prefixes:
- if prefix + group in node:
- cmds += self.node_subst_list(node, prefix + group)
- self.unedited_cmds[group] = cmds
-
- self.set_work_dir()
- self.set_install_root()
- self.set_root_read_only(True)
-
- def get_unique_key(self):
- key = super().get_unique_key()
- del key["commands"]
- key["unedited-commands"] = self.unedited_cmds
- return key
-
- def stage(self, sandbox):
- super().stage(sandbox)
- # For each package, create a subdir in build-root and copy the files to there
- # then reconstitute the /DEBIAN files.
- input_elm = self.search(Scope.BUILD, self.__input)
- if not input_elm:
- self.error("{}: Failed to find input element {} in build-depends"
- .format(self.name, self.__input))
- return
- bstdata = input_elm.get_public_data('bst')
- if "dpkg-data" not in bstdata:
- self.error("{}: input element {} does not have any bst.dpkg-data public data"
- .format(self.name, self.__input))
- for package, package_data in self.node_items(bstdata['dpkg-data']):
- package_name = package_data.get("name", "{}-{}".format(input_elm.normal_name, package))
- if not ("split-rules" in bstdata and
- package in bstdata["split-rules"]):
- self.error("{}: Input element {} does not have bst.split-rules.{}"
- .format(self.name, self.__input.name, package))
- package_splits = bstdata['split-rules'][package]
- src = os.path.join(sandbox.get_directory(),
- self.get_variable("build-root").lstrip(os.sep))
- dst = os.path.join(src, package)
- os.makedirs(dst, exist_ok=True)
- utils.link_files(src, dst, package_splits)
-
- # Create this dir. If it already exists,
- # something unexpected has happened.
- debiandir = os.path.join(dst, "DEBIAN")
- os.makedirs(debiandir)
-
- # Recreate the DEBIAN files.
- # control is extracted verbatim, and is mandatory.
- if "control" not in package_data:
- self.error("{}: Cannot reconstitute package {}".format(self.name, package),
- detail="There is no public.bst.dpkg-data.{}.control".format(package))
- controlpath = os.path.join(debiandir, "control")
- controltext = package_data["control"]
- # Slightly ugly way of renaming the package
- controltext = re.sub(r"^Package:\s*\S+",
- "Package: {}".format(package_name),
- controltext)
- with open(controlpath, "w") as f:
- f.write(controltext)
-
- # Generate a DEBIAN/md5sums file from the artifact
- md5sums = {}
- for split in package_splits:
- filepath = os.path.join(src, split.lstrip(os.sep))
- if os.path.isfile(filepath):
- md5sums[split] = md5sum_file(filepath)
- md5sumspath = os.path.join(debiandir, "md5sums")
- with open(md5sumspath, "w") as f:
- for path, md5sum in md5sums.items():
- f.write("{} {}\n".format(md5sum, path))
-
- # scripts may exist
- if ("package-scripts" in bstdata and
- package in bstdata["package-scripts"]):
- for script in ["postinst", "preinst", "postrm", "prerm"]:
- if script in bstdata["package-scripts"][package]:
- filepath = os.path.join(debiandir, script)
- with open(filepath, "w") as f:
- f.write(bstdata["package-scripts"][package][script])
- os.chmod(filepath, 0o755)
-
- def _packages_list(self):
- input_elm = self.search(Scope.BUILD, self.__input)
- if not input_elm:
- detail = ("Available elements are {}"
- .format("\n".join([x.name for x in self.dependencies(Scope.BUILD)])))
- self.error("{} Failed to find element {}".format(self.name, self.__input),
- detail=detail)
-
- bstdata = input_elm.get_public_data("bst")
- if "dpkg-data" not in bstdata:
- self.error("{}: Can't get package list for {}, no bst.dpkg-data"
- .format(self.name, self.__input))
- return " ".join([k for k, v in self.node_items(bstdata["dpkg-data"])])
-
- def _sub_packages_list(self, cmdlist):
- return [
- cmd.replace("<PACKAGES>", self._packages_list()) for cmd in cmdlist
- ]
-
- def assemble(self, sandbox):
- # Mangle commands here to replace <PACKAGES> with the list of packages.
- # It can't be done in configure (where it was originally set) because
- # we don't have access to the input element at that time.
- for group, commands in self.unedited_cmds.items():
- self.add_commands(group, self._sub_packages_list(commands))
- return super().assemble(sandbox)
-
-
-# Plugin entry point
-def setup():
- return DpkgDeployElement