blob: 7e3301ee9259ec755dab4769ddf56ef9a8fbe5ed [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Command inithelper manages services for a variety of platforms and init
// systems, such as upstart, systemd etc.
package main
// TODO(caprita): The separation of responsibilities between root/non-root code
// can be shifted away from root a bit more, by having the init daemon files
// created as non-root and root just installs files and runs a specific set of
// commands. Figure out if worth it. Also consider combining with suidhelper.
// For now they're separate since we don't always need both at the same time.
// TODO(caprita): Add unit test.
import (
"bytes"
"flag"
"fmt"
"os"
"v.io/x/ref/services/device/internal/sysinit"
)
func usage() {
const usage = `Usage:
%s [flags] [command]
Flags:
%s
Command:
print: prints the file that would be installed
install: installs the service
uninstall: uninstalls the service
start: starts the service
stop: stops the service
`
var flagDefaults bytes.Buffer
flag.CommandLine.SetOutput(&flagDefaults)
flag.CommandLine.PrintDefaults()
flag.CommandLine.SetOutput(nil)
fmt.Fprintf(os.Stderr, usage, os.Args[0], flagDefaults.String())
}
func main() {
fmt.Fprintln(os.Stderr, os.Args)
if os.Geteuid() != 0 && os.Getuid() != 0 {
fmt.Fprintln(os.Stderr, "uid is ", os.Getuid(), ", effective uid is ", os.Geteuid())
fmt.Fprintln(os.Stderr, "inithelper is not root. Is your filesystem mounted with nosuid?")
os.Exit(1)
}
flag.Usage = usage
sdFlag := flag.String("service_description", "", "File containing a JSON-encoded sysinit.ServiceDescription object.")
systemFlag := flag.String("system", sysinit.InitSystem(), "System label, to select the appropriate sysinit mechanism.")
flag.Parse()
if *sdFlag == "" {
fmt.Fprintf(os.Stderr, "--service_description must be set.\n")
flag.Usage()
os.Exit(1)
}
if *systemFlag == "" {
fmt.Fprintf(os.Stderr, "--system must be set.\n")
flag.Usage()
os.Exit(1)
}
var sd sysinit.ServiceDescription
if err := sd.LoadFrom(*sdFlag); err != nil {
fmt.Fprintf(os.Stderr, "LoadFrom(%v) failed: %v\n", *sdFlag, err)
os.Exit(2)
}
si := sysinit.New(*systemFlag, &sd)
args := flag.Args()
if len(args) != 1 {
fmt.Fprintf(os.Stderr, "Command must be specified.\n")
flag.Usage()
os.Exit(1)
}
switch args[0] {
case "print":
if err := si.Print(); err != nil {
fmt.Fprintf(os.Stderr, "Failed to print %v: %s\n", si, err)
os.Exit(2)
}
case "install":
if err := si.Install(); err != nil {
fmt.Fprintf(os.Stderr, "Failed to install %v: %s\n", si, err)
os.Exit(2)
}
case "uninstall":
if err := si.Uninstall(); err != nil {
fmt.Fprintf(os.Stderr, "Failed to uninstall %v: %s\n", si, err)
os.Exit(2)
}
case "start":
if err := si.Start(); err != nil {
fmt.Fprintf(os.Stderr, "Failed to start %v: %s\n", si, err)
os.Exit(2)
}
case "stop":
if err := si.Stop(); err != nil {
fmt.Fprintf(os.Stderr, "Failed to stop %v: %s\n", si, err)
os.Exit(2)
}
default:
fmt.Fprintf(os.Stderr, "Invalid command: %s\n", args[0])
flag.Usage()
os.Exit(1)
}
}