File: quickstart-linux.go

package info (click to toggle)
acmetool 0.2.2-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 792 kB
  • sloc: sh: 349; makefile: 105
file content (107 lines) | stat: -rw-r--r-- 3,176 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// +build linux

package cli

import (
	"fmt"
	sddbus "github.com/coreos/go-systemd/dbus"
	sdunit "github.com/coreos/go-systemd/unit"
	"github.com/hlandau/acmetool/interaction"
	"gopkg.in/hlandau/svcutils.v1/exepath"
	"gopkg.in/hlandau/svcutils.v1/systemd" // coreos/go-systemd/util requires cgo
	"io"
	"os"
)

func promptSystemd() {
	if !systemd.IsRunningSystemd() {
		log.Debugf("not running systemd")
		return
	}

	log.Debug("connecting to systemd")
	conn, err := sddbus.New()
	if err != nil {
		log.Errore(err, "connect to systemd")
		return
	}

	defer conn.Close()
	log.Debug("connected")

	props, err := conn.GetUnitProperties("acmetool-redirector.service")
	if err != nil {
		log.Errore(err, "systemd GetUnitProperties")
		return
	}

	if props["LoadState"].(string) != "not-found" {
		log.Info("acmetool-redirector.service unit already installed, skipping")
		return
	}

	r, err := interaction.Auto.Prompt(&interaction.Challenge{
		Title: "Install Redirector as systemd Service?",
		Body: `Would you like acmetool to automatically install the redirector as a systemd service?

The service name will be acmetool-redirector.`,
		ResponseType: interaction.RTYesNo,
		UniqueID:     "acmetool-quickstart-install-redirector-systemd",
	})
	log.Fatale(err, "interaction")

	if r.Cancelled {
		return
	}

	username, err := determineAppropriateUsername()
	if err != nil {
		log.Errore(err, "determine appropriate username")
		return
	}

	f, err := os.OpenFile("/etc/systemd/system/acmetool-redirector.service", os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0644)
	if err != nil {
		log.Errore(err, "acmetool-redirector.service unit file already exists?")
		return
	}
	defer f.Close()

	rdr := sdunit.Serialize([]*sdunit.UnitOption{
		sdunit.NewUnitOption("Unit", "Description", "acmetool HTTP redirector"),
		sdunit.NewUnitOption("Service", "Type", "notify"),
		sdunit.NewUnitOption("Service", "ExecStart", exepath.Abs+` redirector --service.uid=`+username),
		sdunit.NewUnitOption("Service", "Restart", "always"),
		sdunit.NewUnitOption("Service", "RestartSec", "30"),
		sdunit.NewUnitOption("Install", "WantedBy", "multi-user.target"),
	})

	_, err = io.Copy(f, rdr)
	if err != nil {
		log.Errore(err, "cannot write unit file")
		return
	}

	f.Close()
	err = conn.Reload() // softfail
	log.Warne(err, "systemctl daemon-reload failed")

	_, _, err = conn.EnableUnitFiles([]string{"acmetool-redirector.service"}, false, false)
	log.Errore(err, "failed to enable unit acmetool-redirector.service")

	_, err = conn.StartUnit("acmetool-redirector.service", "replace", nil)
	log.Errore(err, "failed to start acmetool-redirector")
	resultStr := "The acmetool-redirector service was successfully started."
	if err != nil {
		resultStr = "The acmetool-redirector service WAS NOT successfully started. You may have a web server listening on port 80. You will need to troubleshoot this yourself."
	}

	_, err = interaction.Auto.Prompt(&interaction.Challenge{
		Title: "systemd Service Installation Complete",
		Body: fmt.Sprintf(`acmetool-redirector has been installed as a systemd service.
    
    %s`, resultStr),
		UniqueID: "acmetool-quickstart-complete",
	})
	log.Errore(err, "interaction")
}