blog/service.go

117 lines
2.7 KiB
Go

// service.go
package main
import (
"fmt"
"os"
"os/exec"
"os/user"
"path/filepath"
"text/template"
)
const serviceTemplate = `[Unit]
Description=Blog Server
After=network.target
[Service]
Type=simple
User={{.User}}
WorkingDirectory={{.WorkDir}}
ExecStart={{.BinaryPath}}
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
`
type ServiceConfig struct {
User string
WorkDir string
BinaryPath string
}
func InstallService() {
// 1. Get Absolute Path to Binary
binPath, err := os.Executable()
if err != nil {
fmt.Printf("Error getting executable path: %v\n", err)
return
}
binPath, _ = filepath.Abs(binPath)
// 2. Get Working Directory
workDir, err := os.Getwd()
if err != nil {
fmt.Printf("Error getting working directory: %v\n", err)
return
}
// 3. Determine User
// If running as sudo, try to get the original user, otherwise use current
username := os.Getenv("SUDO_USER")
if username == "" {
u, err := user.Current()
if err == nil {
username = u.Username
} else {
username = "root"
}
}
config := ServiceConfig{
User: username,
WorkDir: workDir,
BinaryPath: binPath,
}
// 4. Generate Content
tmpl, err := template.New("service").Parse(serviceTemplate)
if err != nil {
panic(err)
}
serviceFile := "/etc/systemd/system/blog.service"
// Check if we have write permissions to /etc/systemd/system
f, err := os.OpenFile(serviceFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
if err != nil {
// Permission denied or other error: Print instructions instead
fmt.Println("---------------------------------------------------")
fmt.Println("Run the following command with sudo to install:")
fmt.Println("---------------------------------------------------")
fmt.Printf("sudo bash -c 'cat > %s <<EOF\n", serviceFile)
tmpl.Execute(os.Stdout, config)
fmt.Println("EOF'")
fmt.Println("---------------------------------------------------")
fmt.Println("Then run:")
fmt.Println("sudo systemctl daemon-reload")
fmt.Println("sudo systemctl enable --now blog")
return
}
defer f.Close()
// Write file
if err := tmpl.Execute(f, config); err != nil {
fmt.Printf("Error writing service file: %v\n", err)
return
}
fmt.Printf("Service file created at %s\n", serviceFile)
// 5. Reload Daemon
cmd := exec.Command("systemctl", "daemon-reload")
if err := cmd.Run(); err != nil {
fmt.Println("Warning: Failed to reload systemd daemon. Run 'sudo systemctl daemon-reload' manually.")
}
// 6. Enable and Start
cmd = exec.Command("systemctl", "enable", "--now", "blog")
if output, err := cmd.CombinedOutput(); err != nil {
fmt.Printf("Warning: Failed to enable service: %v\nOutput: %s\n", err, output)
} else {
fmt.Println("Service installed, enabled, and started successfully!")
}
}