stage/systemd-unit:stage to create systemd unit file
Add systemd unit files in osbuild stage This stage creates systemd unit file in `/usr/lib/systemd/system/`. The stage accepts filename which must end with `.service`.Section `Unit` , `Service` , `Install` accepts various parameters as per the systemd documentaion.`systemd-analyze verify` is be performed after the .service file is created to check for potential errors. Signed-off-by: Sayan Paul <paul.sayan@gmail.com>
This commit is contained in:
parent
f9e35c25da
commit
e858dc72c3
6 changed files with 2388 additions and 0 deletions
181
stages/org.osbuild.systemd.unit.create
Executable file
181
stages/org.osbuild.systemd.unit.create
Executable file
|
|
@ -0,0 +1,181 @@
|
|||
#!/usr/bin/python3
|
||||
"""
|
||||
Create Systemd services unit file
|
||||
|
||||
This stage allows to create Systemd unit files in
|
||||
`/usr/lib/systemd/system/`. The `filename` property specifies the
|
||||
'.service' file to be added. These names are validated using the
|
||||
same rules as specified by systemd.unit(5) and they must contain the
|
||||
'.service' suffix (other types of unit files are not supported).
|
||||
|
||||
The Unit configuration can currently specify the following subset
|
||||
of options:
|
||||
- 'Unit' section
|
||||
- 'Description' - string
|
||||
- 'ConditionPathExists' - string
|
||||
- 'DefaultDependencies' - bool
|
||||
- 'Requires' - [strings]
|
||||
- 'Wants' - [strings]
|
||||
- 'Service' section
|
||||
- 'Type' - string
|
||||
- 'RemainAfterExit' - bool
|
||||
- 'ExecStartPre' - [string]
|
||||
- 'ExecStopPost' - [string]
|
||||
- 'ExecStart' - [string]
|
||||
- 'Install' section
|
||||
- 'WantedBy' - [string]
|
||||
- 'RequiredBy' - [string]
|
||||
"""
|
||||
|
||||
import configparser
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
import osbuild.api
|
||||
|
||||
SCHEMA = r"""
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"filename",
|
||||
"config"
|
||||
],
|
||||
"properties": {
|
||||
"filename": {
|
||||
"type": "string",
|
||||
"pattern": "^[\\w:.\\\\-]+[@]{0,1}[\\w:.\\\\-]*\\.service$"
|
||||
},
|
||||
"config": {
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": ["Unit", "Service", "Install"],
|
||||
"description": "Configuration for a '.service' unit.",
|
||||
"properties": {
|
||||
"Unit": {
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"description": "'Unit' configuration section of a unit file.",
|
||||
"properties": {
|
||||
"Description": {
|
||||
"type": "string"
|
||||
},
|
||||
"Wants": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"Requires": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"ConditionPathExists": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"DefaultDependencies": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Service": {
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"description": "'Service' configuration section of a unit file.",
|
||||
"properties": {
|
||||
"Type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"simple",
|
||||
"exec",
|
||||
"forking",
|
||||
"oneshot",
|
||||
"dbus",
|
||||
"notify",
|
||||
"notify-reload",
|
||||
"idle"
|
||||
]
|
||||
},
|
||||
"RemainAfterExit": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"ExecStartPre": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"ExecStopPost": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"ExecStart": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Install": {
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"description": "'Install' configuration section of a unit file.",
|
||||
"properties": {
|
||||
"WantedBy": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"RequiredBy": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
def main(tree, options):
|
||||
filename = options["filename"]
|
||||
# ensure the service name does not exceed maximum filename length
|
||||
if len(filename) > 255:
|
||||
raise ValueError(f"Error: the {filename} service exceeds the maximum filename length.")
|
||||
|
||||
cfg = options["config"]
|
||||
config = configparser.ConfigParser(allow_no_value=True)
|
||||
# prevent conversion of the option name to lowercase
|
||||
config.optionxform = lambda option: option
|
||||
|
||||
for section, opts in cfg.items():
|
||||
if not config.has_section(section):
|
||||
config.add_section(section)
|
||||
for option, value in opts.items():
|
||||
if isinstance(value, list):
|
||||
for v in value:
|
||||
config.set(section, str(option) + "=" + str(v))
|
||||
else:
|
||||
config.set(section, option, str(value))
|
||||
|
||||
systemd_dir = f"{tree}/usr/lib/systemd/system"
|
||||
with open(f"{systemd_dir}/{filename}", "w", encoding="utf8") as f:
|
||||
config.write(f, space_around_delimiters=False)
|
||||
|
||||
subprocess.run(["systemd-analyze", "verify", f"{systemd_dir}/{filename}"], check=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = osbuild.api.arguments()
|
||||
r = main(args["tree"], args["options"])
|
||||
sys.exit(r)
|
||||
1043
test/data/stages/systemd.unit.create/a.json
Normal file
1043
test/data/stages/systemd.unit.create/a.json
Normal file
File diff suppressed because it is too large
Load diff
31
test/data/stages/systemd.unit.create/a.mpp.yaml
Normal file
31
test/data/stages/systemd.unit.create/a.mpp.yaml
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
version: '2'
|
||||
pipelines:
|
||||
- mpp-import-pipelines:
|
||||
path: ../manifests/fedora-vars.ipp.yaml
|
||||
- mpp-import-pipeline:
|
||||
path: ../manifests/fedora-build-v2.ipp.yaml
|
||||
id: build
|
||||
runner:
|
||||
mpp-format-string: org.osbuild.fedora{release}
|
||||
- name: tree
|
||||
build: name:build
|
||||
stages:
|
||||
- type: org.osbuild.rpm
|
||||
inputs:
|
||||
packages:
|
||||
type: org.osbuild.files
|
||||
origin: org.osbuild.source
|
||||
mpp-depsolve:
|
||||
architecture: $arch
|
||||
module-platform-id: $module_platform_id
|
||||
repos:
|
||||
mpp-eval: repos
|
||||
packages:
|
||||
- nftables
|
||||
- openssh-server
|
||||
- systemd
|
||||
options:
|
||||
gpgkeys:
|
||||
mpp-eval: gpgkeys
|
||||
exclude:
|
||||
docs: true
|
||||
1074
test/data/stages/systemd.unit.create/b.json
Normal file
1074
test/data/stages/systemd.unit.create/b.json
Normal file
File diff suppressed because it is too large
Load diff
52
test/data/stages/systemd.unit.create/b.mpp.yaml
Normal file
52
test/data/stages/systemd.unit.create/b.mpp.yaml
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
version: '2'
|
||||
pipelines:
|
||||
- mpp-import-pipelines:
|
||||
path: ../manifests/fedora-vars.ipp.yaml
|
||||
- mpp-import-pipeline:
|
||||
path: ../manifests/fedora-build-v2.ipp.yaml
|
||||
id: build
|
||||
runner:
|
||||
mpp-format-string: org.osbuild.fedora{release}
|
||||
- name: tree
|
||||
build: name:build
|
||||
stages:
|
||||
- type: org.osbuild.rpm
|
||||
inputs:
|
||||
packages:
|
||||
type: org.osbuild.files
|
||||
origin: org.osbuild.source
|
||||
mpp-depsolve:
|
||||
architecture: $arch
|
||||
module-platform-id: $module_platform_id
|
||||
repos:
|
||||
mpp-eval: repos
|
||||
packages:
|
||||
- nftables
|
||||
- openssh-server
|
||||
- systemd
|
||||
options:
|
||||
gpgkeys:
|
||||
mpp-eval: gpgkeys
|
||||
exclude:
|
||||
docs: true
|
||||
|
||||
- type: org.osbuild.systemd.unit.create
|
||||
options:
|
||||
filename: create-directory.service
|
||||
config:
|
||||
Unit:
|
||||
Description: Create directory
|
||||
DefaultDependencies: false
|
||||
ConditionPathExists:
|
||||
- "|!/etc/myfile"
|
||||
Service:
|
||||
Type: "oneshot"
|
||||
RemainAfterExit: true
|
||||
ExecStart:
|
||||
- mkdir -p /etc/mydir
|
||||
- touch /etc/myfile
|
||||
Install:
|
||||
WantedBy:
|
||||
- local-fs.target
|
||||
RequiredBy:
|
||||
- multi-user.target
|
||||
7
test/data/stages/systemd.unit.create/diff.json
Normal file
7
test/data/stages/systemd.unit.create/diff.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"added_files": [
|
||||
"/usr/lib/systemd/system/create-directory.service"
|
||||
],
|
||||
"deleted_files": [],
|
||||
"differences": {}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue