diff --git a/.scripts/packages.list b/.scripts/packages.list index d2043fcd..b59a158c 100644 --- a/.scripts/packages.list +++ b/.scripts/packages.list @@ -18,6 +18,7 @@ * + hash * + httputil * - initsystem +* ! initsystem/sdnotify * + jsonutil * + knf * + knf/united diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b928b9f..86006ced 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ ## Changelog +### 12.121.0 + +- `[initsystem/sdnotify]` Added new package for sending messages to systemd +- `[support/deps]` Updated for compatibility with the latest version of [depsy](https://kaos.sh/depsy) +- `[terminal/tty]` Improved check for systemd + ### 12.120.0 - `[knf]` Added methods `Alias` and `Config.Alias` diff --git a/README.md b/README.md index ba807315..e0dff8b9 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,7 @@ go get -u github.com/essentialkaos/ek/v12 * [`hash`](https://kaos.sh/g/ek.v12/hash) — Package hash contains different hash algorithms and utilities * [`httputil`](https://kaos.sh/g/ek.v12/httputil) — Package provides methods for working with HTTP request/responses * [`initsystem`](https://kaos.sh/g/ek.v12/initsystem) — Package provides methods for working with different init systems (sysv, upstart, systemd) +* [`initsystem`](https://kaos.sh/g/ek.v12/initsystem/sdnotify) — Package provides methods methods for sending [notifications to systemd](https://www.freedesktop.org/software/systemd/man/latest/sd_notify.html#Well-known%20assignments) * [`jsonutil`](https://kaos.sh/g/ek.v12/jsonutil) — Package provides methods for working with JSON data * [`knf`](https://kaos.sh/g/ek.v12/knf) — Package provides methods for working with configuration files in [KNF format](https://kaos.sh/knf-spec) * [`knf/united`](https://kaos.sh/g/ek.v12/knf/united) — Package provides united configuration (_knf + options + environment variables_) diff --git a/ek.go b/ek.go index b217a9ba..11292799 100644 --- a/ek.go +++ b/ek.go @@ -21,7 +21,7 @@ import ( // ////////////////////////////////////////////////////////////////////////////////// // // VERSION is current ek package version -const VERSION = "12.120.0" +const VERSION = "12.121.0" // ////////////////////////////////////////////////////////////////////////////////// // diff --git a/go.mod b/go.mod index a06b6bd7..74e146a0 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.18 require ( github.com/essentialkaos/check v1.4.0 - github.com/essentialkaos/depsy v1.1.0 + github.com/essentialkaos/depsy v1.3.0 github.com/essentialkaos/go-linenoise/v3 v3.6.0 golang.org/x/crypto v0.22.0 golang.org/x/sys v0.19.0 diff --git a/go.sum b/go.sum index 05d7b082..c8d358e6 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/essentialkaos/check v1.4.0 h1:kWdFxu9odCxUqo1NNFNJmguGrDHgwi3A8daXX1nkuKk= github.com/essentialkaos/check v1.4.0/go.mod h1:LMKPZ2H+9PXe7Y2gEoKyVAwUqXVgx7KtgibfsHJPus0= -github.com/essentialkaos/depsy v1.1.0 h1:U6dp687UkQwXlZU17Hg2KMxbp3nfZAoZ8duaeUFYvJI= -github.com/essentialkaos/depsy v1.1.0/go.mod h1:kpiTAV17dyByVnrbNaMcZt2jRwvuXClUYOzpyJQwtG8= +github.com/essentialkaos/depsy v1.3.0 h1:CN7bRgBU2jGTHSkg/Sh38eDUn7cvmaTp2sxFt2HpFeU= +github.com/essentialkaos/depsy v1.3.0/go.mod h1:kpiTAV17dyByVnrbNaMcZt2jRwvuXClUYOzpyJQwtG8= github.com/essentialkaos/go-linenoise/v3 v3.6.0 h1:deLcrodtLIkcHjNyW/MoQpjznXPVqvwlspxk7s/5YeY= github.com/essentialkaos/go-linenoise/v3 v3.6.0/go.mod h1:Fi6kLdZdURkXHpRkIiX2nFGORNv81CXTZ2Mn72i/cn0= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= diff --git a/initsystem/sdnotify/example_test.go b/initsystem/sdnotify/example_test.go new file mode 100644 index 00000000..36a94d13 --- /dev/null +++ b/initsystem/sdnotify/example_test.go @@ -0,0 +1,19 @@ +package sdnotify + +// ////////////////////////////////////////////////////////////////////////////////// // +// // +// Copyright (c) 2024 ESSENTIAL KAOS // +// Apache License, Version 2.0 // +// // +// ////////////////////////////////////////////////////////////////////////////////// // + +func ExampleConnect() { + err := Connect() + + if err != nil { + panic(err.Error()) + } + + Status("Loading data %d%%", 50) + Ready() +} diff --git a/initsystem/sdnotify/sdnotify_linux.go b/initsystem/sdnotify/sdnotify_linux.go new file mode 100644 index 00000000..03214935 --- /dev/null +++ b/initsystem/sdnotify/sdnotify_linux.go @@ -0,0 +1,89 @@ +// Package sdnotify provides methods for sending notifications to systemd +package sdnotify + +// ////////////////////////////////////////////////////////////////////////////////// // +// // +// Copyright (c) 2024 ESSENTIAL KAOS // +// Apache License, Version 2.0 // +// // +// ////////////////////////////////////////////////////////////////////////////////// // + +import ( + "fmt" + "net" + "os" +) + +// ////////////////////////////////////////////////////////////////////////////////// // + +var ( + ErrNoSocket = fmt.Errorf("NOTIFY_SOCKET is empty") + ErrNotConnected = fmt.Errorf("Not connected to socket") +) + +// ////////////////////////////////////////////////////////////////////////////////// // + +var conn net.Conn + +// ////////////////////////////////////////////////////////////////////////////////// // + +// Connect connects systemd to socket +func Connect() error { + var err error + + socket := os.Getenv("NOTIFY_SOCKET") + + if err != nil { + return ErrNoSocket + } + + conn, err = net.Dial("unixgram", socket) + + if err != nil { + return fmt.Errorf("Can't connect to socket: %w", err) + } + + return nil +} + +// Notify sends provided message to systemd +func Notify(msg string) error { + if conn == nil { + return ErrNotConnected + } + + _, err := fmt.Fprint(conn, msg) + + return err +} + +// Ready sends READY message to systemd +func Ready() error { + return Notify("READY=1") +} + +// Reloading sends RELOADING message to systemd +func Reloading() error { + return Notify("RELOADING=1") +} + +// Stopping sends STOPPING message to systemd +func Stopping() error { + return Notify("STOPPING=1") +} + +// MainPID sends MAINPID message with PID to systemd +func MainPID(pid int) error { + return Notify(fmt.Sprintf("MAINPID=%d", pid)) +} + +// ExtendTimeout sends EXTEND_TIMEOUT_USEC message to systemd +func ExtendTimeout(sec float64) error { + usec := uint(sec * 1_000_000) + return Notify(fmt.Sprintf("EXTEND_TIMEOUT_USEC=%d", usec)) +} + +// Status sends status message to systemd +func Status(format string, a ...any) error { + return Notify(fmt.Sprintf(format, a...)) +} diff --git a/initsystem/sdnotify/sdnotify_stubs.go b/initsystem/sdnotify/sdnotify_stubs.go new file mode 100644 index 00000000..a9bfce4a --- /dev/null +++ b/initsystem/sdnotify/sdnotify_stubs.go @@ -0,0 +1,54 @@ +//go:build windows || darwin +// +build windows darwin + +// Package sdnotify provides methods for sending notifications to systemd +package sdnotify + +// ////////////////////////////////////////////////////////////////////////////////// // +// // +// Copyright (c) 2024 ESSENTIAL KAOS // +// Apache License, Version 2.0 // +// // +// ////////////////////////////////////////////////////////////////////////////////// // + +// ////////////////////////////////////////////////////////////////////////////////// // + +// ❗ Connect connects systemd to socket +func Connect() error { + panic("UNSUPPORTED") +} + +// ❗ Notify sends provided message to systemd +func Notify(msg string) error { + panic("UNSUPPORTED") +} + +// ❗ Ready sends READY message to systemd +func Ready() error { + panic("UNSUPPORTED") +} + +// ❗ Reloading sends RELOADING message to systemd +func Reloading() error { + panic("UNSUPPORTED") +} + +// ❗ Stopping sends STOPPING message to systemd +func Stopping() error { + panic("UNSUPPORTED") +} + +// ❗ MainPID sends MAINPID message with PID to systemd +func MainPID(pid int) error { + panic("UNSUPPORTED") +} + +// ❗ ExtendTimeout sends EXTEND_TIMEOUT_USEC message to systemd +func ExtendTimeout(sec float64) error { + panic("UNSUPPORTED") +} + +// ❗ Status sends status message to systemd +func Status(format string, a ...any) error { + panic("UNSUPPORTED") +} diff --git a/support/deps/deps.go b/support/deps/deps.go index 618c6f1e..d2277845 100644 --- a/support/deps/deps.go +++ b/support/deps/deps.go @@ -23,7 +23,7 @@ func Extract(gomod []byte) []support.Dep { for _, dep := range depsy.Extract(gomod, false) { result = append(result, support.Dep{ Version: dep.Version, - Path: dep.Path, + Path: dep.PrettyPath(), Extra: dep.Extra, }) } diff --git a/support/support_nix.go b/support/support_nix.go index 82b3eada..23fa2678 100644 --- a/support/support_nix.go +++ b/support/support_nix.go @@ -460,9 +460,10 @@ func (i *Info) printDependencies() { fmtutil.Separator(false, "DEPENDENCIES") for _, dep := range i.Deps { - if dep.Extra == "" { + switch dep.Extra { + case "": fmtc.Printf(" {s}%8s{!} %s\n", dep.Version, dep.Path) - } else { + default: fmtc.Printf(" {s}%8s{!} %s {s-}(%s){!}\n", dep.Version, dep.Path, dep.Extra) } } diff --git a/terminal/tty/tty_posix.go b/terminal/tty/tty_posix.go index f3adb6c7..f25174b8 100644 --- a/terminal/tty/tty_posix.go +++ b/terminal/tty/tty_posix.go @@ -46,8 +46,7 @@ func IsFakeTTY() bool { // IsSystemd returns true if process started by systemd func IsSystemd() bool { - return os.Getenv("INVOCATION_ID") != "" || - os.Getenv("SYSTEMCTL_IGNORE_DEPENDENCIES") != "" + return os.Getppid() == 1 } // ////////////////////////////////////////////////////////////////////////////////// // diff --git a/terminal/tty/tty_test.go b/terminal/tty/tty_test.go index 28e22c94..27e3c975 100644 --- a/terminal/tty/tty_test.go +++ b/terminal/tty/tty_test.go @@ -48,12 +48,7 @@ func (s *TTYSuite) TestIsTTY(c *C) { } func (s *TTYSuite) TestIsSystemd(c *C) { - os.Setenv("INVOCATION_ID", "") - os.Setenv("SYSTEMCTL_IGNORE_DEPENDENCIES", "") - c.Assert(IsSystemd(), Equals, false) - os.Setenv("INVOCATION_ID", "5d0149bfa2c34b79bccb13074001eb20") - c.Assert(IsSystemd(), Equals, true) - os.Setenv("INVOCATION_ID", "") + IsSystemd() } func (s *TTYSuite) TestIsTMUX(c *C) {