Use go-systemd/login1 for Reboot/Shutdown

This commit is contained in:
Pablo Carranza Vélez 2015-09-09 14:32:37 +00:00
parent 6f42fc2036
commit 8585ad718f
7 changed files with 125 additions and 25 deletions

View File

@ -66,7 +66,7 @@ gosuper: go-builder
test-gosuper: go-builder
-docker rm --volumes -f resin_test_gosuper_$(JOB_NAME) || true
docker run --name resin_test_gosuper_$(JOB_NAME) -v /var/run/dbus:/mnt/root/run/dbus resin/go-supervisor-builder:$(SUPERVISOR_VERSION) bash -c "cd src/resin-supervisor/gosuper && ./test_formatting.sh && go test -v ./gosuper"
docker run --name resin_test_gosuper_$(JOB_NAME) -v /var/run/dbus:/mnt/root/run/dbus -e DBUS_SYSTEM_BUS_ADDRESS="unix:path=/mnt/root/run/dbus/system_bus_socket" resin/go-supervisor-builder:$(SUPERVISOR_VERSION) bash -c "cd src/resin-supervisor/gosuper && ./test_formatting.sh && go test -v ./gosuper"
docker rm --volumes -f resin_test_gosuper_$(JOB_NAME)
format-gosuper: go-builder

View File

@ -22,6 +22,7 @@ mount -t tmpfs -o size=1m tmpfs /var/run/resin
if [ -z "$GOSUPER_SOCKET" ]; then
export GOSUPER_SOCKET=/var/run/resin/gosuper.sock
fi
export DBUS_SYSTEM_BUS_ADDRESS="unix:path=/mnt/root/run/dbus/system_bus_socket"
/usr/bin/supervisord -c /etc/supervisor/supervisord.conf

View File

@ -5,6 +5,11 @@
"./..."
],
"Deps": [
{
"ImportPath": "github.com/coreos/go-systemd/login1",
"Comment": "v3-13-g392c689",
"Rev": "392c689e425689acb51976419a8d62878966511f"
},
{
"ImportPath": "github.com/godbus/dbus",
"Comment": "v2-14-g69f6e9a",

View File

@ -0,0 +1,84 @@
// Copyright 2015 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Integration with the systemd logind API. See http://www.freedesktop.org/wiki/Software/systemd/logind/
package login1
import (
"os"
"strconv"
"resin-supervisor/gosuper/Godeps/_workspace/src/github.com/godbus/dbus"
)
const (
dbusInterface = "org.freedesktop.login1.Manager"
dbusPath = "/org/freedesktop/login1"
)
// Conn is a connection to systemds dbus endpoint.
type Conn struct {
conn *dbus.Conn
object dbus.BusObject
}
// New() establishes a connection to the system bus and authenticates.
func New() (*Conn, error) {
c := new(Conn)
if err := c.initConnection(); err != nil {
return nil, err
}
return c, nil
}
func (c *Conn) initConnection() error {
var err error
c.conn, err = dbus.SystemBusPrivate()
if err != nil {
return err
}
// Only use EXTERNAL method, and hardcode the uid (not username)
// to avoid a username lookup (which requires a dynamically linked
// libc)
methods := []dbus.Auth{dbus.AuthExternal(strconv.Itoa(os.Getuid()))}
err = c.conn.Auth(methods)
if err != nil {
c.conn.Close()
return err
}
err = c.conn.Hello()
if err != nil {
c.conn.Close()
return err
}
c.object = c.conn.Object("org.freedesktop.login1", dbus.ObjectPath(dbusPath))
return nil
}
// Reboot asks logind for a reboot optionally asking for auth.
func (c *Conn) Reboot(askForAuth bool) {
c.object.Call(dbusInterface+".Reboot", 0, askForAuth)
}
// PowerOff asks logind for a power off optionally asking for auth.
func (c *Conn) PowerOff(askForAuth bool) {
c.object.Call(dbusInterface+".PowerOff", 0, askForAuth)
}

View File

@ -0,0 +1,28 @@
// Copyright 2015 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package login1
import (
"testing"
)
// TestNew ensures that New() works without errors.
func TestNew(t *testing.T) {
_, err := New()
if err != nil {
t.Fatal(err)
}
}

View File

@ -96,7 +96,7 @@ func RebootHandler(writer http.ResponseWriter, request *http.Request) {
sendResponse := responseSender(writer)
sendResponse("OK", "", http.StatusAccepted)
systemd.Reboot()
systemd.Logind.Reboot(false)
}
func ShutdownHandler(writer http.ResponseWriter, request *http.Request) {
@ -104,5 +104,5 @@ func ShutdownHandler(writer http.ResponseWriter, request *http.Request) {
sendResponse := responseSender(writer)
sendResponse("OK", "", http.StatusAccepted)
systemd.Shutdown()
systemd.Logind.PowerOff(false)
}

View File

@ -2,33 +2,15 @@ package systemd
import (
"log"
"os/exec"
"resin-supervisor/gosuper/Godeps/_workspace/src/github.com/godbus/dbus"
"resin-supervisor/gosuper/Godeps/_workspace/src/github.com/coreos/go-systemd/login1"
)
var Systemd dbus.BusObject
var Logind *login1.Conn
func init() {
if conn, err := dbus.Dial("unix:path=/mnt/root/run/dbus/system_bus_socket"); err != nil {
var err error
if Logind, err = login1.New(); err != nil {
log.Fatal("Failed to connect to host system bus")
} else {
Systemd = conn.Object("org.freedesktop.systemd1", "/org/freedesktop/systemd1")
}
}
func Reboot() {
if err := exec.Command("sync").Run(); err != nil {
log.Println(err)
} else if call := Systemd.Call("org.freedesktop.systemd1.Reboot", 0); call.Err != nil {
log.Println(call.Err)
}
}
func Shutdown() {
if err := exec.Command("sync").Run(); err != nil {
log.Println(err)
} else if call := Systemd.Call("org.freedesktop.systemd1.PowerOff", 0); call.Err != nil {
log.Println(call.Err)
}
}