WIP builds on windows
This commit is contained in:
parent
c9b6fd62a0
commit
b317446e7e
|
@ -1,5 +1,6 @@
|
||||||
/cmd/watchdog/installer/static
|
/cmd/watchdog/installer/static
|
||||||
/watchdog
|
/watchdog
|
||||||
/cmd/watchdog/watchdog
|
/cmd/watchdog/watchdog
|
||||||
|
watchdog.exe
|
||||||
xversion.go
|
xversion.go
|
||||||
*.json
|
*.json
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
// Package installer can be used cross-platform to install apps
|
||||||
|
// as either userspace or system services for fairly simple applications.
|
||||||
|
// This is not intended for complex installers.
|
||||||
|
//
|
||||||
|
// 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
|
|
@ -1,19 +1,19 @@
|
||||||
package installer
|
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 (
|
import (
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Same as http.FileSystem
|
// "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
|
||||||
|
|
||||||
|
// FileSystem is the same as http.FileSystem
|
||||||
type FileSystem interface {
|
type FileSystem interface {
|
||||||
Open(name string) (File, error)
|
Open(name string) (File, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Same as http.File
|
// File is the same as http.File
|
||||||
type File interface {
|
type File interface {
|
||||||
io.Closer
|
io.Closer
|
||||||
io.Reader
|
io.Reader
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
//go:generate go run -mod=vendor github.com/UnnoTed/fileb0x b0x.toml
|
//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
|
package installer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -10,6 +8,47 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Config should describe the service well-enough for it to
|
||||||
|
// run on Mac, Linux, and Windows.
|
||||||
|
//
|
||||||
|
// &Config{
|
||||||
|
// // A human-friendy name
|
||||||
|
// Title: "Foobar App",
|
||||||
|
// // A computer-friendly name
|
||||||
|
// Name: "foobar-app",
|
||||||
|
// // A name for OS X plist
|
||||||
|
// ReverseDNS: "com.example.foobar-app",
|
||||||
|
// // A human-friendly description
|
||||||
|
// Desc: "Foobar App",
|
||||||
|
// // The app /service homepage
|
||||||
|
// URL: "https://example.com/foobar-app/",
|
||||||
|
// // The full path of the interpreter, if any (ruby, python, node, etc)
|
||||||
|
// Interpreter: "/opt/node/bin/node",
|
||||||
|
// // The name of the executable (or script)
|
||||||
|
// Exec: "foobar-app.js",
|
||||||
|
// // An array of arguments
|
||||||
|
// Argv: []string{"-c", "/path/to/config.json"},
|
||||||
|
// // A map of Environment variables that should be set
|
||||||
|
// Envs: map[string]string{
|
||||||
|
// PORT: "8080",
|
||||||
|
// ENV: "development",
|
||||||
|
// },
|
||||||
|
// // The user (Linux & Mac only).
|
||||||
|
// // This does not apply to userspace services.
|
||||||
|
// // There may be special considerations
|
||||||
|
// User: "www-data",
|
||||||
|
// // If different from User
|
||||||
|
// Group: "",
|
||||||
|
// // Whether to install as a system or user service
|
||||||
|
// System: false,
|
||||||
|
// // Whether or not the service may need privileged ports
|
||||||
|
// PrivilegedPorts: false,
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Note that some fields are exported for templating,
|
||||||
|
// but not intended to be set by you.
|
||||||
|
// These are documented as omitted from JSON.
|
||||||
|
// Try to stick to what's outlined above.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
@ -23,7 +62,7 @@ type Config struct {
|
||||||
User string `json:"user"`
|
User string `json:"user"`
|
||||||
Group string `json:"group"`
|
Group string `json:"group"`
|
||||||
home string `json:"-"`
|
home string `json:"-"`
|
||||||
Local string `json:"local"`
|
Local string `json:"-"`
|
||||||
LogDir string `json:"-"`
|
LogDir string `json:"-"`
|
||||||
System bool `json:"system"`
|
System bool `json:"system"`
|
||||||
Restart bool `json:"restart"`
|
Restart bool `json:"restart"`
|
||||||
|
@ -32,6 +71,8 @@ type Config struct {
|
||||||
MultiuserProtection bool `json:"multiuser_protection"`
|
MultiuserProtection bool `json:"multiuser_protection"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Install will do a best-effort attempt to install a start-on-startup
|
||||||
|
// user or system service via systemd, launchd, or reg.exe
|
||||||
func Install(c *Config) error {
|
func Install(c *Config) error {
|
||||||
if "" == c.Exec {
|
if "" == c.Exec {
|
||||||
c.Exec = c.Name
|
c.Exec = c.Name
|
||||||
|
|
|
@ -2,16 +2,81 @@ package installer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
//"golang.org/x/sys/windows"
|
"log"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"golang.org/x/sys/windows/registry"
|
||||||
)
|
)
|
||||||
|
|
||||||
// See
|
// TODO system service requires elevated privileges
|
||||||
// https://github.com/golang/go/issues/28804
|
// See https://coolaj86.com/articles/golang-and-windows-and-admins-oh-my/
|
||||||
// https://stackoverflow.com/questions/31558066/how-to-ask-for-administer-privileges-on-windows-with-go/31561120
|
|
||||||
// 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(c *Config) error {
|
func install(c *Config) error {
|
||||||
//token := windows.Token(0)
|
//token := windows.Token(0)
|
||||||
return fmt.Errorf("not yet implemented")
|
/*
|
||||||
|
// LEAVE THIS DOCUMENTATION HERE
|
||||||
|
reg.exe
|
||||||
|
/V <value name> - "Telebit"
|
||||||
|
/T <data type> - "REG_SZ" - String
|
||||||
|
/D <value data>
|
||||||
|
/C - case sensitive
|
||||||
|
/F <search data??> - not sure...
|
||||||
|
|
||||||
|
// Special Note:
|
||||||
|
"/c" is similar to -- (*nix), and required within the data string
|
||||||
|
So instead of setting "do.exe --do-arg1 --do-arg2"
|
||||||
|
you must set "do.exe /c --do-arg1 --do-arg2"
|
||||||
|
|
||||||
|
vars.telebitNode += '.exe';
|
||||||
|
var cmd = 'reg.exe add "HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"'
|
||||||
|
+ ' /V "Telebit" /t REG_SZ /D '
|
||||||
|
+ '"' + things.argv[0] + ' /c ' // something like C:\Program Files (x64)\nodejs\node.exe
|
||||||
|
+ [ path.join(__dirname, 'bin/telebitd.js')
|
||||||
|
, 'daemon'
|
||||||
|
, '--config'
|
||||||
|
, path.join(os.homedir(), '.config/telebit/telebitd.yml')
|
||||||
|
].join(' ')
|
||||||
|
+ '" /F'
|
||||||
|
;
|
||||||
|
*/
|
||||||
|
autorunKey := `SOFTWARE\Microsoft\Windows\CurrentVersion\Run`
|
||||||
|
k, _, err := registry.CreateKey(
|
||||||
|
registry.CURRENT_USER,
|
||||||
|
autorunKey,
|
||||||
|
registry.SET_VALUE,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
defer k.Close()
|
||||||
|
|
||||||
|
setArgs := ""
|
||||||
|
args := c.Argv
|
||||||
|
exec := filepath.Join(c.home, ".local", "opt", c.Name, c.Exec)
|
||||||
|
bin := c.Interpreter
|
||||||
|
if "" != bin {
|
||||||
|
// If this is something like node or python,
|
||||||
|
// the interpeter must be called as "the main thing"
|
||||||
|
// and "the app" must be an argument
|
||||||
|
args = append([]string{exec}, args...)
|
||||||
|
} else {
|
||||||
|
// Otherwise, if "the app" is a true binary,
|
||||||
|
// it can be "the main thing"
|
||||||
|
bin = exec
|
||||||
|
}
|
||||||
|
if 0 != len(args) {
|
||||||
|
// On Windows the /c acts kinda like -- does on *nix,
|
||||||
|
// at least for commands in the registry that have arguments
|
||||||
|
setArgs = ` /c `
|
||||||
|
}
|
||||||
|
|
||||||
|
// The final string ends up looking something like one of these:
|
||||||
|
// "C:\Users\aj\.local\opt\appname\appname.js /c -p 8080"
|
||||||
|
// "C:\Program Files (x64)\nodejs\node.exe /c C:\Users\aj\.local\opt\appname\appname.js -p 8080"
|
||||||
|
regSZ := bin + setArgs + strings.Join(c.Argv, " ")
|
||||||
|
fmt.Println("Set Registry Key:")
|
||||||
|
fmt.Println(autorunKey, c.Title, regSZ)
|
||||||
|
k.SetStringValue(c.Title, regSZ)
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,9 @@ package installer
|
||||||
|
|
||||||
import "os/user"
|
import "os/user"
|
||||||
|
|
||||||
func IsAdmin() {
|
// IsAdmin returns true if the user can be determined to be an admin
|
||||||
|
// and false otherwise (errs on the side of non-admin).
|
||||||
|
func IsAdmin() bool {
|
||||||
u, err := user.Current()
|
u, err := user.Current()
|
||||||
if nil != err {
|
if nil != err {
|
||||||
return false
|
return false
|
||||||
|
@ -15,7 +17,11 @@ func IsAdmin() {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
ids := u.GroupIds()
|
ids, err := u.GroupIds()
|
||||||
|
if nil != err {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
for i := range ids {
|
for i := range ids {
|
||||||
if "S-1-5-32-544" == ids[i] {
|
if "S-1-5-32-544" == ids[i] {
|
||||||
return true
|
return true
|
||||||
|
|
1
go.mod
1
go.mod
|
@ -6,4 +6,5 @@ require (
|
||||||
git.rootprojects.org/root/go-gitver v1.1.1
|
git.rootprojects.org/root/go-gitver v1.1.1
|
||||||
github.com/UnnoTed/fileb0x v1.1.3
|
github.com/UnnoTed/fileb0x v1.1.3
|
||||||
golang.org/x/net v0.0.0-20180921000356-2f5d2388922f
|
golang.org/x/net v0.0.0-20180921000356-2f5d2388922f
|
||||||
|
golang.org/x/sys v0.0.0-20181019160139-8e24a49d80f8
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue