Merge pull request #353 from LK4D4/update_dbus

Update github.com/godbus/dbus to v2
This commit is contained in:
Victor Marmol 2015-01-29 15:46:05 -08:00
commit 3c52181f61
11 changed files with 200 additions and 19 deletions

View File

@ -42,7 +42,7 @@ clone() {
# the following lines are in sorted order, FYI
clone git github.com/codegangsta/cli 1.1.0
clone git github.com/coreos/go-systemd v2
clone git github.com/godbus/dbus v1
clone git github.com/godbus/dbus v2
clone git github.com/syndtr/gocapability 3c85049eae
# intentionally not vendoring Docker itself... that'd be a circle :)

View File

@ -0,0 +1,50 @@
# How to Contribute
## Getting Started
- Fork the repository on GitHub
- Read the [README](README.markdown) for build and test instructions
- Play with the project, submit bugs, submit patches!
## Contribution Flow
This is a rough outline of what a contributor's workflow looks like:
- Create a topic branch from where you want to base your work (usually master).
- Make commits of logical units.
- Make sure your commit messages are in the proper format (see below).
- Push your changes to a topic branch in your fork of the repository.
- Make sure the tests pass, and add any new tests as appropriate.
- Submit a pull request to the original repository.
Thanks for your contributions!
### Format of the Commit Message
We follow a rough convention for commit messages that is designed to answer two
questions: what changed and why. The subject line should feature the what and
the body of the commit should describe the why.
```
scripts: add the test-cluster command
this uses tmux to setup a test cluster that you can easily kill and
start for debugging.
Fixes #38
```
The format can be described more formally as follows:
```
<subsystem>: <what changed>
<BLANK LINE>
<why this change was made>
<BLANK LINE>
<footer>
```
The first line is the subject and should be no longer than 70 characters, the
second line is always blank, and other lines should be wrapped at 80 characters.
This allows the message to be easier to read on GitHub as well as in various
git tools.

View File

@ -0,0 +1,2 @@
Brandon Philips <brandon@ifup.org> (@philips)
Brian Waldon <brian@waldon.cc> (@bcwaldon)

View File

@ -175,6 +175,13 @@ func (conn *Conn) BusObject() *Object {
// not be called on shared connections.
func (conn *Conn) Close() error {
conn.outLck.Lock()
if conn.closed {
// inWorker calls Close on read error, the read error may
// be caused by another caller calling Close to shutdown the
// dbus connection, a double-close scenario we prevent here.
conn.outLck.Unlock()
return nil
}
close(conn.out)
conn.closed = true
conn.outLck.Unlock()
@ -317,11 +324,7 @@ func (conn *Conn) inWorker() {
}
conn.signalsLck.Lock()
for _, ch := range conn.signals {
// don't block trying to send a signal
select {
case ch <- signal:
default:
}
ch <- signal
}
conn.signalsLck.Unlock()
case TypeMethodCall:
@ -508,6 +511,10 @@ type Error struct {
Body []interface{}
}
func NewError(name string, body []interface{}) *Error {
return &Error{name, body}
}
func (e Error) Error() string {
if len(e.Body) >= 1 {
s, ok := e.Body[0].(string)
@ -546,13 +553,14 @@ type transport interface {
SendMessage(*Message) error
}
var (
transports map[string]func(string) (transport, error) = make(map[string]func(string) (transport, error))
)
func getTransport(address string) (transport, error) {
var err error
var t transport
m := map[string]func(string) (transport, error){
"unix": newUnixTransport,
}
addresses := strings.Split(address, ";")
for _, v := range addresses {
i := strings.IndexRune(v, ':')
@ -560,7 +568,7 @@ func getTransport(address string) (transport, error) {
err = errors.New("dbus: invalid bus address (no transport)")
continue
}
f := m[v[:i]]
f := transports[v[:i]]
if f == nil {
err = errors.New("dbus: invalid bus address (invalid or unsupported transport)")
}

View File

@ -17,6 +17,12 @@ var IntrospectData = Interface{
},
}
// XML document type declaration of the introspection format version 1.0
const IntrospectDeclarationString = `
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
`
// The introspection data for the org.freedesktop.DBus.Introspectable interface,
// as a string.
const IntrospectDataString = `

View File

@ -4,6 +4,7 @@ import (
"encoding/xml"
"github.com/godbus/dbus"
"reflect"
"strings"
)
// Introspectable implements org.freedesktop.Introspectable.
@ -31,7 +32,7 @@ func NewIntrospectable(n *Node) Introspectable {
if err != nil {
panic(err)
}
return Introspectable(b)
return Introspectable(strings.TrimSpace(IntrospectDeclarationString) + string(b))
}
// Introspect implements org.freedesktop.Introspectable.Introspect.
@ -50,7 +51,7 @@ func Methods(v interface{}) []Method {
}
mt := t.Method(i).Type
if mt.NumOut() == 0 ||
mt.Out(mt.NumOut()-1) != reflect.TypeOf(&dbus.Error{"", nil}) {
mt.Out(mt.NumOut()-1) != reflect.TypeOf(&dbus.Error{}) {
continue
}

View File

@ -22,19 +22,19 @@ const (
// ErrIfaceNotFound is the error returned to peers who try to access properties
// on interfaces that aren't found.
var ErrIfaceNotFound = &dbus.Error{"org.freedesktop.DBus.Properties.Error.InterfaceNotFound", nil}
var ErrIfaceNotFound = dbus.NewError("org.freedesktop.DBus.Properties.Error.InterfaceNotFound", nil)
// ErrPropNotFound is the error returned to peers trying to access properties
// that aren't found.
var ErrPropNotFound = &dbus.Error{"org.freedesktop.DBus.Properties.Error.PropertyNotFound", nil}
var ErrPropNotFound = dbus.NewError("org.freedesktop.DBus.Properties.Error.PropertyNotFound", nil)
// ErrReadOnly is the error returned to peers trying to set a read-only
// property.
var ErrReadOnly = &dbus.Error{"org.freedesktop.DBus.Properties.Error.ReadOnly", nil}
var ErrReadOnly = dbus.NewError("org.freedesktop.DBus.Properties.Error.ReadOnly", nil)
// ErrInvalidArg is returned to peers if the type of the property that is being
// changed and the argument don't match.
var ErrInvalidArg = &dbus.Error{"org.freedesktop.DBus.Properties.Error.InvalidArg", nil}
var ErrInvalidArg = dbus.NewError("org.freedesktop.DBus.Properties.Error.InvalidArg", nil)
// The introspection data for the org.freedesktop.DBus.Properties interface.
var IntrospectData = introspect.Interface{

View File

@ -1,3 +1,5 @@
//+build !windows
package dbus
import (
@ -58,6 +60,10 @@ func newUnixTransport(keys string) (transport, error) {
}
}
func init() {
transports["unix"] = newUnixTransport
}
func (t *unixTransport) EnableUnixFDs() {
t.hasUnixFDs = true
}

View File

@ -0,0 +1,95 @@
// The UnixCredentials system call is currently only implemented on Linux
// http://golang.org/src/pkg/syscall/sockcmsg_linux.go
// https://golang.org/s/go1.4-syscall
// http://code.google.com/p/go/source/browse/unix/sockcmsg_linux.go?repo=sys
// Local implementation of the UnixCredentials system call for DragonFly BSD
package dbus
/*
#include <sys/ucred.h>
*/
import "C"
import (
"io"
"os"
"syscall"
"unsafe"
)
// http://golang.org/src/pkg/syscall/ztypes_linux_amd64.go
// http://golang.org/src/pkg/syscall/ztypes_dragonfly_amd64.go
type Ucred struct {
Pid int32
Uid uint32
Gid uint32
}
// http://golang.org/src/pkg/syscall/types_linux.go
// http://golang.org/src/pkg/syscall/types_dragonfly.go
// https://github.com/DragonFlyBSD/DragonFlyBSD/blob/master/sys/sys/ucred.h
const (
SizeofUcred = C.sizeof_struct_ucred
)
// http://golang.org/src/pkg/syscall/sockcmsg_unix.go
func cmsgAlignOf(salen int) int {
// From http://golang.org/src/pkg/syscall/sockcmsg_unix.go
//salign := sizeofPtr
// NOTE: It seems like 64-bit Darwin and DragonFly BSD kernels
// still require 32-bit aligned access to network subsystem.
//if darwin64Bit || dragonfly64Bit {
// salign = 4
//}
salign := 4
return (salen + salign - 1) & ^(salign - 1)
}
// http://golang.org/src/pkg/syscall/sockcmsg_unix.go
func cmsgData(h *syscall.Cmsghdr) unsafe.Pointer {
return unsafe.Pointer(uintptr(unsafe.Pointer(h)) + uintptr(cmsgAlignOf(syscall.SizeofCmsghdr)))
}
// http://golang.org/src/pkg/syscall/sockcmsg_linux.go
// UnixCredentials encodes credentials into a socket control message
// for sending to another process. This can be used for
// authentication.
func UnixCredentials(ucred *Ucred) []byte {
b := make([]byte, syscall.CmsgSpace(SizeofUcred))
h := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
h.Level = syscall.SOL_SOCKET
h.Type = syscall.SCM_CREDS
h.SetLen(syscall.CmsgLen(SizeofUcred))
*((*Ucred)(cmsgData(h))) = *ucred
return b
}
// http://golang.org/src/pkg/syscall/sockcmsg_linux.go
// ParseUnixCredentials decodes a socket control message that contains
// credentials in a Ucred structure. To receive such a message, the
// SO_PASSCRED option must be enabled on the socket.
func ParseUnixCredentials(m *syscall.SocketControlMessage) (*Ucred, error) {
if m.Header.Level != syscall.SOL_SOCKET {
return nil, syscall.EINVAL
}
if m.Header.Type != syscall.SCM_CREDS {
return nil, syscall.EINVAL
}
ucred := *(*Ucred)(unsafe.Pointer(&m.Data[0]))
return &ucred, nil
}
func (t *unixTransport) SendNullByte() error {
ucred := &Ucred{Pid: int32(os.Getpid()), Uid: uint32(os.Getuid()), Gid: uint32(os.Getgid())}
b := UnixCredentials(ucred)
_, oobn, err := t.UnixConn.WriteMsgUnix([]byte{0}, b, nil)
if err != nil {
return err
}
if oobn != len(b) {
return io.ErrShortWrite
}
return nil
}

View File

@ -1,4 +1,7 @@
// +build !darwin
// The UnixCredentials system call is currently only implemented on Linux
// http://golang.org/src/pkg/syscall/sockcmsg_linux.go
// https://golang.org/s/go1.4-syscall
// http://code.google.com/p/go/source/browse/unix/sockcmsg_linux.go?repo=sys
package dbus

View File

@ -4,6 +4,7 @@ import (
"bytes"
"fmt"
"reflect"
"sort"
"strconv"
)
@ -89,18 +90,27 @@ func (v Variant) format() (string, bool) {
return "{}", false
}
unamb := true
buf := bytes.NewBuffer([]byte("{"))
var buf bytes.Buffer
kvs := make([]string, rv.Len())
for i, k := range rv.MapKeys() {
s, b := MakeVariant(k.Interface()).format()
unamb = unamb && b
buf.Reset()
buf.WriteString(s)
buf.WriteString(": ")
s, b = MakeVariant(rv.MapIndex(k).Interface()).format()
unamb = unamb && b
buf.WriteString(s)
if i != rv.Len()-1 {
kvs[i] = buf.String()
}
buf.Reset()
buf.WriteByte('{')
sort.Strings(kvs)
for i, kv := range kvs {
if i > 0 {
buf.WriteString(", ")
}
buf.WriteString(kv)
}
buf.WriteByte('}')
return buf.String(), unamb