1
// Copyright 2015 CoreOS, Inc.
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
7
// http://www.apache.org/licenses/LICENSE-2.0
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
15
// Integration with the systemd logind API. See http://www.freedesktop.org/wiki/Software/systemd/logind/
23
"github.com/godbus/dbus"
27
dbusInterface = "org.freedesktop.login1.Manager"
28
dbusPath = "/org/freedesktop/login1"
31
// Conn is a connection to systemds dbus endpoint.
37
// New() establishes a connection to the system bus and authenticates.
38
func New() (*Conn, error) {
41
if err := c.initConnection(); err != nil {
48
func (c *Conn) initConnection() error {
50
c.conn, err = dbus.SystemBusPrivate()
55
// Only use EXTERNAL method, and hardcode the uid (not username)
56
// to avoid a username lookup (which requires a dynamically linked
58
methods := []dbus.Auth{dbus.AuthExternal(strconv.Itoa(os.Getuid()))}
60
err = c.conn.Auth(methods)
72
c.object = c.conn.Object("org.freedesktop.login1", dbus.ObjectPath(dbusPath))
77
// Reboot asks logind for a reboot optionally asking for auth.
78
func (c *Conn) Reboot(askForAuth bool) {
79
c.object.Call(dbusInterface+".Reboot", 0, askForAuth)
82
// Inhibit takes inhibition lock in logind.
83
func (c *Conn) Inhibit(what, who, why, mode string) (*os.File, error) {
86
err := c.object.Call(dbusInterface+".Inhibit", 0, what, who, why, mode).Store(&fd)
91
return os.NewFile(uintptr(fd), "inhibit"), nil
94
// Subscribe to signals on the logind dbus
95
func (c *Conn) Subscribe(members ...string) chan *dbus.Signal {
96
for _, member := range members {
97
c.conn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0,
98
fmt.Sprintf("type='signal',interface='org.freedesktop.login1.Manager',member='%s'", member))
100
ch := make(chan *dbus.Signal, 10)
105
// PowerOff asks logind for a power off optionally asking for auth.
106
func (c *Conn) PowerOff(askForAuth bool) {
107
c.object.Call(dbusInterface+".PowerOff", 0, askForAuth)