Compare commits

..

1 Commits

Author SHA1 Message Date
59bde93b91 add services-dinit 2023-12-26 02:44:23 +01:00
3 changed files with 31 additions and 45 deletions

View File

@@ -4,7 +4,7 @@
# === This file is part of Calamares - <https://github.com/calamares> === # === This file is part of Calamares - <https://github.com/calamares> ===
# #
# Copyright 2018-2019, Adriaan de Groot <groot@kde.org> # Copyright 2018-2019, Adriaan de Groot <groot@kde.org>
# Copyright 2019, Artoo <artoo@artixlinux.org> # Copyright 2021, Artoo <artoo@artixlinux.org>
# #
# Calamares is free software: you can redistribute it and/or modify # Calamares is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
@@ -33,12 +33,12 @@ _ = gettext.translation("calamares-python",
def pretty_name(): def pretty_name():
return _("Configure Runit services") return _("Configure Dinit services")
class RunitController: class DinitController:
""" """
This is the runit service controller. This is the dinit service controller.
All of its state comes from global storage and the job All of its state comes from global storage and the job
configuration at initialization time. configuration at initialization time.
""" """
@@ -51,45 +51,43 @@ class RunitController:
self.services["enable"] = libcalamares.job.configuration.get('services', []) self.services["enable"] = libcalamares.job.configuration.get('services', [])
self.services["disable"] = libcalamares.job.configuration.get('disable', []) self.services["disable"] = libcalamares.job.configuration.get('disable', [])
self.svDir = libcalamares.job.configuration['svDir'] self.initdDir = libcalamares.job.configuration['initdDir']
self.runsvDir = libcalamares.job.configuration['runsvDir'] self.runsvDir = libcalamares.job.configuration['runsvDir']
def make_failure_description(self, state, name, runlevel): def make_failure_description(self, state, name):
""" """
Returns a generic "could not <foo>" failure message, specialized Returns a generic "could not <foo>" failure message, specialized
for the action @p state and the specific service @p name in @p runlevel. for the action @p state and the specific service @p name.
""" """
if state == "enable": if state == "enable":
description = _("Cannot enable service {name!s} to run-level {level!s}.") description = _("Cannot enable service {name!s}.")
elif state == "disable": elif state == "disable":
description = _("Cannot disable service {name!s} from run-level {level!s}.") description = _("Cannot disable service {name!s}.")
else: else:
description = _("Unknown service-action <code>{arg!s}</code> for service {name!s} in run-level {level!s}.") description = _("Unknown service-action <code>{arg!s}</code> for service {name!s}.")
return description.format(arg=state, name=name, level=runlevel) return description.format(arg=state, name=name)
def update(self, state): def update(self, state):
""" """
Call sv-helper for each service listed Process each service listed
in services for the given @p state. in services for the given @p state.
""" """
for svc in self.services.get(state, []): for svc in self.services.get(state, []):
if isinstance(svc, str): if isinstance(svc, str):
name = svc name = svc
runlevel = "default"
mandatory = False mandatory = False
else: else:
name = svc["name"] name = svc["name"]
runlevel = svc.get("runlevel", "default")
mandatory = svc.get("mandatory", False) mandatory = svc.get("mandatory", False)
service_path = self.root + self.svDir + "/" + name service_path = self.root + self.initdDir + "/" + name
runlevel_path = self.root + self.runsvDir + "/" + runlevel runlevel_path = self.root + self.runsvDir
src = self.svDir + "/" + name src = self.initdDir + "/" + name
dest = self.runsvDir + "/" + runlevel + "/" dest = self.runsvDir + "/"
if state == 'enable': if state == 'enable':
cmd = ["ln", "-sv", src, dest] cmd = ["ln", "-sv", src, dest]
@@ -100,30 +98,21 @@ class RunitController:
if exists(runlevel_path): if exists(runlevel_path):
ec = target_env_call(cmd) ec = target_env_call(cmd)
if ec != 0: if ec != 0:
warning("Cannot {} service {} to {}".format(state, name, runlevel)) warning("Cannot {} service {}".format(state, name))
warning("{} returned error code {!s}".format(cmd, ec)) warning("{} returned error code {!s}".format(cmd, ec))
if mandatory: if mandatory:
title = _("Cannot modify service") title = _("Cannot modify service")
diagnostic = _("<code>cmd {arg!s}</code> call in chroot returned error code {num!s}.").format(arg=state, num=ec) diagnostic = _("<code>cmd {arg!s}</code> call in chroot returned error code {num!s}.").format(arg=state, num=ec)
return (title, return (title,
self.make_failure_description(state, name, runlevel) + " " + diagnostic self.make_failure_description(state, name) + " " + diagnostic
) )
else:
warning("Target runlevel {} does not exist for {}.".format(runlevel, name))
if mandatory:
title = _("Target runlevel does not exist")
diagnostic = _("The path for runlevel {level!s} is <code>{path!s}</code>, which does not exist.").format(level=runlevel, path=runlevel_path)
return (title,
self.make_failure_description(state, name, runlevel) + " " + diagnostic
)
else: else:
warning("Target service {} does not exist in {}.".format(name, self.svDir)) warning("Target service {} does not exist in {}.".format(name, self.initdDir))
if mandatory: if mandatory:
title = _("Target service does not exist") title = _("Target service does not exist")
diagnostic = _("The path for service {name!s} is <code>{path!s}</code>, which does not exist.").format(name=name, path=service_path) diagnostic = _("The path for service {name!s} is <code>{path!s}</code>, which does not exist.").format(name=name, path=service_path)
return (title, return (title,
self.make_failure_description(state, name, runlevel) + " " + diagnostic self.make_failure_description(state, name) + " " + diagnostic
) )
@@ -141,4 +130,4 @@ def run():
Setup services Setup services
""" """
return RunitController().run() return DinitController().run()

View File

@@ -1,5 +1,5 @@
--- ---
type: "job" type: "job"
name: "services-runit" name: "services-dinit"
interface: "python" interface: "python"
script: "main.py" script: "main.py"

View File

@@ -4,39 +4,36 @@
# Handle disable with care and only use it if absolutely necessary. # Handle disable with care and only use it if absolutely necessary.
# #
# if a service is listed in the conf but is not present/detected on the target system, # if a service is listed in the conf but is not present/detected on the target system,
# or a runlevel does not exist, it will be ignored and skipped; a warning is logged. # it will be ignored and skipped; a warning is logged.
# #
--- ---
# svDir: holds the runit service directory location # initdDir: holds the runit service directory location
svDir: /etc/runit/sv initdDir: /etc/dinit.d
# runsvDir: holds the runlevels directory location # runsvDir: holds the runlevels directory location
runsvDir: /etc/runit/runsvdir runsvDir: /etc/dinit.d/boot.d
# services: a list of entries to **enable** # services: a list of entries to **enable**
# disable: a list of entries to **disable** # disable: a list of entries to **disable**
# #
# Each entry has three fields: # Each entry has three fields:
# - name: the service name # - name: the service name
# - (optional) runlevel: can hold any runlevel present on the target
# system; if no runlevel is provided, "default" is assumed.
# - (optional) mandatory: if set to true, a failure to modify # - (optional) mandatory: if set to true, a failure to modify
# the service will result in installation failure, rather than just # the service will result in installation failure, rather than just
# a warning. The default is false. # a warning. The default is false.
# #
# an entry may also be a single string, which is interpreted # an entry may also be a single string, which is interpreted
# as the name field (runlevel "default" is assumed then, and not-mandatory). # as the name field.
# #
# # Example services and disable settings: # # Example services and disable settings:
# # - add foo1 to default, but it must succeed # # - add foo1, but it must succeed
# # - add foo2 to nonetwork # # - add foo2
# # - remove foo3 from default # # - remove foo3
# # - remove foo4 from default # # - remove foo4
# services: # services:
# - name: foo1 # - name: foo1
# mandatory: true # mandatory: true
# - name: foo2 # - name: foo2
# runlevel: nonetwork
# disable: # disable:
# - name: foo3 # - name: foo3
# - foo4 # - foo4