1
0
mirror of https://github.com/rancher/os.git synced 2025-07-02 01:31:48 +00:00

add power functions - down, restart, halt

This commit is contained in:
sidharthamani 2015-02-12 15:22:48 -08:00
parent 70b376ce6a
commit 56a4f96b24
4 changed files with 167 additions and 7 deletions

View File

@ -78,11 +78,11 @@ func NewConfig() *Config {
"8.8.8.8",
"8.8.4.4",
},
ImagesPath: "/",
ImagesPattern: "images*.tar",
StateRequired: false,
ImagesPath: "/",
ImagesPattern: "images*.tar",
StateRequired: false,
StateDev: "LABEL=RANCHER_STATE",
StateDevFSType: "auto",
StateDevFSType: "ext4",
SysInit: "/sbin/init-sys",
SystemDockerArgs: []string{"docker", "-d", "-s", "overlay", "-b", "none"},
UserInit: "/sbin/init-user",
@ -143,6 +143,9 @@ func NewConfig() *Config {
"--volume", "/init:/usr/bin/system-docker:ro",
"--volume", "/init:/usr/bin/respawn:ro",
"--volume", "/var/run/docker.sock:/var/run/system-docker.sock:ro",
"--volume", "/sbin/poweroff:/sbin/poweroff:ro",
"--volume", "/sbin/reboot:/sbin/reboot:ro",
"--volume", "/sbin/halt:/sbin/halt:ro",
"--volumes-from", "system-state",
"--net", "host",
"--pid", "host",

View File

@ -55,6 +55,9 @@ var (
"/sbin/modprobe": "/busybox",
"/var/run": "/run",
DOCKER: "/docker",
"/sbin/poweroff": "/init",
"/sbin/halt": "/init",
"/sbin/reboot": "/init",
}
)
@ -215,10 +218,10 @@ func mountState(cfg *config.Config) error {
var err error
dev := util.ResolveDevice(cfg.StateDev)
log.Debugf("Mounting state device %s", dev)
log.Debugf("Mounting state device %s", dev)
fsType := cfg.StateDevFSType
log.Debugf("FsType has been set to %s", fsType)
log.Debugf("FsType has been set to %s", fsType)
if fsType == "auto" {
actualFsType, fsErr := util.GetFsType(dev)
if fsErr != nil {

View File

@ -6,6 +6,7 @@ import (
log "github.com/Sirupsen/logrus"
"github.com/docker/docker/pkg/reexec"
osInit "github.com/rancherio/os/init"
"github.com/rancherio/os/power"
"github.com/rancherio/os/respawn"
"github.com/rancherio/os/sysinit"
"github.com/rancherio/os/user"
@ -18,8 +19,10 @@ func main() {
reexec.Register("/sbin/init-sys", sysinit.SysInit)
reexec.Register("/usr/bin/system-docker", user.SystemDocker)
reexec.Register("system-docker", user.SystemDocker)
reexec.Register("poweroff", power.PowerOff)
reexec.Register("reboot", power.Reboot)
reexec.Register("halt", power.Halt)
reexec.Register("respawn", respawn.Main)
if !reexec.Init() {
log.Fatalf("Failed to find an entry point for %s", os.Args[0])
}

151
power/power.go Normal file
View File

@ -0,0 +1,151 @@
package power
import (
"bufio"
"errors"
"os"
"strconv"
"syscall"
"strings"
"github.com/fsouza/go-dockerclient"
)
const (
dockerPath = "unix:///var/run/system-docker.sock"
dockerCGroupsFile = "/proc/self/cgroup"
)
func PowerOff() {
reboot(syscall.LINUX_REBOOT_CMD_POWER_OFF)
}
func Reboot() {
reboot(syscall.LINUX_REBOOT_CMD_RESTART)
}
func Halt() {
reboot(syscall.LINUX_REBOOT_CMD_HALT)
}
func reboot(code int) {
err := shutDownContainers()
if err != nil {
panic(err)
}
err = syscall.Reboot(code)
if err != nil {
panic(err)
}
}
func shutDownContainers() error {
var err error
shutDown := true
timeout := uint(0)
for i := range os.Args {
arg := os.Args[i]
if arg == "-f" || arg == "--f" || arg == "--force" {
shutDown = false
}
if arg == "-t" || arg == "--t" || arg == "--timeout" {
if len(os.Args) > i+1 {
t, er := strconv.Atoi(os.Args[i+1])
if er != nil {
return err
}
timeout = uint(t)
} else {
panic("please specify a timeout")
}
}
}
if !shutDown {
return nil
}
client, err := docker.NewClient(dockerPath)
if err != nil {
return err
}
opts := docker.ListContainersOptions{All: true, Filters: map[string][]string{"status": []string{"running"}}}
var containers []docker.APIContainers
containers, err = client.ListContainers(opts)
if err != nil {
return err
}
currentContainerId, err := getCurrentContainerId()
if err != nil {
return err
}
var stopErrorStrings []string
for i := range containers {
if containers[i].ID == currentContainerId {
continue
}
stopErr := client.StopContainer(containers[i].ID, timeout)
if stopErr != nil {
stopErrorStrings = append(stopErrorStrings, " [" + containers[i].ID + "] " +stopErr.Error())
}
}
var waitErrorStrings []string
for i := range containers {
if containers[i].ID == currentContainerId {
continue
}
_, waitErr := client.WaitContainer(containers[i].ID)
if waitErr != nil {
waitErrorStrings = append(waitErrorStrings, " [" + containers[i].ID + "] " + waitErr.Error())
}
}
if len(waitErrorStrings) != 0 || len(stopErrorStrings) != 0 {
return errors.New("error while stopping \n1. STOP Errors [" + strings.Join(stopErrorStrings, ",") + "] \n2. WAIT Errors [" + strings.Join(waitErrorStrings, ",") + "]")
}
return nil
}
func getCurrentContainerId() (string, error) {
file, err := os.Open(dockerCGroupsFile)
if err != nil {
return "", err
}
fileReader := bufio.NewScanner(file)
if !fileReader.Scan() {
return "", errors.New("Empty file /proc/self/cgroup")
}
line := fileReader.Text()
parts := strings.Split(line, "/")
while len(parts) != 3 {
if !fileReader.Scan() {
return "", errors.New("Found no docker cgroups")
}
line = fileReader.Text()
parts = strings.Split(line, "/")
if len(parts) == 3 {
if strings.HasSuffix(parts[1], "docker") {
break
} else {
parts = nil
}
}
}
return parts[len(parts)-1:][0], nil
}