flatpak: the package, Flathub with it, and the installations as tools (hq to-be 42 phase 2.9)
The package ships Flathub in /usr/share/flatpak/remotes.d, so the module declares no remote of its own and checks it instead. Eleven Go tools: list, runtimes, remotes (naming the desktop's duplicate user Flathub), updates, unused, disk usage, and install, remove, update and remove-unused, the system installation's acts through sudo -n and the account's without. uninstall --unused has no dry run, so flatpak_unused works it out from flatpak's own answers: an application's runtime and SDK, the extension points of what is used, and pins. Acts run as jobs inside the bundle, because an install outlasts a call.
This commit is contained in:
@@ -0,0 +1,213 @@
|
||||
// The flatpak module's tools (novox/hq research 027/02, 026/05): the applications and runtimes in
|
||||
// both installations, the remotes, pending updates, what nothing uses any more and the space it all
|
||||
// takes; and installing, removing and updating. A Go bundle the node's runtime launches over stdio
|
||||
// (ADR 0188, ADR 0193); it runs as the operator account. An act on the system installation goes
|
||||
// through `sudo -n`; one on the account's own installation does not.
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
stdio "git.novox.be/novox/mesh-sdk/go"
|
||||
)
|
||||
|
||||
var providedBy = map[string]string{
|
||||
"flatpak": "the flatpak package, which this module installs",
|
||||
"du": "the coreutils package",
|
||||
}
|
||||
|
||||
func main() {
|
||||
if err := stdio.Serve("", tools()); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
var installationArg = map[string]any{"type": "string", "enum": []string{"system", "user"},
|
||||
"description": "the system installation (default), or the account's own"}
|
||||
|
||||
func installationOf(args map[string]any, def string) (string, error) {
|
||||
i, err := optText(args, "installation", def)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if i == "" {
|
||||
return "", nil
|
||||
}
|
||||
return i, oneOf("installation", i, "system", "user")
|
||||
}
|
||||
|
||||
func refArg(args map[string]any, key string) (string, error) {
|
||||
r, err := text(args, key)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return r, checkRef(r)
|
||||
}
|
||||
|
||||
func tools() []stdio.Tool {
|
||||
return []stdio.Tool{
|
||||
{
|
||||
Name: "flatpak_list",
|
||||
Description: "The installed applications, in both installations or one: id, name, version, branch, origin, " +
|
||||
"installation and size. (r)",
|
||||
Input: map[string]any{"installation": installationArg},
|
||||
Run: func(args map[string]any) (any, error) {
|
||||
inst, err := installationOf(args, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return List("app", inst)
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "flatpak_runtimes",
|
||||
Description: "The installed runtimes and extensions, in both installations or one: id, branch, origin, installation and size. (r)",
|
||||
Input: map[string]any{"installation": installationArg},
|
||||
Run: func(args map[string]any) (any, error) {
|
||||
inst, err := installationOf(args, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return List("runtime", inst)
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "flatpak_remotes",
|
||||
Description: "The remotes of both installations, with how many installed refs come from each, and findings: " +
|
||||
"Flathub missing from the system installation, the same remote in both installations, a remote nothing " +
|
||||
"is installed from. (r)",
|
||||
Input: map[string]any{},
|
||||
Run: func(map[string]any) (any, error) { return Remotes() },
|
||||
},
|
||||
{
|
||||
Name: "flatpak_updates",
|
||||
Description: "What an update would change: each ref with a newer commit on its remote. Asks the remotes, so it needs the network. (r)",
|
||||
Input: map[string]any{"installation": installationArg},
|
||||
Run: func(args map[string]any) (any, error) {
|
||||
inst, err := installationOf(args, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return Updates(inst)
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "flatpak_unused",
|
||||
Description: "The runtimes and extensions no installed application needs any more, computed without changing " +
|
||||
"anything: a runtime is used when an application names it as its runtime or SDK, when it fills an " +
|
||||
"extension point of something used, or when it is pinned. With the space each takes. (r)",
|
||||
Input: map[string]any{},
|
||||
Run: func(map[string]any) (any, error) { return Unused() },
|
||||
},
|
||||
{
|
||||
Name: "flatpak_disk_usage",
|
||||
Description: "The space flatpak takes: each installation's directory on disk, and the applications and " +
|
||||
"runtimes by size, largest first. (r)",
|
||||
Input: map[string]any{},
|
||||
Run: func(map[string]any) (any, error) { return DiskUsage() },
|
||||
},
|
||||
{
|
||||
Name: "flatpak_install",
|
||||
Description: "Install an application or runtime from a remote (default flathub), in the system installation " +
|
||||
"(default) or the account's. Answers when finished, or after 18 s with a job to follow with flatpak_job. (a)",
|
||||
Input: map[string]any{
|
||||
"ref": map[string]any{"type": "string", "description": "an application id such as org.gimp.GIMP, or a full ref"},
|
||||
"remote": map[string]any{"type": "string", "description": "the remote (default flathub)"},
|
||||
"installation": installationArg,
|
||||
},
|
||||
Run: func(args map[string]any) (any, error) {
|
||||
ref, err := refArg(args, "ref")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
remote, err := optText(args, "remote", "flathub")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
inst, err := installationOf(args, "system")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return Install(ref, remote, inst)
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "flatpak_remove",
|
||||
Description: "Uninstall an application or runtime, keeping its data unless delete_data is set. Answers when finished, or with a job to follow. (a)",
|
||||
Input: map[string]any{
|
||||
"ref": map[string]any{"type": "string", "description": "the application id or ref"},
|
||||
"installation": installationArg,
|
||||
"delete_data": map[string]any{"type": "boolean", "description": "remove the application's data in the home too"},
|
||||
},
|
||||
Run: func(args map[string]any) (any, error) {
|
||||
ref, err := refArg(args, "ref")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
inst, err := installationOf(args, "system")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
del, err := optFlag(args, "delete_data", false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return Remove(ref, inst, del)
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "flatpak_update",
|
||||
Description: "Update one ref, or everything in an installation when no ref is given. Answers when finished, or with a job to follow. (a)",
|
||||
Input: map[string]any{
|
||||
"ref": map[string]any{"type": "string", "description": "the application id or ref (default all)"},
|
||||
"installation": installationArg,
|
||||
},
|
||||
Run: func(args map[string]any) (any, error) {
|
||||
ref, err := optText(args, "ref", "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if ref != "" {
|
||||
if err := checkRef(ref); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
inst, err := installationOf(args, "system")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return Update(ref, inst)
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "flatpak_remove_unused",
|
||||
Description: "Uninstall what flatpak itself finds unused in one installation (system by default). " +
|
||||
"flatpak_unused shows what that is beforehand. Answers when finished, or with a job to follow. (a)",
|
||||
Input: map[string]any{"installation": installationArg},
|
||||
Run: func(args map[string]any) (any, error) {
|
||||
inst, err := installationOf(args, "system")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return RemoveUnused(inst)
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "flatpak_job",
|
||||
Description: "A long act this module started: running or finished, its exit status and the end of its output. Without job, every act this process knows. (r)",
|
||||
Input: map[string]any{"job": map[string]any{"type": "string", "description": "the job id an act answered"}},
|
||||
Run: func(args map[string]any) (any, error) {
|
||||
id, err := optText(args, "job", "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if id == "" {
|
||||
return map[string]any{"jobs": listJobs()}, nil
|
||||
}
|
||||
return jobByID(id)
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user