Compare commits
	
		
			2 Commits
		
	
	
		
			1e9f95295d
			...
			fb4f0c5a69
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| fb4f0c5a69 | |||
| ae809d5d5e | 
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1,6 +1,4 @@ | ||||
| installer | ||||
| watchdog.service | ||||
| /cmd/install/static | ||||
| /cmd/watchdog/installer/static | ||||
| /watchdog | ||||
| /cmd/watchdog/watchdog | ||||
| xversion.go | ||||
|  | ||||
| @ -1,23 +0,0 @@ | ||||
| //go:generate go run -mod=vendor github.com/UnnoTed/fileb0x b0x.toml | ||||
| 
 | ||||
| // I'm prototyping this out to be useful for more than just watchdog | ||||
| // hence there are a few unnecessary things for the sake of the trying it out | ||||
| package main | ||||
| 
 | ||||
| type Config struct { | ||||
| 	Name                string `json:"name"` | ||||
| 	Desc                string `json:"desc"` | ||||
| 	URL                 string `json:"url"` | ||||
| 	Exec                string `json:"exec"` | ||||
| 	Args                string `json:"args"` | ||||
| 	User                string `json:"user"` | ||||
| 	Group               string `json:"group"` | ||||
| 	Production          bool   `json:"production"` | ||||
| 	PrivilegedPorts     bool   `json:"privileged_ports"` | ||||
| 	MultiuserProtection bool   `json:"multiuser_protection"` | ||||
| } | ||||
| 
 | ||||
| func main() { | ||||
| 
 | ||||
| 	install() | ||||
| } | ||||
| @ -1,7 +0,0 @@ | ||||
| package main | ||||
| 
 | ||||
| import "log" | ||||
| 
 | ||||
| func install() { | ||||
| 	log.Fatal("not yet implemented") | ||||
| } | ||||
| @ -1,60 +0,0 @@ | ||||
| // +build !windows !darwin | ||||
| package main | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"io/ioutil" | ||||
| 	"log" | ||||
| 	"text/template" | ||||
| 
 | ||||
| 	"git.rootprojects.org/root/watchdog.go/cmd/install/static" | ||||
| ) | ||||
| 
 | ||||
| func install() { | ||||
| 	b, err := static.ReadFile("dist/etc/systemd/system/watchdog.service.tmpl") | ||||
| 	if err != nil { | ||||
| 		log.Fatal(err) | ||||
| 		return | ||||
| 	} | ||||
| 	s := string(b) | ||||
| 
 | ||||
| 	j, err := static.ReadFile("dist/etc/systemd/system/watchdog.service.json") | ||||
| 	if err != nil { | ||||
| 		log.Fatal(err) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	//conf := map[string]string{} | ||||
| 	conf := &Config{} | ||||
| 	err = json.Unmarshal(j, &conf) | ||||
| 	if nil != err { | ||||
| 		log.Fatal(err) | ||||
| 		return | ||||
| 	} | ||||
| 	if "" == conf.Group { | ||||
| 		conf.Group = conf.User | ||||
| 	} | ||||
| 
 | ||||
| 	serviceFile := conf.Exec + ".service" | ||||
| 
 | ||||
| 	rw := &bytes.Buffer{} | ||||
| 	// not sure what the template name does, but whatever | ||||
| 	tmpl, err := template.New("service").Parse(s) | ||||
| 	if err != nil { | ||||
| 		log.Fatal(err) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	err = tmpl.Execute(rw, conf) | ||||
| 	if nil != err { | ||||
| 		log.Fatal(err) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	if err := ioutil.WriteFile(serviceFile, rw.Bytes(), 0644); err != nil { | ||||
| 		log.Fatalf("ioutil.WriteFile error: %v", err) | ||||
| 	} | ||||
| 	fmt.Printf("Wrote %q\n", serviceFile) | ||||
| } | ||||
							
								
								
									
										63
									
								
								cmd/watchdog/install.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								cmd/watchdog/install.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,63 @@ | ||||
| package main | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"log" | ||||
| 	"os" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"git.rootprojects.org/root/watchdog.go/cmd/watchdog/installer" | ||||
| ) | ||||
| 
 | ||||
| func install(binpath string, args []string) { | ||||
| 	system := true | ||||
| 	production := false | ||||
| 	config := "./config.json" | ||||
| 	for i := range os.Args { | ||||
| 		switch { | ||||
| 		case strings.HasSuffix(os.Args[i], "userspace"): | ||||
| 			system = false | ||||
| 		case strings.HasSuffix(os.Args[i], "production"): | ||||
| 			fmt.Println("Warning: production options don't work on all systems. If you have trouble, drop this first.") | ||||
| 			production = false | ||||
| 		case "-c" == os.Args[i]: | ||||
| 			if len(os.Args) <= i+1 { | ||||
| 				fmt.Println("-c requires a string path to the config file") | ||||
| 				os.Exit(1) | ||||
| 			} | ||||
| 			config = os.Args[i+1] | ||||
| 		} | ||||
| 	} | ||||
| 	/* | ||||
| 		j, err := static.ReadFile("dist/etc/systemd/system/watchdog.service.json") | ||||
| 		if err != nil { | ||||
| 			log.Fatal(err) | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		//conf := map[string]string{} | ||||
| 		conf := &Config{} | ||||
| 		err = json.Unmarshal(j, &conf) | ||||
| 		if nil != err { | ||||
| 			log.Fatal(err) | ||||
| 			return | ||||
| 		} | ||||
| 	*/ | ||||
| 	err := installer.Install(&installer.Config{ | ||||
| 		Title:               "Watchdog", | ||||
| 		Desc:                "Get notified when sites go down", | ||||
| 		URL:                 "https://git.rootprojects.org/root/watchdog.go", | ||||
| 		Name:                "watchdog", | ||||
| 		Exec:                "watchdog", | ||||
| 		Local:               "", | ||||
| 		System:              system, | ||||
| 		Restart:             true, | ||||
| 		Argv:                []string{"-c", config}, | ||||
| 		PrivilegedPorts:     false, | ||||
| 		MultiuserProtection: false, | ||||
| 		Production:          production, | ||||
| 	}) | ||||
| 	if nil != err { | ||||
| 		log.Fatal(err) | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										71
									
								
								cmd/watchdog/installer/dist/Library/LaunchDaemons/_rdns_.plist.tmpl
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								cmd/watchdog/installer/dist/Library/LaunchDaemons/_rdns_.plist.tmpl
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,71 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||||
| <plist version="1.0"> | ||||
| <dict> | ||||
| 	<key>Label</key> | ||||
| 	<string>{{ .Title }}</string> | ||||
| 	<key>ProgramArguments</key> | ||||
| 	<array> | ||||
| 		{{- if .Interpreter }} | ||||
| 		<string>{{ .Interpreter }}</string> | ||||
| 		{{- end }} | ||||
| 		<string>{{ .Local }}/opt/{{ .Name }}/{{ .Exec }}</string> | ||||
| 	  {{- if .Argv }} | ||||
| 		{{- range $arg := .Argv }} | ||||
| 		<string>{{ $arg }}</string> | ||||
| 		{{- end }} | ||||
| 	  {{- end }} | ||||
| 	</array> | ||||
| 	{{- if .Envs }} | ||||
| 	<key>EnvironmentVariables</key> | ||||
| 	<dict> | ||||
| 		{{- range $key, $value := .Envs }} | ||||
| 		<key>{{ $key }}</key> | ||||
| 		<string>{{ $value }}</string> | ||||
| 		{{- end }} | ||||
| 	</dict> | ||||
| 	{{- end }} | ||||
| 
 | ||||
| 	{{if .User -}} | ||||
| 	<key>UserName</key> | ||||
| 	<string>{{ .User }}</string> | ||||
| 	<key>GroupName</key> | ||||
| 	<string>{{ .Group }}</string> | ||||
| 	<key>InitGroups</key> | ||||
| 	<true/> | ||||
| 
 | ||||
| 	{{end -}} | ||||
| 	<key>RunAtLoad</key> | ||||
| 	<true/> | ||||
| 	{{ if .Restart -}} | ||||
| 	<key>KeepAlive</key> | ||||
| 	<true/> | ||||
| 	<!--dict> | ||||
| 		<key>Crashed</key> | ||||
| 		<true/> | ||||
| 		<key>NetworkState</key> | ||||
| 		<true/> | ||||
| 		<key>SuccessfulExit</key> | ||||
| 		<false/> | ||||
| 	</dict--> | ||||
| 
 | ||||
| 	{{ end -}} | ||||
| 	{{ if .Production -}} | ||||
| 	<key>SoftResourceLimits</key> | ||||
| 	<dict> | ||||
| 		<key>NumberOfFiles</key> | ||||
| 		<integer>8192</integer> | ||||
| 	</dict> | ||||
| 	<key>HardResourceLimits</key> | ||||
| 	<dict/> | ||||
| 
 | ||||
| 	{{ end -}} | ||||
| 	<key>WorkingDirectory</key> | ||||
| 	<string>{{ .Local }}/opt/{{ .Name }}</string> | ||||
| 
 | ||||
| 	<key>StandardErrorPath</key> | ||||
| 	<string>{{ .LogDir }}/{{ .Name }}.log</string> | ||||
| 	<key>StandardOutPath</key> | ||||
| 	<string>{{ .LogDir }}/{{ .Name }}.log</string> | ||||
| </dict> | ||||
| </plist> | ||||
| @ -1,18 +1,24 @@ | ||||
| # Pre-req | ||||
| # sudo adduser {{ .Exec }} --home /opt/{{ .Exec }} | ||||
| # sudo mkdir -p /opt/{{ .Exec }}/ /var/log/{{ .Exec }} | ||||
| # sudo chown -R {{ .Exec }}:{{ .Exec }} /opt/{{ .Exec }}/ /var/log/{{ .Exec }} | ||||
| # sudo mkdir -p {{ .Local }}/opt/{{ .Name }}/ {{ .Local }}/var/log/{{ .Name }} | ||||
| {{ if not .Local -}} | ||||
| {{ if .User -}} | ||||
| # sudo adduser {{ .User }} --home /opt/{{ .Name }} | ||||
| # sudo chown -R {{ .User }}:{{ .Group }} /opt/{{ .Name }}/ /var/log/{{ .Name }} | ||||
| {{- end }} | ||||
| {{- end }} | ||||
| 
 | ||||
| # Post-install | ||||
| # sudo systemctl daemon-reload | ||||
| # sudo systemctl restart {{ .Exec }}.service | ||||
| # sudo journalctl -xefu {{ .Exec }} | ||||
| # sudo systemctl {{ if .Local -}} --user {{- end }} daemon-reload | ||||
| # sudo systemctl {{ if .Local -}} --user {{- end }} restart {{ .Name }}.service | ||||
| # sudo journalctl {{ if .Local -}} --user {{- end }} -xefu {{ .Name }} | ||||
| 
 | ||||
| [Unit] | ||||
| Description={{ .Name }} - {{ .Desc }} | ||||
| Description={{ .Title }} - {{ .Desc }} | ||||
| Documentation={{ .URL }} | ||||
| {{ if not .Local -}} | ||||
| After=network-online.target | ||||
| Wants=network-online.target systemd-networkd-wait-online.service | ||||
| {{- end }} | ||||
| 
 | ||||
| [Service] | ||||
| # Restart on crash (bad signal), but not on 'clean' failure (error exit code) | ||||
| @ -28,8 +34,8 @@ User={{ .User }} | ||||
| Group={{ .Group }} | ||||
| 
 | ||||
| {{ end -}} | ||||
| WorkingDirectory=/opt/{{ .Exec }} | ||||
| ExecStart=/opt/{{ .Exec }}/{{ .Exec }} {{ .Args }} | ||||
| WorkingDirectory={{ .Local }}/opt/{{ .Name }} | ||||
| ExecStart={{if .Interpreter }}{{ .Interpreter }} {{ end }}{{ .Local }}/opt/{{ .Name }}/{{ .Name }} {{ .Args }} | ||||
| ExecReload=/bin/kill -USR1 $MAINPID | ||||
| 
 | ||||
| {{if .Production -}} | ||||
| @ -49,14 +55,14 @@ PrivateDevices=true | ||||
| ProtectHome=true | ||||
| # Make /usr, /boot, /etc and possibly some more folders read-only. | ||||
| ProtectSystem=full | ||||
| # ... except /opt/{{ .Exec }} because we want a place for the database | ||||
| # and /var/log/{{ .Exec }} because we want a place where logs can go. | ||||
| # ... except /opt/{{ .Name }} because we want a place for the database | ||||
| # and /var/log/{{ .Name }} because we want a place where logs can go. | ||||
| # This merely retains r/w access rights, it does not add any new. | ||||
| # Must still be writable on the host! | ||||
| ReadWriteDirectories=/opt/{{ .Exec }} /var/log/{{ .Exec }} | ||||
| ReadWriteDirectories=/opt/{{ .Name }} /var/log/{{ .Name }} | ||||
| 
 | ||||
| # Note: in v231 and above ReadWritePaths has been renamed to ReadWriteDirectories | ||||
| ; ReadWritePaths=/opt/{{ .Exec }} /var/log/{{ .Exec }} | ||||
| ; ReadWritePaths=/opt/{{ .Name }} /var/log/{{ .Name }} | ||||
| 
 | ||||
| {{ end -}} | ||||
| {{if .PrivilegedPorts -}} | ||||
| @ -75,4 +81,8 @@ NoNewPrivileges=true | ||||
| 
 | ||||
| {{ end -}} | ||||
| [Install] | ||||
| {{ if not .Local -}} | ||||
| WantedBy=multi-user.target | ||||
| {{- else -}} | ||||
| WantedBy=default.target | ||||
| {{- end }} | ||||
							
								
								
									
										23
									
								
								cmd/watchdog/installer/filesystem.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								cmd/watchdog/installer/filesystem.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,23 @@ | ||||
| package installer | ||||
| 
 | ||||
| // "A little copying is better than a little dependency" | ||||
| // These are here so that we don't need a dependency on http.FileSystem and http.File | ||||
| 
 | ||||
| import ( | ||||
| 	"io" | ||||
| 	"os" | ||||
| ) | ||||
| 
 | ||||
| // Same as http.FileSystem | ||||
| type FileSystem interface { | ||||
| 	Open(name string) (File, error) | ||||
| } | ||||
| 
 | ||||
| // Same as http.File | ||||
| type File interface { | ||||
| 	io.Closer | ||||
| 	io.Reader | ||||
| 	io.Seeker | ||||
| 	Readdir(count int) ([]os.FileInfo, error) | ||||
| 	Stat() (os.FileInfo, error) | ||||
| } | ||||
							
								
								
									
										68
									
								
								cmd/watchdog/installer/install.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								cmd/watchdog/installer/install.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,68 @@ | ||||
| //go:generate go run -mod=vendor github.com/UnnoTed/fileb0x b0x.toml | ||||
| 
 | ||||
| // I'm prototyping this out to be useful for more than just watchdog | ||||
| // hence there are a few unnecessary things for the sake of the trying it out | ||||
| package installer | ||||
| 
 | ||||
| import ( | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"strings" | ||||
| ) | ||||
| 
 | ||||
| type Config struct { | ||||
| 	Title               string            `json:"title"` | ||||
| 	Name                string            `json:"name"` | ||||
| 	Desc                string            `json:"desc"` | ||||
| 	URL                 string            `json:"url"` | ||||
| 	Interpreter         string            `json:"interpreter"` // i.e. node, python | ||||
| 	Exec                string            `json:"exec"` | ||||
| 	Argv                []string          `json:"argv"` | ||||
| 	Args                string            `json:"-"` | ||||
| 	Envs                map[string]string `json:"envs"` | ||||
| 	User                string            `json:"user"` | ||||
| 	Group               string            `json:"group"` | ||||
| 	home                string            `json:"-"` | ||||
| 	Local               string            `json:"local"` | ||||
| 	LogDir              string            `json:"-"` | ||||
| 	System              bool              `json:"system"` | ||||
| 	Restart             bool              `json:"restart"` | ||||
| 	Production          bool              `json:"production"` | ||||
| 	PrivilegedPorts     bool              `json:"privileged_ports"` | ||||
| 	MultiuserProtection bool              `json:"multiuser_protection"` | ||||
| } | ||||
| 
 | ||||
| func Install(c *Config) error { | ||||
| 	if "" == c.Exec { | ||||
| 		c.Exec = c.Name | ||||
| 	} | ||||
| 	c.Args = strings.Join(c.Argv, " ") | ||||
| 
 | ||||
| 	// TODO handle non-system installs | ||||
| 	// * ~/.local/opt/watchdog/watchdog | ||||
| 	// * ~/.local/share/watchdog/var/log/ | ||||
| 	// * ~/.config/watchdog/watchdog.json | ||||
| 	if !c.System { | ||||
| 		home, err := os.UserHomeDir() | ||||
| 		if nil != err { | ||||
| 			return err | ||||
| 		} | ||||
| 		c.home = home | ||||
| 		c.Local = filepath.Join(c.home, ".local") | ||||
| 		c.LogDir = filepath.Join(c.home, ".local", "share", c.Name, "var", "log") | ||||
| 	} else { | ||||
| 		c.LogDir = "/var/log/" + c.Name | ||||
| 	} | ||||
| 
 | ||||
| 	err := install(c) | ||||
| 	if nil != err { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	err = os.MkdirAll(c.LogDir, 0750) | ||||
| 	if nil != err { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										64
									
								
								cmd/watchdog/installer/install_darwin.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								cmd/watchdog/installer/install_darwin.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,64 @@ | ||||
| package installer | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"fmt" | ||||
| 	"io/ioutil" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"strings" | ||||
| 	"text/template" | ||||
| 
 | ||||
| 	"git.rootprojects.org/root/watchdog.go/cmd/watchdog/installer/static" | ||||
| ) | ||||
| 
 | ||||
| func install(c *Config) error { | ||||
| 	// Darwin-specific config options | ||||
| 	if c.PrivilegedPorts { | ||||
| 		if !c.System { | ||||
| 			return fmt.Errorf("You must use root-owned LaunchDaemons (not user-owned LaunchAgents) to use priveleged ports on OS X") | ||||
| 		} | ||||
| 	} | ||||
| 	plistDir := "/Library/LaunchDaemons/" | ||||
| 	if !c.System { | ||||
| 		plistDir = filepath.Join(c.home, "Library/LaunchAgents") | ||||
| 	} | ||||
| 
 | ||||
| 	// Check paths first | ||||
| 	err := os.MkdirAll(filepath.Dir(plistDir), 0750) | ||||
| 	if nil != err { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	// Create service file from template | ||||
| 	b, err := static.ReadFile("dist/Library/LaunchDaemons/_rdns_.plist.tmpl") | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	s := string(b) | ||||
| 	rw := &bytes.Buffer{} | ||||
| 	// not sure what the template name does, but whatever | ||||
| 	tmpl, err := template.New("service").Parse(s) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	err = tmpl.Execute(rw, c) | ||||
| 	if nil != err { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	// Write the file out | ||||
| 	// TODO rdns | ||||
| 	plistName := c.Name + ".plist" | ||||
| 	plistPath := filepath.Join(plistDir, plistName) | ||||
| 	if err := ioutil.WriteFile(plistPath, rw.Bytes(), 0644); err != nil { | ||||
| 		fmt.Println("Use 'sudo' to install as a privileged system service.") | ||||
| 		fmt.Println("Use '--userspace' to install as an user service.") | ||||
| 		return fmt.Errorf("ioutil.WriteFile error: %v", err) | ||||
| 	} | ||||
| 	fmt.Printf("Installed. To start '%s' run the following:\n", c.Name) | ||||
| 	// TODO template config file | ||||
| 	fmt.Printf("\tlaunchctl load -w %s\n", strings.Replace(plistPath, c.home, "~", 1)) | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										65
									
								
								cmd/watchdog/installer/install_linux.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								cmd/watchdog/installer/install_linux.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,65 @@ | ||||
| package installer | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"fmt" | ||||
| 	"io/ioutil" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"text/template" | ||||
| 
 | ||||
| 	"git.rootprojects.org/root/watchdog.go/cmd/watchdog/installer/static" | ||||
| ) | ||||
| 
 | ||||
| func install(c *Config) error { | ||||
| 	// Linux-specific config options | ||||
| 	if c.System { | ||||
| 		if "" == c.User { | ||||
| 			c.User = "root" | ||||
| 		} | ||||
| 	} | ||||
| 	if "" == c.Group { | ||||
| 		c.Group = c.User | ||||
| 	} | ||||
| 	serviceDir := "/etc/systemd/system/" | ||||
| 
 | ||||
| 	// Check paths first | ||||
| 	serviceName := c.Name + ".service" | ||||
| 	if !c.System { | ||||
| 		// Not sure which of these it's supposed to be... | ||||
| 		// * ~/.local/share/systemd/user/watchdog.service | ||||
| 		// * ~/.config/systemd/user/watchdog.service | ||||
| 		// https://wiki.archlinux.org/index.php/Systemd/User | ||||
| 		serviceDir = filepath.Join(c.home, ".local/share/systemd/user") | ||||
| 	} | ||||
| 	err = os.MkdirAll(filepath.Dir(serviceDir), 0750) | ||||
| 	if nil != err { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	// Create service file from template | ||||
| 	b, err := static.ReadFile("dist/etc/systemd/system/_name_.service.tmpl") | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	s := string(b) | ||||
| 	rw := &bytes.Buffer{} | ||||
| 	// not sure what the template name does, but whatever | ||||
| 	tmpl, err := template.New("service").Parse(s) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	err = tmpl.Execute(rw, c) | ||||
| 	if nil != err { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	// Write the file out | ||||
| 	servicePath := filepath.Join(serviceDir, serviceName) | ||||
| 	if err := ioutil.WriteFile(servicePath, rw.Bytes(), 0644); err != nil { | ||||
| 		return fmt.Errorf("ioutil.WriteFile error: %v", err) | ||||
| 	} | ||||
| 	fmt.Printf("Wrote %q\n", servicePath) | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| @ -1,7 +1,7 @@ | ||||
| package main | ||||
| package installer | ||||
| 
 | ||||
| import ( | ||||
| 	"log" | ||||
| 	"fmt" | ||||
| 	//"golang.org/x/sys/windows" | ||||
| ) | ||||
| 
 | ||||
| @ -11,7 +11,7 @@ import ( | ||||
| // https://stackoverflow.com/questions/27366298/check-if-application-is-running-as-administrator-in-golang | ||||
| // https://www.reddit.com/r/golang/comments/53dthc/way_to_detect_if_the_programs_running_with/ | ||||
| // https://play.golang.org/p/bBtRZrk4_p | ||||
| func install() { | ||||
| func install(c *Config) error { | ||||
| 	//token := windows.Token(0) | ||||
| 	log.Fatal("not yet implemented") | ||||
| 	return fmt.Errorf("not yet implemented") | ||||
| } | ||||
							
								
								
									
										7
									
								
								cmd/watchdog/installer/unknownos.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								cmd/watchdog/installer/unknownos.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| // +build !windows,!linux,!darwin | ||||
| 
 | ||||
| package installer | ||||
| 
 | ||||
| func install(c *Config) error { | ||||
| 	return nil, nil | ||||
| } | ||||
							
								
								
									
										29
									
								
								cmd/watchdog/installer/watchdog.service
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								cmd/watchdog/installer/watchdog.service
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | ||||
| # Pre-req | ||||
| # sudo adduser watchdog --home /opt/watchdog | ||||
| # sudo mkdir -p /opt/watchdog/ /var/log/watchdog | ||||
| # sudo chown -R watchdog:watchdog /opt/watchdog/ /var/log/watchdog | ||||
| 
 | ||||
| [Unit] | ||||
| Description=Watchdog - Get notified when sites go down | ||||
| Documentation=https://git.rootprojects.org/root/watchdog.go | ||||
| After=network-online.target | ||||
| Wants=network-online.target systemd-networkd-wait-online.service | ||||
| 
 | ||||
| [Service] | ||||
| # Restart on crash (bad signal), but not on 'clean' failure (error exit code) | ||||
| # Allow up to 3 restarts within 10 seconds | ||||
| # (it's unlikely that a user or properly-running script will do this) | ||||
| Restart=on-abnormal | ||||
| StartLimitInterval=10 | ||||
| StartLimitBurst=3 | ||||
| 
 | ||||
| # User and group the process will run as | ||||
| User=root | ||||
| Group=root | ||||
| 
 | ||||
| WorkingDirectory=/opt/watchdog | ||||
| ExecStart=/opt/watchdog -c ./config.json | ||||
| ExecReload=/bin/kill -USR1 $MAINPID | ||||
| 
 | ||||
| [Install] | ||||
| WantedBy=multi-user.target | ||||
							
								
								
									
										15
									
								
								cmd/watchdog/installer/whoami.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								cmd/watchdog/installer/whoami.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
| // +build !windows | ||||
| 
 | ||||
| package installer | ||||
| 
 | ||||
| import "os/user" | ||||
| 
 | ||||
| func IsAdmin() bool { | ||||
| 	u, err := user.Current() | ||||
| 	if nil != err { | ||||
| 		return false | ||||
| 	} | ||||
| 
 | ||||
| 	// not quite, but close enough for now | ||||
| 	return "0" == u.Uid | ||||
| } | ||||
							
								
								
									
										26
									
								
								cmd/watchdog/installer/whoami_windows.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								cmd/watchdog/installer/whoami_windows.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | ||||
| package installer | ||||
| 
 | ||||
| import "os/user" | ||||
| 
 | ||||
| func IsAdmin() { | ||||
| 	u, err := user.Current() | ||||
| 	if nil != err { | ||||
| 		return false | ||||
| 	} | ||||
| 
 | ||||
| 	// https://support.microsoft.com/en-us/help/243330/well-known-security-identifiers-in-windows-operating-systems | ||||
| 	// not quite, but close enough for now | ||||
| 	// BUILTIN\ADMINISTRATORS | ||||
| 	if "S-1-5-32-544" == u.Uid || "S-1-5-32-544" == u.Gid { | ||||
| 		return true | ||||
| 	} | ||||
| 
 | ||||
| 	ids := u.GroupIds() | ||||
| 	for i := range ids { | ||||
| 		if "S-1-5-32-544" == ids[i] { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return false | ||||
| } | ||||
| @ -11,7 +11,7 @@ import ( | ||||
| 	"os" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	watchdog "git.rootprojects.org/root/watchdog.go" | ||||
| 	"git.rootprojects.org/root/watchdog.go" | ||||
| ) | ||||
| 
 | ||||
| var GitRev, GitVersion, GitTimestamp string | ||||
| @ -21,6 +21,7 @@ func usage() { | ||||
| } | ||||
| 
 | ||||
| func main() { | ||||
| 	fmt.Println("Watchdog " + GitVersion) | ||||
| 	for i := range os.Args { | ||||
| 		switch { | ||||
| 		case strings.HasSuffix(os.Args[i], "version"): | ||||
| @ -31,6 +32,13 @@ func main() { | ||||
| 		case strings.HasSuffix(os.Args[i], "help"): | ||||
| 			usage() | ||||
| 			os.Exit(0) | ||||
| 		case os.Args[i] == "install": | ||||
| 			args := []string{} | ||||
| 			if len(os.Args) > i+1 { | ||||
| 				args = os.Args[i+1:] | ||||
| 			} | ||||
| 			install(os.Args[0], args) | ||||
| 			os.Exit(0) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										10
									
								
								cmd/watchdog/watchdog.service.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								cmd/watchdog/watchdog.service.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | ||||
| { | ||||
| 	"name": "Watchdog", | ||||
| 	"desc": "Get notified when sites go down", | ||||
| 	"url": "https://git.rootprojects.org/root/watchdog.go", | ||||
| 	"exec": "watchdog", | ||||
| 	"args": "-c ./config.json", | ||||
| 	"user": "root", | ||||
| 	"privileged_ports": false, | ||||
| 	"multiuser_protection": false | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user