Compare commits

..

1 Commits

Author SHA1 Message Date
1eba5ba959 add services-runit 2023-12-26 02:45:08 +01:00
8 changed files with 339 additions and 276 deletions

View File

@@ -1,2 +0,0 @@
SPDX-FileCopyrightText: 2020 demmm <anke62@gmail.com>
SPDX-License-Identifier: GPL-3.0-or-later

View File

@@ -42,7 +42,7 @@ Item {
width: 450
height: 104
anchors.centerIn: parent
text: qsTr("OpenRC base system.<br/>
text: qsTr("LibreOffice is a powerful and free office suite, used by millions of people around the world. It includes several applications that make it the most versatile Free and Open Source office suite on the market.<br/>
Default option.")
font.pointSize: 10
anchors.verticalCenterOffset: -10
@@ -50,14 +50,76 @@ Item {
wrapMode: Text.WordWrap
}
Switch {
id: element2
x: 500
y: 110
width: 187
height: 14
text: qsTr("LibreOffice")
checked: true
hoverEnabled: true
ButtonGroup.group: switchGroup
indicator: Rectangle {
implicitWidth: 40
implicitHeight: 14
radius: 10
color: element2.checked ? "#3498db" : "#B9B9B9"
border.color: element2.checked ? "#3498db" : "#cccccc"
Rectangle {
x: element2.checked ? parent.width - width : 0
y: (parent.height - height) / 2
width: 20
height: 20
radius: 10
color: element2.down ? "#cccccc" : "#ffffff"
border.color: element2.checked ? (element1.down ? "#3498db" : "#3498db") : "#999999"
}
}
onCheckedChanged: {
if ( checked ) {
config.packageChoice = "libreoffice"
}
}
}
Image {
id: image2
x: 8
y: 25
height: 100
fillMode: Image.PreserveAspectFit
source: "images/libreoffice.jpg"
}
}
Rectangle {
width: 700
height: 150
radius: 10
border.width: 0
Text {
width: 450
height: 104
anchors.centerIn: parent
text: qsTr("If you don't want to install an office suite, just select No Office Suite. You can always add one (or more) later on your installed system as the need arrives.")
font.pointSize: 10
anchors.verticalCenterOffset: -10
anchors.horizontalCenterOffset: 100
wrapMode: Text.WordWrap
}
Switch {
id: element1
x: 500
y: 110
width: 187
height: 14
text: qsTr("OpenRC")
checked: true
text: qsTr("No Office Suite")
checked: false
hoverEnabled: true
ButtonGroup.group: switchGroup
@@ -81,80 +143,18 @@ Item {
onCheckedChanged: {
if ( checked ) {
config.packageChoice = "elogind-openrc"
config.packageChoice = "no_office_suite"
}
}
}
Image {
id: image1
id: image
x: 8
y: 25
height: 100
fillMode: Image.PreserveAspectFit
source: "images/artix.png"
}
}
Rectangle {
width: 700
height: 150
radius: 10
border.width: 0
Text {
width: 450
height: 104
anchors.centerIn: parent
text: qsTr("Dinit base system.")
font.pointSize: 10
anchors.verticalCenterOffset: -10
anchors.horizontalCenterOffset: 100
wrapMode: Text.WordWrap
}
Switch {
id: element2
x: 500
y: 110
width: 187
height: 14
text: qsTr("Dinit")
checked: false
hoverEnabled: true
ButtonGroup.group: switchGroup
indicator: Rectangle {
implicitWidth: 40
implicitHeight: 14
radius: 10
color: element2.checked ? "#3498db" : "#B9B9B9"
border.color: element2.checked ? "#3498db" : "#cccccc"
Rectangle {
x: element2.checked ? parent.width - width : 0
y: (parent.height - height) / 2
width: 20
height: 20
radius: 10
color: element2.down ? "#cccccc" : "#ffffff"
border.color: element2.checked ? (element2.down ? "#3498db" : "#3498db") : "#999999"
}
}
onCheckedChanged: {
if ( checked ) {
config.packageChoice = "elogind-dinit"
}
}
}
Image {
id: image2
x: 8
y: 25
height: 100
fillMode: Image.PreserveAspectFit
source: "images/artix.png"
source: "images/no-selection.png"
}
}
@@ -169,7 +169,7 @@ Item {
width: 450
height: 104
anchors.centerIn: parent
text: qsTr("Runit base system.")
text: qsTr("Create a minimal Desktop install, remove all extra applications and decide later on what you would like to add to your system. Examples of what won't be on such an install, there will be no Office Suite, no media players, no image viewer or print support. It will be just a desktop, file browser, package manager, text editor and simple web-browser.")
font.pointSize: 10
anchors.verticalCenterOffset: -10
anchors.horizontalCenterOffset: 100
@@ -182,7 +182,7 @@ Item {
y: 110
width: 187
height: 14
text: qsTr("Runit")
text: qsTr("Minimal Install")
checked: false
hoverEnabled: true
ButtonGroup.group: switchGroup
@@ -207,7 +207,7 @@ Item {
onCheckedChanged: {
if ( checked ) {
config.packageChoice = "elogind-runit"
config.packageChoice = "minimal_install"
}
}
}
@@ -218,70 +218,7 @@ Item {
y: 25
height: 100
fillMode: Image.PreserveAspectFit
source: "images/artix.png"
}
}
Rectangle {
width: 700
height: 150
color: "#ffffff"
radius: 10
border.width: 0
Text {
width: 450
height: 104
anchors.centerIn: parent
text: qsTr("S6 base system.")
font.pointSize: 10
anchors.verticalCenterOffset: -10
anchors.horizontalCenterOffset: 100
wrapMode: Text.WordWrap
}
Switch {
id: element4
x: 500
y: 110
width: 187
height: 14
text: qsTr("S6")
checked: false
hoverEnabled: true
ButtonGroup.group: switchGroup
indicator: Rectangle {
implicitWidth: 40
implicitHeight: 14
radius: 10
color: element4.checked ? "#3498db" : "#B9B9B9"
border.color: element4.checked ? "#3498db" : "#cccccc"
Rectangle {
x: element4.checked ? parent.width - width : 0
y: (parent.height - height) / 2
width: 20
height: 20
radius: 10
color: element4.down ? "#cccccc" : "#ffffff"
border.color: element4.checked ? (element4.down ? "#3498db" : "#3498db") : "#999999"
}
}
onCheckedChanged: {
if ( checked ) {
config.packageChoice = "elogind-s6"
}
}
}
Image {
id: image4
x: 8
y: 25
height: 100
fillMode: Image.PreserveAspectFit
source: "images/artix.png"
source: "images/plasma.png"
}
}
@@ -293,7 +230,7 @@ Item {
Text {
height: 25
anchors.centerIn: parent
text: qsTr("Please select an option for your install, or use the default: OpenRC.")
text: qsTr("Please select an option for your install, or use the default: LibreOffice included.")
font.pointSize: 10
wrapMode: Text.WordWrap
}

View File

@@ -4,6 +4,5 @@
<file>images/libreoffice.jpg</file>
<file>images/no-selection.png</file>
<file>images/plasma.png</file>
<file>images/artix.png</file>
</qresource>
</RCC>

View File

@@ -42,7 +42,7 @@ Item {
width: 450
height: 104
anchors.centerIn: parent
text: qsTr("OpenRC base system.<br/>
text: qsTr("LibreOffice is a powerful and free office suite, used by millions of people around the world. It includes several applications that make it the most versatile Free and Open Source office suite on the market.<br/>
Default option.")
font.pointSize: 10
anchors.verticalCenterOffset: -10
@@ -50,14 +50,76 @@ Item {
wrapMode: Text.WordWrap
}
Switch {
id: element2
x: 500
y: 110
width: 187
height: 14
text: qsTr("LibreOffice")
checked: true
hoverEnabled: true
ButtonGroup.group: switchGroup
indicator: Rectangle {
implicitWidth: 40
implicitHeight: 14
radius: 10
color: element2.checked ? "#3498db" : "#B9B9B9"
border.color: element2.checked ? "#3498db" : "#cccccc"
Rectangle {
x: element2.checked ? parent.width - width : 0
y: (parent.height - height) / 2
width: 20
height: 20
radius: 10
color: element2.down ? "#cccccc" : "#ffffff"
border.color: element2.checked ? (element1.down ? "#3498db" : "#3498db") : "#999999"
}
}
onCheckedChanged: {
if ( checked ) {
config.packageChoice = "libreoffice"
}
}
}
Image {
id: image2
x: 8
y: 25
height: 100
fillMode: Image.PreserveAspectFit
source: "images/libreoffice.jpg"
}
}
Rectangle {
width: 700
height: 150
radius: 10
border.width: 0
Text {
width: 450
height: 104
anchors.centerIn: parent
text: qsTr("If you don't want to install an office suite, just select No Office Suite. You can always add one (or more) later on your installed system as the need arrives.")
font.pointSize: 10
anchors.verticalCenterOffset: -10
anchors.horizontalCenterOffset: 100
wrapMode: Text.WordWrap
}
Switch {
id: element1
x: 500
y: 110
width: 187
height: 14
text: qsTr("OpenRC")
checked: true
text: qsTr("No Office Suite")
checked: false
hoverEnabled: true
ButtonGroup.group: switchGroup
@@ -81,80 +143,18 @@ Item {
onCheckedChanged: {
if ( checked ) {
config.packageChoice = "elogind-openrc"
config.packageChoice = "no_office_suite"
}
}
}
Image {
id: image1
id: image
x: 8
y: 25
height: 100
fillMode: Image.PreserveAspectFit
source: "images/artix.png"
}
}
Rectangle {
width: 700
height: 150
radius: 10
border.width: 0
Text {
width: 450
height: 104
anchors.centerIn: parent
text: qsTr("Dinit base system.")
font.pointSize: 10
anchors.verticalCenterOffset: -10
anchors.horizontalCenterOffset: 100
wrapMode: Text.WordWrap
}
Switch {
id: element2
x: 500
y: 110
width: 187
height: 14
text: qsTr("Dinit")
checked: false
hoverEnabled: true
ButtonGroup.group: switchGroup
indicator: Rectangle {
implicitWidth: 40
implicitHeight: 14
radius: 10
color: element2.checked ? "#3498db" : "#B9B9B9"
border.color: element2.checked ? "#3498db" : "#cccccc"
Rectangle {
x: element2.checked ? parent.width - width : 0
y: (parent.height - height) / 2
width: 20
height: 20
radius: 10
color: element2.down ? "#cccccc" : "#ffffff"
border.color: element2.checked ? (element2.down ? "#3498db" : "#3498db") : "#999999"
}
}
onCheckedChanged: {
if ( checked ) {
config.packageChoice = "elogind-dinit"
}
}
}
Image {
id: image2
x: 8
y: 25
height: 100
fillMode: Image.PreserveAspectFit
source: "images/artix.png"
source: "images/no-selection.png"
}
}
@@ -169,7 +169,7 @@ Item {
width: 450
height: 104
anchors.centerIn: parent
text: qsTr("Runit base system.")
text: qsTr("Create a minimal Desktop install, remove all extra applications and decide later on what you would like to add to your system. Examples of what won't be on such an install, there will be no Office Suite, no media players, no image viewer or print support. It will be just a desktop, file browser, package manager, text editor and simple web-browser.")
font.pointSize: 10
anchors.verticalCenterOffset: -10
anchors.horizontalCenterOffset: 100
@@ -182,7 +182,7 @@ Item {
y: 110
width: 187
height: 14
text: qsTr("Runit")
text: qsTr("Minimal Install")
checked: false
hoverEnabled: true
ButtonGroup.group: switchGroup
@@ -207,7 +207,7 @@ Item {
onCheckedChanged: {
if ( checked ) {
config.packageChoice = "elogind-runit"
config.packageChoice = "minimal_install"
}
}
}
@@ -218,70 +218,7 @@ Item {
y: 25
height: 100
fillMode: Image.PreserveAspectFit
source: "images/artix.png"
}
}
Rectangle {
width: 700
height: 150
color: "#ffffff"
radius: 10
border.width: 0
Text {
width: 450
height: 104
anchors.centerIn: parent
text: qsTr("S6 base system.")
font.pointSize: 10
anchors.verticalCenterOffset: -10
anchors.horizontalCenterOffset: 100
wrapMode: Text.WordWrap
}
Switch {
id: element4
x: 500
y: 110
width: 187
height: 14
text: qsTr("S6")
checked: false
hoverEnabled: true
ButtonGroup.group: switchGroup
indicator: Rectangle {
implicitWidth: 40
implicitHeight: 14
radius: 10
color: element4.checked ? "#3498db" : "#B9B9B9"
border.color: element4.checked ? "#3498db" : "#cccccc"
Rectangle {
x: element4.checked ? parent.width - width : 0
y: (parent.height - height) / 2
width: 20
height: 20
radius: 10
color: element4.down ? "#cccccc" : "#ffffff"
border.color: element4.checked ? (element4.down ? "#3498db" : "#3498db") : "#999999"
}
}
onCheckedChanged: {
if ( checked ) {
config.packageChoice = "elogind-s6"
}
}
}
Image {
id: image4
x: 8
y: 25
height: 100
fillMode: Image.PreserveAspectFit
source: "images/artix.png"
source: "images/plasma.png"
}
}
@@ -293,7 +230,7 @@ Item {
Text {
height: 25
anchors.centerIn: parent
text: qsTr("Please select an option for your install, or use the default: OpenRC.")
text: qsTr("Please select an option for your install, or use the default: LibreOffice included.")
font.pointSize: 10
wrapMode: Text.WordWrap
}

View File

@@ -4,6 +4,5 @@
<file>images/libreoffice.jpg</file>
<file>images/no-selection.png</file>
<file>images/plasma.png</file>
<file>images/artix.png</file>
</qresource>
</RCC>

View File

@@ -0,0 +1,144 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# === This file is part of Calamares - <https://github.com/calamares> ===
#
# Copyright 2018-2019, Adriaan de Groot <groot@kde.org>
# Copyright 2019, Artoo <artoo@artixlinux.org>
#
# Calamares is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Calamares 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Calamares. If not, see <http://www.gnu.org/licenses/>.
import libcalamares
from libcalamares.utils import target_env_call, warning
from os.path import exists, join
import gettext
_ = gettext.translation("calamares-python",
localedir=libcalamares.utils.gettext_path(),
languages=libcalamares.utils.gettext_languages(),
fallback=True).gettext
def pretty_name():
return _("Configure Runit services")
class RunitController:
"""
This is the runit service controller.
All of its state comes from global storage and the job
configuration at initialization time.
"""
def __init__(self):
self.root = libcalamares.globalstorage.value('rootMountPoint')
# Translate the entries in the config to the actions passed to sv-helper
self.services = dict()
self.services["enable"] = libcalamares.job.configuration.get('services', [])
self.services["disable"] = libcalamares.job.configuration.get('disable', [])
self.svDir = libcalamares.job.configuration['svDir']
self.runsvDir = libcalamares.job.configuration['runsvDir']
def make_failure_description(self, state, name, runlevel):
"""
Returns a generic "could not <foo>" failure message, specialized
for the action @p state and the specific service @p name in @p runlevel.
"""
if state == "enable":
description = _("Cannot enable service {name!s} to run-level {level!s}.")
elif state == "disable":
description = _("Cannot disable service {name!s} from run-level {level!s}.")
else:
description = _("Unknown service-action <code>{arg!s}</code> for service {name!s} in run-level {level!s}.")
return description.format(arg=state, name=name, level=runlevel)
def update(self, state):
"""
Call sv-helper for each service listed
in services for the given @p state.
"""
for svc in self.services.get(state, []):
if isinstance(svc, str):
name = svc
runlevel = "default"
mandatory = False
else:
name = svc["name"]
runlevel = svc.get("runlevel", "default")
mandatory = svc.get("mandatory", False)
service_path = self.root + self.svDir + "/" + name
runlevel_path = self.root + self.runsvDir + "/" + runlevel
src = self.svDir + "/" + name
dest = self.runsvDir + "/" + runlevel + "/"
if state == 'enable':
cmd = ["ln", "-sv", src, dest]
elif state == 'disable':
cmd = ["rm", "-rv", dest]
if exists(service_path):
if exists(runlevel_path):
ec = target_env_call(cmd)
if ec != 0:
warning("Cannot {} service {} to {}".format(state, name, runlevel))
warning("{} returned error code {!s}".format(cmd, ec))
if mandatory:
title = _("Cannot modify service")
diagnostic = _("<code>cmd {arg!s}</code> call in chroot returned error code {num!s}.").format(arg=state, num=ec)
return (title,
self.make_failure_description(state, name, runlevel) + " " + 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:
warning("Target service {} does not exist in {}.".format(name, self.svDir))
if mandatory:
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)
return (title,
self.make_failure_description(state, name, runlevel) + " " + diagnostic
)
def run(self):
"""Run the controller
"""
for state in ("enable", "disable"):
r = self.update(state)
if r is not None:
return r
def run():
"""
Setup services
"""
return RunitController().run()

View File

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

View File

@@ -0,0 +1,44 @@
# runit services module to modify service runlevels via symlinks in the chroot
#
# Services can be added (to any runlevel, or multiple runlevels) or deleted.
# 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,
# or a runlevel does not exist, it will be ignored and skipped; a warning is logged.
#
---
# svDir: holds the runit service directory location
svDir: /etc/runit/sv
# runsvDir: holds the runlevels directory location
runsvDir: /etc/runit/runsvdir
# services: a list of entries to **enable**
# disable: a list of entries to **disable**
#
# Each entry has three fields:
# - 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
# the service will result in installation failure, rather than just
# a warning. The default is false.
#
# an entry may also be a single string, which is interpreted
# as the name field (runlevel "default" is assumed then, and not-mandatory).
#
# # Example services and disable settings:
# # - add foo1 to default, but it must succeed
# # - add foo2 to nonetwork
# # - remove foo3 from default
# # - remove foo4 from default
# services:
# - name: foo1
# mandatory: true
# - name: foo2
# runlevel: nonetwork
# disable:
# - name: foo3
# - foo4
services: []
disable: []