Stage 6: server image with a console installer (0.4.0)
- server/ profile and build-iso.sh [desktop|server]; make iso-server, make qemu-server, run-qemu.sh --serial; login on tty and ttyS0 - das-server: SSH, chrony, NetworkManager/dhcpcd, Docker with Compose, nftables (closed except SSH, own table), fail2ban reading socklog, sshd without root passwords, Docker log rotation, tools - das-server-install: dialog installer in Ukrainian and English, or unattended with --config; GPT + Btrfs subvolumes, GRUB for UEFI and BIOS, serial console, SSH key with optional keys-only logins - das-install-common: mount-source and postinstall shared with Calamares - dsv: runit service manager (list, enable, disable, start, stop, restart, status, logs) with bash completion, also on the desktop - das-update split into a subpackage without GTK; the window and tray icon move to /usr/libexec/das/das-update-gui - das-snapper-setup enables dbus, which snapper needs - TODO: ISO size review with measured numbers and options Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
// Command das-update-gui is the desktop part of das-update, installed as
|
||||
// /usr/libexec/das/das-update-gui by das-tools. das-update starts it when a
|
||||
// display is available, so servers get das-update without GTK.
|
||||
//
|
||||
// das-update-gui window that lists and installs updates
|
||||
// das-update-gui --tray background check, shows a tray icon when updates are available
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"os"
|
||||
|
||||
"dasos/tools/internal/i18n"
|
||||
)
|
||||
|
||||
func main() {
|
||||
tray := flag.Bool("tray", false, "check for updates in the background")
|
||||
lang := flag.String("lang", "", "message language, e.g. uk_UA.UTF-8")
|
||||
flag.Parse()
|
||||
if *lang != "" {
|
||||
i18n.SetLang(*lang)
|
||||
}
|
||||
if *tray {
|
||||
os.Exit(runTray())
|
||||
}
|
||||
os.Exit(runWindow())
|
||||
}
|
||||
+9
-8
@@ -16,6 +16,7 @@ import (
|
||||
|
||||
"dasos/tools/internal/i18n"
|
||||
"dasos/tools/internal/system"
|
||||
"dasos/tools/internal/update"
|
||||
"dasos/tools/internal/xbps"
|
||||
)
|
||||
|
||||
@@ -265,20 +266,20 @@ func (w *window) startInstall() {
|
||||
for sc.Scan() {
|
||||
line := sc.Text()
|
||||
switch {
|
||||
case strings.HasPrefix(line, markStep):
|
||||
line = "\n==> " + strings.TrimPrefix(line, markStep)
|
||||
case strings.HasPrefix(line, markSnapshot):
|
||||
n, _ := strconv.Atoi(strings.TrimPrefix(line, markSnapshot))
|
||||
case strings.HasPrefix(line, update.MarkStep):
|
||||
line = "\n==> " + strings.TrimPrefix(line, update.MarkStep)
|
||||
case strings.HasPrefix(line, update.MarkSnapshot):
|
||||
n, _ := strconv.Atoi(strings.TrimPrefix(line, update.MarkSnapshot))
|
||||
glib.IdleAdd(func() { w.snapshot = n })
|
||||
line = i18n.T("update.snapshot", n)
|
||||
case line == markReboot:
|
||||
case line == update.MarkReboot:
|
||||
reboot = true
|
||||
continue
|
||||
case line == markUpToDate:
|
||||
case line == update.MarkUpToDate:
|
||||
upToDate = true
|
||||
continue
|
||||
case strings.HasPrefix(line, markError):
|
||||
failure = strings.TrimPrefix(line, markError)
|
||||
case strings.HasPrefix(line, update.MarkError):
|
||||
failure = strings.TrimPrefix(line, update.MarkError)
|
||||
}
|
||||
glib.IdleAdd(func() { w.appendLog(line + "\n") })
|
||||
}
|
||||
@@ -1,10 +1,13 @@
|
||||
// Command das-update updates Das OS with a snapper snapshot taken before
|
||||
// the update, so a broken update can be rolled back from the boot menu.
|
||||
//
|
||||
// das-update window that lists and installs updates
|
||||
// das-update the update window on a desktop, otherwise the same as --cli
|
||||
// das-update --tray background check, shows a tray icon when updates are available
|
||||
// das-update --cli the same in a terminal (servers, ssh); -y skips the question
|
||||
// das-update --cli update in a terminal (servers, ssh); -y skips the question
|
||||
// das-update --apply the privileged part, started by the window through pkexec
|
||||
//
|
||||
// The window and the tray icon are a separate program from das-tools
|
||||
// (guiPath), so this one has no GTK dependency.
|
||||
package main
|
||||
|
||||
import (
|
||||
@@ -42,27 +45,42 @@ func main() {
|
||||
case *cli:
|
||||
os.Exit(runCLI(*yes))
|
||||
case *tray:
|
||||
os.Exit(runTray())
|
||||
// Nothing to show without the desktop part
|
||||
if haveGUI() {
|
||||
execGUI()
|
||||
}
|
||||
default:
|
||||
os.Exit(runWindow())
|
||||
if haveGUI() && haveDisplay() {
|
||||
execGUI()
|
||||
}
|
||||
os.Exit(runCLI(*yes))
|
||||
}
|
||||
}
|
||||
|
||||
// Machine-readable lines that --apply prints for the window, among the
|
||||
// plain output of xbps.
|
||||
const (
|
||||
markStep = "@@step "
|
||||
markSnapshot = "@@snapshot "
|
||||
markReboot = "@@reboot"
|
||||
markUpToDate = "@@uptodate"
|
||||
markError = "@@error "
|
||||
)
|
||||
// guiPath is the window and tray icon program from das-tools.
|
||||
const guiPath = "/usr/libexec/das/das-update-gui"
|
||||
|
||||
func haveGUI() bool {
|
||||
_, err := os.Stat(guiPath)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func haveDisplay() bool {
|
||||
return os.Getenv("DISPLAY") != "" || os.Getenv("WAYLAND_DISPLAY") != ""
|
||||
}
|
||||
|
||||
// execGUI replaces this process with the graphical part, passing the
|
||||
// arguments on. It returns only when that fails.
|
||||
func execGUI() {
|
||||
err := syscall.Exec(guiPath, append([]string{guiPath}, os.Args[1:]...), os.Environ())
|
||||
fmt.Fprintln(os.Stderr, "das-update:", err)
|
||||
}
|
||||
|
||||
type markReporter struct{ w io.Writer }
|
||||
|
||||
func (r markReporter) Step(title string) { fmt.Fprintln(r.w, markStep+title) }
|
||||
func (r markReporter) Step(title string) { fmt.Fprintln(r.w, update.MarkStep+title) }
|
||||
func (r markReporter) Output() io.Writer { return r.w }
|
||||
func (r markReporter) Snapshot(n int) { fmt.Fprintf(r.w, "%s%d\n", markSnapshot, n) }
|
||||
func (r markReporter) Snapshot(n int) { fmt.Fprintf(r.w, "%s%d\n", update.MarkSnapshot, n) }
|
||||
|
||||
func runApply() int {
|
||||
if os.Geteuid() != 0 {
|
||||
@@ -74,13 +92,13 @@ func runApply() int {
|
||||
r := markReporter{os.Stdout}
|
||||
res, err := update.System().Apply(context.Background(), r)
|
||||
if err != nil {
|
||||
fmt.Println(markError + err.Error())
|
||||
fmt.Println(update.MarkError + err.Error())
|
||||
return 1
|
||||
}
|
||||
if len(res.Updates) == 0 {
|
||||
fmt.Println(markUpToDate)
|
||||
fmt.Println(update.MarkUpToDate)
|
||||
} else if res.Reboot {
|
||||
fmt.Println(markReboot)
|
||||
fmt.Println(update.MarkReboot)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package update
|
||||
|
||||
// Machine-readable lines that "das-update --apply" prints among the plain
|
||||
// output of xbps, for the window that runs it through pkexec.
|
||||
const (
|
||||
MarkStep = "@@step "
|
||||
MarkSnapshot = "@@snapshot "
|
||||
MarkReboot = "@@reboot"
|
||||
MarkUpToDate = "@@uptodate"
|
||||
MarkError = "@@error "
|
||||
)
|
||||
@@ -1,18 +1,19 @@
|
||||
# Template file for 'das-tools'
|
||||
# In-tree package: Go sources are in files/src (FILESDIR).
|
||||
pkgname=das-tools
|
||||
version=0.2.0
|
||||
version=0.3.0
|
||||
revision=1
|
||||
create_wrksrc=yes
|
||||
# Like build_style=go: the Go linker decides about PIE, xbps-src must not check it
|
||||
nopie=yes
|
||||
hostmakedepends="go pkg-config"
|
||||
makedepends="gtk+3-devel"
|
||||
depends="dbus libnotify polkit sudo xdg-user-dirs xdg-utils"
|
||||
short_desc="Das OS tools: das-update (updates with snapshots) and das-welcome"
|
||||
depends="das-update>=${version}_${revision} dbus libnotify polkit xdg-user-dirs xdg-utils"
|
||||
short_desc="Das OS desktop tools: update window and tray icon, das-welcome"
|
||||
maintainer="Das <anry.das@gmail.com>"
|
||||
license="MIT"
|
||||
homepage="https://git.das.org.ua/das/Das-OS"
|
||||
subpackages="das-update"
|
||||
|
||||
do_build() {
|
||||
cp -rL "${FILESDIR}/src/." .
|
||||
@@ -24,6 +25,7 @@ do_build() {
|
||||
|
||||
do_install() {
|
||||
vbin bin/das-update
|
||||
vinstall bin/das-update-gui 755 usr/libexec/das
|
||||
vbin bin/das-welcome
|
||||
vinstall "${FILESDIR}/data/das-update.desktop" 644 usr/share/applications
|
||||
vinstall "${FILESDIR}/data/das-welcome.desktop" 644 usr/share/applications
|
||||
@@ -32,3 +34,13 @@ do_install() {
|
||||
vinstall "${FILESDIR}/data/ua.org.das.update.policy" 644 usr/share/polkit-1/actions
|
||||
vlicense "${FILESDIR}/LICENSE"
|
||||
}
|
||||
|
||||
# Without GTK, for servers: the window and the tray icon stay in das-tools.
|
||||
das-update_package() {
|
||||
short_desc="Das OS updates with a snapper snapshot to roll back to"
|
||||
depends="sudo"
|
||||
pkg_install() {
|
||||
vmove usr/bin/das-update
|
||||
vmove usr/share/polkit-1
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user