package gosyphus import ( "os" "strings" ) // Gosyphus represents a Systemd service type Gosyphus struct { servType string description string user string group string directory string process string restart bool needNetwork bool environment map[string]string wantedBy string } // NewService creates a service func NewService(wd, proc, usr, grp string) *Gosyphus { g := &Gosyphus{ servType: "simple", directory: wd, process: proc, user: usr, group: grp, restart: true, needNetwork: true, wantedBy: "multi-user.target", } g.environment = make(map[string]string) return g } // Describe sets the description of the service func (g *Gosyphus) Describe(desc string) { g.description = desc } // DisableNetwork removes the network requirement from the service func (g *Gosyphus) DisableNetwork() { g.needNetwork = false } // EnableNetwork adds the network requirement to the service func (g *Gosyphus) EnableNetwork() { g.needNetwork = true } // DisableRestart sets the 'Restart' flag to 'never' func (g *Gosyphus) DisableRestart() { g.restart = false } // EnableRestart sets the 'Restart' flag to 'always' func (g *Gosyphus) EnableRestart() { g.restart = true } // AddToEnvironment adds a new line to the service environment func (g *Gosyphus) AddToEnvironment(k, v string) { g.environment[k] = v } // SetEnvironmentToCurrent copies the active environment into the service func (g *Gosyphus) SetEnvironmentToCurrent() { for _, env := range os.Environ() { vars := strings.Split(env, "=") if len(vars) == 2 { g.AddToEnvironment(vars[0], vars[1]) } } } // GenerateFile generates the .service file in the current directory func (g *Gosyphus) GenerateFile(filename string) error { // For now, we force the USER and HOME environment variables // TODO: make this dynamic g.AddToEnvironment("USER", g.user) g.AddToEnvironment("HOME", "/home/"+g.user) f, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY, 0664) if err != nil { return err } f.WriteString("[Unit]\n") f.WriteString("Description=" + g.description + "\n") f.WriteString("After=syslog.target\n") if g.needNetwork { f.WriteString("After=network.target\n") } f.WriteString("\n") f.WriteString("[Service]\n") f.WriteString("Type=simple\n") f.WriteString("User=" + g.user + "\n") f.WriteString("Group=" + g.group + "\n") f.WriteString("WorkingDirectory=" + g.directory + "\n") f.WriteString("ExecStart=" + g.process + "\n") if g.restart { f.WriteString("Restart=always\n") } else { f.WriteString("Restart=no\n") } if len(g.environment) > 0 { f.WriteString("Environment=") } var envString string for k, v := range g.environment { envString += ",\"" + k + "=" + v + "\"" } if len(envString) > 0 { envString = envString[1:] } f.WriteString(envString) f.WriteString("\n") f.WriteString("[Install]\n") f.WriteString("WantedBy=" + g.wantedBy + "\n") f.Close() return nil }