Browse Source

Merge branch '0.2' into test-fix

Ben Johnson 12 years ago
parent
commit
a6a32a592d
39 changed files with 961 additions and 344 deletions
  1. 29 11
      third_party/bitbucket.org/kardianos/osext/osext_sysctl.go
  2. 20 26
      third_party/code.google.com/p/go.net/ipv4/gen.go
  3. 23 24
      third_party/code.google.com/p/go.net/ipv4/gentest.go
  4. 34 25
      third_party/code.google.com/p/go.net/ipv4/header.go
  5. 5 4
      third_party/code.google.com/p/go.net/ipv4/header_test.go
  6. 2 2
      third_party/code.google.com/p/go.net/ipv4/iana_test.go
  7. 20 26
      third_party/code.google.com/p/go.net/ipv6/gen.go
  8. 23 24
      third_party/code.google.com/p/go.net/ipv6/gentest.go
  9. 2 2
      third_party/code.google.com/p/go.net/ipv6/iana.go
  10. 2 2
      third_party/code.google.com/p/go.net/ipv6/iana_test.go
  11. 2 16
      third_party/code.google.com/p/go.net/websocket/client.go
  12. 5 21
      third_party/code.google.com/p/go.net/websocket/hybi.go
  13. 0 108
      third_party/code.google.com/p/go.net/websocket/hybi_test.go
  14. 0 8
      third_party/code.google.com/p/go.net/websocket/server.go
  15. 1 5
      third_party/code.google.com/p/go.net/websocket/websocket.go
  16. 14 0
      third_party/code.google.com/p/go.net/websocket/websocket_test.go
  17. 17 4
      third_party/github.com/coreos/go-etcd/etcd/client.go
  18. 21 1
      third_party/github.com/coreos/go-etcd/etcd/client_test.go
  19. 1 1
      third_party/github.com/coreos/go-etcd/etcd/delete_test.go
  20. 1 1
      third_party/github.com/coreos/go-etcd/etcd/get_test.go
  21. 1 1
      third_party/github.com/coreos/go-etcd/etcd/list_test.go
  22. 1 1
      third_party/github.com/coreos/go-etcd/etcd/set_test.go
  23. 1 1
      third_party/github.com/coreos/go-etcd/etcd/testAndSet_test.go
  24. 6 1
      third_party/github.com/coreos/go-etcd/etcd/watch.go
  25. 7 4
      third_party/github.com/coreos/go-etcd/etcd/watch_test.go
  26. 3 0
      third_party/github.com/coreos/go-etcd/examples/sync-cluster/README.md
  27. 51 0
      third_party/github.com/coreos/go-etcd/examples/sync-cluster/sync-cluster.go
  28. 16 14
      third_party/github.com/coreos/go-log/log/commands.go
  29. 1 2
      third_party/github.com/coreos/go-log/log/fields.go
  30. 1 2
      third_party/github.com/coreos/go-log/log/logger.go
  31. 1 2
      third_party/github.com/coreos/go-log/log/priority.go
  32. 1 2
      third_party/github.com/coreos/go-log/log/sinks.go
  33. 1 1
      third_party/github.com/coreos/go-raft/server.go
  34. 2 1
      third_party/github.com/coreos/go-systemd/activation/files.go
  35. 100 0
      third_party/github.com/coreos/go-systemd/dbus/dbus.go
  36. 166 0
      third_party/github.com/coreos/go-systemd/dbus/methods.go
  37. 193 0
      third_party/github.com/coreos/go-systemd/dbus/properties.go
  38. 182 0
      third_party/github.com/coreos/go-systemd/dbus/subscription.go
  39. 5 1
      third_party/github.com/coreos/go-systemd/journal/send.go

+ 29 - 11
third_party/bitbucket.org/kardianos/osext/osext_sysctl.go

@@ -8,6 +8,7 @@ package osext
 
 import (
 	"os"
+	"path/filepath"
 	"runtime"
 	"syscall"
 	"unsafe"
@@ -47,18 +48,35 @@ func executable() (string, error) {
 			break
 		}
 	}
+	var strpath string
 	if buf[0] != '/' {
-		if getwdError != nil {
-			return string(buf), getwdError
-		} else {
-			if buf[0] == '.' {
-				buf = buf[1:]
-			}
-			if startUpcwd[len(startUpcwd)-1] != '/' {
-				return startUpcwd + "/" + string(buf), nil
-			}
-			return startUpcwd + string(buf), nil
+		var e error
+		if strpath, e = getAbs(buf); e != nil {
+			return strpath, e
 		}
+	} else {
+		strpath = string(buf)
+	}
+	// darwin KERN_PROCARGS may return the path to a symlink rather than the
+	// actual executable
+	if runtime.GOOS == "darwin" {
+		if strpath, err := filepath.EvalSymlinks(strpath); err != nil {
+			return strpath, err
+		}
+	}
+	return strpath, nil
+}
+
+func getAbs(buf []byte) (string, error) {
+	if getwdError != nil {
+		return string(buf), getwdError
+	} else {
+		if buf[0] == '.' {
+			buf = buf[1:]
+		}
+		if startUpcwd[len(startUpcwd)-1] != '/' && buf[0] != '/' {
+			return startUpcwd + "/" + string(buf), nil
+		}
+		return startUpcwd + string(buf), nil
 	}
-	return string(buf), nil
 }

+ 20 - 26
third_party/code.google.com/p/go.net/ipv4/gen.go

@@ -97,20 +97,16 @@ func parseICMPv4Parameters(w io.Writer, r io.Reader) error {
 }
 
 type icmpv4Parameters struct {
-	XMLName    xml.Name              `xml:"registry"`
-	Title      string                `xml:"title"`
-	Updated    string                `xml:"updated"`
-	Registries []icmpv4ParamRegistry `xml:"registry"`
-}
-
-type icmpv4ParamRegistry struct {
-	Title   string              `xml:"title"`
-	Records []icmpv4ParamRecord `xml:"record"`
-}
-
-type icmpv4ParamRecord struct {
-	Value string `xml:"value"`
-	Descr string `xml:"description"`
+	XMLName    xml.Name `xml:"registry"`
+	Title      string   `xml:"title"`
+	Updated    string   `xml:"updated"`
+	Registries []struct {
+		Title   string `xml:"title"`
+		Records []struct {
+			Value string `xml:"value"`
+			Descr string `xml:"description"`
+		} `xml:"record"`
+	} `xml:"registry"`
 }
 
 type canonICMPv4ParamRecord struct {
@@ -193,18 +189,16 @@ func parseProtocolNumbers(w io.Writer, r io.Reader) error {
 }
 
 type protocolNumbers struct {
-	XMLName  xml.Name         `xml:"registry"`
-	Title    string           `xml:"title"`
-	Updated  string           `xml:"updated"`
-	RegTitle string           `xml:"registry>title"`
-	Note     string           `xml:"registry>note"`
-	Records  []protocolRecord `xml:"registry>record"`
-}
-
-type protocolRecord struct {
-	Value string `xml:"value"`
-	Name  string `xml:"name"`
-	Descr string `xml:"description"`
+	XMLName  xml.Name `xml:"registry"`
+	Title    string   `xml:"title"`
+	Updated  string   `xml:"updated"`
+	RegTitle string   `xml:"registry>title"`
+	Note     string   `xml:"registry>note"`
+	Records  []struct {
+		Value string `xml:"value"`
+		Name  string `xml:"name"`
+		Descr string `xml:"description"`
+	} `xml:"registry>record"`
 }
 
 type canonProtocolRecord struct {

+ 23 - 24
third_party/code.google.com/p/go.net/ipv4/gentest.go

@@ -39,7 +39,7 @@ var registries = []struct {
 
 func main() {
 	var bb bytes.Buffer
-	fmt.Fprintf(&bb, "// go run gentv.go\n")
+	fmt.Fprintf(&bb, "// go run gentest.go\n")
 	fmt.Fprintf(&bb, "// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT\n\n")
 	fmt.Fprintf(&bb, "package ipv4_test\n\n")
 	for _, r := range registries {
@@ -85,18 +85,19 @@ func parseDSCPRegistry(w io.Writer, r io.Reader) error {
 }
 
 type dscpRegistry struct {
-	XMLName     xml.Name     `xml:"registry"`
-	Title       string       `xml:"title"`
-	Updated     string       `xml:"updated"`
-	Note        string       `xml:"note"`
-	RegTitle    string       `xml:"registry>title"`
-	PoolRecords []dscpRecord `xml:"registry>record"`
-	Records     []dscpRecord `xml:"registry>registry>record"`
-}
-
-type dscpRecord struct {
-	Name  string `xml:"name"`
-	Space string `xml:"space"`
+	XMLName     xml.Name `xml:"registry"`
+	Title       string   `xml:"title"`
+	Updated     string   `xml:"updated"`
+	Note        string   `xml:"note"`
+	RegTitle    string   `xml:"registry>title"`
+	PoolRecords []struct {
+		Name  string `xml:"name"`
+		Space string `xml:"space"`
+	} `xml:"registry>record"`
+	Records []struct {
+		Name  string `xml:"name"`
+		Space string `xml:"space"`
+	} `xml:"registry>registry>record"`
 }
 
 type canonDSCPRecord struct {
@@ -145,17 +146,15 @@ func parseTOSTCByte(w io.Writer, r io.Reader) error {
 }
 
 type tosTCByte struct {
-	XMLName  xml.Name          `xml:"registry"`
-	Title    string            `xml:"title"`
-	Updated  string            `xml:"updated"`
-	Note     string            `xml:"note"`
-	RegTitle string            `xml:"registry>title"`
-	Records  []tosTCByteRecord `xml:"registry>record"`
-}
-
-type tosTCByteRecord struct {
-	Binary  string `xml:"binary"`
-	Keyword string `xml:"keyword"`
+	XMLName  xml.Name `xml:"registry"`
+	Title    string   `xml:"title"`
+	Updated  string   `xml:"updated"`
+	Note     string   `xml:"note"`
+	RegTitle string   `xml:"registry>title"`
+	Records  []struct {
+		Binary  string `xml:"binary"`
+		Keyword string `xml:"keyword"`
+	} `xml:"registry>record"`
 }
 
 type canonTOSTCByteRecord struct {

+ 34 - 25
third_party/code.google.com/p/go.net/ipv4/header.go

@@ -36,41 +36,47 @@ const (
 	maxHeaderLen = 60 // sensible default, revisit if later RFCs define new usage of version and header length fields
 )
 
-type headerField int
+const (
+	posTOS      = 1  // type-of-service
+	posTotalLen = 2  // packet total length
+	posID       = 4  // identification
+	posFragOff  = 6  // fragment offset
+	posTTL      = 8  // time-to-live
+	posProtocol = 9  // next protocol
+	posChecksum = 10 // checksum
+	posSrc      = 12 // source address
+	posDst      = 16 // destination address
+)
+
+type HeaderFlags int
 
 const (
-	posTOS      headerField = 1  // type-of-service
-	posTotalLen             = 2  // packet total length
-	posID                   = 4  // identification
-	posFragOff              = 6  // fragment offset
-	posTTL                  = 8  // time-to-live
-	posProtocol             = 9  // next protocol
-	posChecksum             = 10 // checksum
-	posSrc                  = 12 // source address
-	posDst                  = 16 // destination address
+	MoreFragments HeaderFlags = 1 << iota // more fragments flag
+	DontFragment                          // don't fragment flag
 )
 
 // A Header represents an IPv4 header.
 type Header struct {
-	Version  int    // protocol version
-	Len      int    // header length
-	TOS      int    // type-of-service
-	TotalLen int    // packet total length
-	ID       int    // identification
-	FragOff  int    // fragment offset
-	TTL      int    // time-to-live
-	Protocol int    // next protocol
-	Checksum int    // checksum
-	Src      net.IP // source address
-	Dst      net.IP // destination address
-	Options  []byte // options, extension headers
+	Version  int         // protocol version
+	Len      int         // header length
+	TOS      int         // type-of-service
+	TotalLen int         // packet total length
+	ID       int         // identification
+	Flags    HeaderFlags // flags
+	FragOff  int         // fragment offset
+	TTL      int         // time-to-live
+	Protocol int         // next protocol
+	Checksum int         // checksum
+	Src      net.IP      // source address
+	Dst      net.IP      // destination address
+	Options  []byte      // options, extension headers
 }
 
 func (h *Header) String() string {
 	if h == nil {
 		return "<nil>"
 	}
-	return fmt.Sprintf("ver: %v, hdrlen: %v, tos: %#x, totallen: %v, id: %#x, fragoff: %#x, ttl: %v, proto: %v, cksum: %#x, src: %v, dst: %v", h.Version, h.Len, h.TOS, h.TotalLen, h.ID, h.FragOff, h.TTL, h.Protocol, h.Checksum, h.Src, h.Dst)
+	return fmt.Sprintf("ver: %v, hdrlen: %v, tos: %#x, totallen: %v, id: %#x, flags: %#x, fragoff: %#x, ttl: %v, proto: %v, cksum: %#x, src: %v, dst: %v", h.Version, h.Len, h.TOS, h.TotalLen, h.ID, h.Flags, h.FragOff, h.TTL, h.Protocol, h.Checksum, h.Src, h.Dst)
 }
 
 // Please refer to the online manual; IP(4) on Darwin, FreeBSD and
@@ -89,12 +95,13 @@ func (h *Header) Marshal() ([]byte, error) {
 	b := make([]byte, hdrlen)
 	b[0] = byte(Version<<4 | (hdrlen >> 2 & 0x0f))
 	b[posTOS] = byte(h.TOS)
+	flagsAndFragOff := (h.FragOff & 0x1fff) | int(h.Flags<<13)
 	if supportsNewIPInput {
 		b[posTotalLen], b[posTotalLen+1] = byte(h.TotalLen>>8), byte(h.TotalLen)
-		b[posFragOff], b[posFragOff+1] = byte(h.FragOff>>8), byte(h.FragOff)
+		b[posFragOff], b[posFragOff+1] = byte(flagsAndFragOff>>8), byte(flagsAndFragOff)
 	} else {
 		*(*uint16)(unsafe.Pointer(&b[posTotalLen : posTotalLen+1][0])) = uint16(h.TotalLen)
-		*(*uint16)(unsafe.Pointer(&b[posFragOff : posFragOff+1][0])) = uint16(h.FragOff)
+		*(*uint16)(unsafe.Pointer(&b[posFragOff : posFragOff+1][0])) = uint16(flagsAndFragOff)
 	}
 	b[posID], b[posID+1] = byte(h.ID>>8), byte(h.ID)
 	b[posTTL] = byte(h.TTL)
@@ -135,6 +142,8 @@ func ParseHeader(b []byte) (*Header, error) {
 		h.TotalLen += hdrlen
 		h.FragOff = int(*(*uint16)(unsafe.Pointer(&b[posFragOff : posFragOff+1][0])))
 	}
+	h.Flags = HeaderFlags(h.FragOff&0xe000) >> 13
+	h.FragOff = h.FragOff & 0x1fff
 	h.ID = int(b[posID])<<8 | int(b[posID+1])
 	h.TTL = int(b[posTTL])
 	h.Protocol = int(b[posProtocol])

+ 5 - 4
third_party/code.google.com/p/go.net/ipv4/header_test.go

@@ -16,28 +16,28 @@ import (
 var (
 	wireHeaderFromKernel = [ipv4.HeaderLen]byte{
 		0x45, 0x01, 0xbe, 0xef,
-		0xca, 0xfe, 0x05, 0xdc,
+		0xca, 0xfe, 0x45, 0xdc,
 		0xff, 0x01, 0xde, 0xad,
 		172, 16, 254, 254,
 		192, 168, 0, 1,
 	}
 	wireHeaderToKernel = [ipv4.HeaderLen]byte{
 		0x45, 0x01, 0xbe, 0xef,
-		0xca, 0xfe, 0x05, 0xdc,
+		0xca, 0xfe, 0x45, 0xdc,
 		0xff, 0x01, 0xde, 0xad,
 		172, 16, 254, 254,
 		192, 168, 0, 1,
 	}
 	wireHeaderFromTradBSDKernel = [ipv4.HeaderLen]byte{
 		0x45, 0x01, 0xdb, 0xbe,
-		0xca, 0xfe, 0xdc, 0x05,
+		0xca, 0xfe, 0xdc, 0x45,
 		0xff, 0x01, 0xde, 0xad,
 		172, 16, 254, 254,
 		192, 168, 0, 1,
 	}
 	wireHeaderToTradBSDKernel = [ipv4.HeaderLen]byte{
 		0x45, 0x01, 0xef, 0xbe,
-		0xca, 0xfe, 0xdc, 0x05,
+		0xca, 0xfe, 0xdc, 0x45,
 		0xff, 0x01, 0xde, 0xad,
 		172, 16, 254, 254,
 		192, 168, 0, 1,
@@ -51,6 +51,7 @@ var (
 		TOS:      1,
 		TotalLen: 0xbeef,
 		ID:       0xcafe,
+		Flags:    ipv4.DontFragment,
 		FragOff:  1500,
 		TTL:      255,
 		Protocol: 1,

+ 2 - 2
third_party/code.google.com/p/go.net/ipv4/iana_test.go

@@ -1,9 +1,9 @@
-// go run gentv.go
+// go run gentest.go
 // GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
 
 package ipv4_test
 
-// Differentiated Services Field Codepoints, Updated: 2010-05-11
+// Differentiated Services Field Codepoints (DSCP), Updated: 2013-06-25
 const (
 	DiffServCS0        = 0x0  // CS0
 	DiffServCS1        = 0x20 // CS1

+ 20 - 26
third_party/code.google.com/p/go.net/ipv6/gen.go

@@ -97,20 +97,16 @@ func parseICMPv6Parameters(w io.Writer, r io.Reader) error {
 }
 
 type icmpv6Parameters struct {
-	XMLName    xml.Name              `xml:"registry"`
-	Title      string                `xml:"title"`
-	Updated    string                `xml:"updated"`
-	Registries []icmpv6ParamRegistry `xml:"registry"`
-}
-
-type icmpv6ParamRegistry struct {
-	Title   string              `xml:"title"`
-	Records []icmpv6ParamRecord `xml:"record"`
-}
-
-type icmpv6ParamRecord struct {
-	Value string `xml:"value"`
-	Name  string `xml:"name"`
+	XMLName    xml.Name `xml:"registry"`
+	Title      string   `xml:"title"`
+	Updated    string   `xml:"updated"`
+	Registries []struct {
+		Title   string `xml:"title"`
+		Records []struct {
+			Value string `xml:"value"`
+			Name  string `xml:"name"`
+		} `xml:"record"`
+	} `xml:"registry"`
 }
 
 type canonICMPv6ParamRecord struct {
@@ -188,18 +184,16 @@ func parseProtocolNumbers(w io.Writer, r io.Reader) error {
 }
 
 type protocolNumbers struct {
-	XMLName  xml.Name         `xml:"registry"`
-	Title    string           `xml:"title"`
-	Updated  string           `xml:"updated"`
-	RegTitle string           `xml:"registry>title"`
-	Note     string           `xml:"registry>note"`
-	Records  []protocolRecord `xml:"registry>record"`
-}
-
-type protocolRecord struct {
-	Value string `xml:"value"`
-	Name  string `xml:"name"`
-	Descr string `xml:"description"`
+	XMLName  xml.Name `xml:"registry"`
+	Title    string   `xml:"title"`
+	Updated  string   `xml:"updated"`
+	RegTitle string   `xml:"registry>title"`
+	Note     string   `xml:"registry>note"`
+	Records  []struct {
+		Value string `xml:"value"`
+		Name  string `xml:"name"`
+		Descr string `xml:"description"`
+	} `xml:"registry>record"`
 }
 
 type canonProtocolRecord struct {

+ 23 - 24
third_party/code.google.com/p/go.net/ipv6/gentest.go

@@ -39,7 +39,7 @@ var registries = []struct {
 
 func main() {
 	var bb bytes.Buffer
-	fmt.Fprintf(&bb, "// go run gentv.go\n")
+	fmt.Fprintf(&bb, "// go run gentest.go\n")
 	fmt.Fprintf(&bb, "// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT\n\n")
 	fmt.Fprintf(&bb, "package ipv6_test\n\n")
 	for _, r := range registries {
@@ -85,18 +85,19 @@ func parseDSCPRegistry(w io.Writer, r io.Reader) error {
 }
 
 type dscpRegistry struct {
-	XMLName     xml.Name     `xml:"registry"`
-	Title       string       `xml:"title"`
-	Updated     string       `xml:"updated"`
-	Note        string       `xml:"note"`
-	RegTitle    string       `xml:"registry>title"`
-	PoolRecords []dscpRecord `xml:"registry>record"`
-	Records     []dscpRecord `xml:"registry>registry>record"`
-}
-
-type dscpRecord struct {
-	Name  string `xml:"name"`
-	Space string `xml:"space"`
+	XMLName     xml.Name `xml:"registry"`
+	Title       string   `xml:"title"`
+	Updated     string   `xml:"updated"`
+	Note        string   `xml:"note"`
+	RegTitle    string   `xml:"registry>title"`
+	PoolRecords []struct {
+		Name  string `xml:"name"`
+		Space string `xml:"space"`
+	} `xml:"registry>record"`
+	Records []struct {
+		Name  string `xml:"name"`
+		Space string `xml:"space"`
+	} `xml:"registry>registry>record"`
 }
 
 type canonDSCPRecord struct {
@@ -145,17 +146,15 @@ func parseTOSTCByte(w io.Writer, r io.Reader) error {
 }
 
 type tosTCByte struct {
-	XMLName  xml.Name          `xml:"registry"`
-	Title    string            `xml:"title"`
-	Updated  string            `xml:"updated"`
-	Note     string            `xml:"note"`
-	RegTitle string            `xml:"registry>title"`
-	Records  []tosTCByteRecord `xml:"registry>record"`
-}
-
-type tosTCByteRecord struct {
-	Binary  string `xml:"binary"`
-	Keyword string `xml:"keyword"`
+	XMLName  xml.Name `xml:"registry"`
+	Title    string   `xml:"title"`
+	Updated  string   `xml:"updated"`
+	Note     string   `xml:"note"`
+	RegTitle string   `xml:"registry>title"`
+	Records  []struct {
+		Binary  string `xml:"binary"`
+		Keyword string `xml:"keyword"`
+	} `xml:"registry>record"`
 }
 
 type canonTOSTCByteRecord struct {

+ 2 - 2
third_party/code.google.com/p/go.net/ipv6/iana.go

@@ -3,7 +3,7 @@
 
 package ipv6
 
-// Internet Control Message Protocol version 6 (ICMPv6) Parameters, Updated: 2012-11-12
+// Internet Control Message Protocol version 6 (ICMPv6) Parameters, Updated: 2013-07-03
 const (
 	ICMPTypeDestinationUnreachable                ICMPType = 1   // Destination Unreachable
 	ICMPTypePacketTooBig                          ICMPType = 2   // Packet Too Big
@@ -41,7 +41,7 @@ const (
 	ICMPTypeDuplicateAddressConfirmation          ICMPType = 158 // Duplicate Address Confirmation
 )
 
-// Internet Control Message Protocol version 6 (ICMPv6) Parameters, Updated: 2012-11-12
+// Internet Control Message Protocol version 6 (ICMPv6) Parameters, Updated: 2013-07-03
 var icmpTypes = map[ICMPType]string{
 	1:   "destination unreachable",
 	2:   "packet too big",

+ 2 - 2
third_party/code.google.com/p/go.net/ipv6/iana_test.go

@@ -1,9 +1,9 @@
-// go run gentv.go
+// go run gentest.go
 // GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
 
 package ipv6_test
 
-// Differentiated Services Field Codepoints, Updated: 2010-05-11
+// Differentiated Services Field Codepoints (DSCP), Updated: 2013-06-25
 const (
 	DiffServCS0        = 0x0  // CS0
 	DiffServCS1        = 0x20 // CS1

+ 2 - 16
third_party/code.google.com/p/go.net/websocket/client.go

@@ -43,26 +43,12 @@ func NewConfig(server, origin string) (config *Config, err error) {
 func NewClient(config *Config, rwc io.ReadWriteCloser) (ws *Conn, err error) {
 	br := bufio.NewReader(rwc)
 	bw := bufio.NewWriter(rwc)
-	switch config.Version {
-	case ProtocolVersionHixie75:
-		err = hixie75ClientHandshake(config, br, bw)
-	case ProtocolVersionHixie76, ProtocolVersionHybi00:
-		err = hixie76ClientHandshake(config, br, bw)
-	case ProtocolVersionHybi08, ProtocolVersionHybi13:
-		err = hybiClientHandshake(config, br, bw)
-	default:
-		err = ErrBadProtocolVersion
-	}
+	err = hybiClientHandshake(config, br, bw)
 	if err != nil {
 		return
 	}
 	buf := bufio.NewReadWriter(br, bw)
-	switch config.Version {
-	case ProtocolVersionHixie75, ProtocolVersionHixie76, ProtocolVersionHybi00:
-		ws = newHixieClientConn(config, buf, rwc)
-	case ProtocolVersionHybi08, ProtocolVersionHybi13:
-		ws = newHybiClientConn(config, buf, rwc)
-	}
+	ws = newHybiClientConn(config, buf, rwc)
 	return
 }
 

+ 5 - 21
third_party/code.google.com/p/go.net/websocket/hybi.go

@@ -385,21 +385,8 @@ func getNonceAccept(nonce []byte) (expected []byte, err error) {
 	return
 }
 
-func isHybiVersion(version int) bool {
-	switch version {
-	case ProtocolVersionHybi08, ProtocolVersionHybi13:
-		return true
-	default:
-	}
-	return false
-}
-
 // Client handshake described in draft-ietf-hybi-thewebsocket-protocol-17
 func hybiClientHandshake(config *Config, br *bufio.Reader, bw *bufio.Writer) (err error) {
-	if !isHybiVersion(config.Version) {
-		panic("wrong protocol version.")
-	}
-
 	bw.WriteString("GET " + config.Location.RequestURI() + " HTTP/1.1\r\n")
 
 	bw.WriteString("Host: " + config.Location.Host + "\r\n")
@@ -410,11 +397,12 @@ func hybiClientHandshake(config *Config, br *bufio.Reader, bw *bufio.Writer) (er
 		nonce = []byte(config.handshakeData["key"])
 	}
 	bw.WriteString("Sec-WebSocket-Key: " + string(nonce) + "\r\n")
-	if config.Version == ProtocolVersionHybi13 {
-		bw.WriteString("Origin: " + strings.ToLower(config.Origin.String()) + "\r\n")
-	} else if config.Version == ProtocolVersionHybi08 {
-		bw.WriteString("Sec-WebSocket-Origin: " + strings.ToLower(config.Origin.String()) + "\r\n")
+	bw.WriteString("Origin: " + strings.ToLower(config.Origin.String()) + "\r\n")
+
+	if config.Version != ProtocolVersionHybi13 {
+		return ErrBadProtocolVersion
 	}
+
 	bw.WriteString("Sec-WebSocket-Version: " + fmt.Sprintf("%d", config.Version) + "\r\n")
 	if len(config.Protocol) > 0 {
 		bw.WriteString("Sec-WebSocket-Protocol: " + strings.Join(config.Protocol, ", ") + "\r\n")
@@ -500,8 +488,6 @@ func (c *hybiServerHandshaker) ReadHandshake(buf *bufio.Reader, req *http.Reques
 	switch version {
 	case "13":
 		c.Version = ProtocolVersionHybi13
-	case "8":
-		c.Version = ProtocolVersionHybi08
 	default:
 		return http.StatusBadRequest, ErrBadWebSocketVersion
 	}
@@ -536,8 +522,6 @@ func Origin(config *Config, req *http.Request) (*url.URL, error) {
 	switch config.Version {
 	case ProtocolVersionHybi13:
 		origin = req.Header.Get("Origin")
-	case ProtocolVersionHybi08:
-		origin = req.Header.Get("Sec-Websocket-Origin")
 	}
 	if origin == "null" {
 		return nil, nil

+ 0 - 108
third_party/code.google.com/p/go.net/websocket/hybi_test.go

@@ -157,68 +157,6 @@ Sec-WebSocket-Protocol: chat
 	}
 }
 
-func TestHybiClientHandshakeHybi08(t *testing.T) {
-	b := bytes.NewBuffer([]byte{})
-	bw := bufio.NewWriter(b)
-	br := bufio.NewReader(strings.NewReader(`HTTP/1.1 101 Switching Protocols
-Upgrade: websocket
-Connection: Upgrade
-Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
-Sec-WebSocket-Protocol: chat
-
-`))
-	var err error
-	config := new(Config)
-	config.Location, err = url.ParseRequestURI("ws://server.example.com/chat")
-	if err != nil {
-		t.Fatal("location url", err)
-	}
-	config.Origin, err = url.ParseRequestURI("http://example.com")
-	if err != nil {
-		t.Fatal("origin url", err)
-	}
-	config.Protocol = append(config.Protocol, "chat")
-	config.Protocol = append(config.Protocol, "superchat")
-	config.Version = ProtocolVersionHybi08
-
-	config.handshakeData = map[string]string{
-		"key": "dGhlIHNhbXBsZSBub25jZQ==",
-	}
-	err = hybiClientHandshake(config, br, bw)
-	if err != nil {
-		t.Errorf("handshake failed: %v", err)
-	}
-	req, err := http.ReadRequest(bufio.NewReader(b))
-	if err != nil {
-		t.Fatalf("read request: %v", err)
-	}
-	if req.Method != "GET" {
-		t.Errorf("request method expected GET, but got %q", req.Method)
-	}
-	if req.URL.Path != "/chat" {
-		t.Errorf("request path expected /demo, but got %q", req.URL.Path)
-	}
-	if req.Proto != "HTTP/1.1" {
-		t.Errorf("request proto expected HTTP/1.1, but got %q", req.Proto)
-	}
-	if req.Host != "server.example.com" {
-		t.Errorf("request Host expected example.com, but got %v", req.Host)
-	}
-	var expectedHeader = map[string]string{
-		"Connection":             "Upgrade",
-		"Upgrade":                "websocket",
-		"Sec-Websocket-Key":      config.handshakeData["key"],
-		"Sec-Websocket-Origin":   config.Origin.String(),
-		"Sec-Websocket-Protocol": "chat, superchat",
-		"Sec-Websocket-Version":  fmt.Sprintf("%d", ProtocolVersionHybi08),
-	}
-	for k, v := range expectedHeader {
-		if req.Header.Get(k) != v {
-			t.Errorf(fmt.Sprintf("%s expected %q but got %q", k, v, req.Header.Get(k)))
-		}
-	}
-}
-
 func TestHybiServerHandshake(t *testing.T) {
 	config := new(Config)
 	handshaker := &hybiServerHandshaker{Config: config}
@@ -314,52 +252,6 @@ Sec-WebSocket-Version: 13
 	}
 }
 
-func TestHybiServerHandshakeHybi08(t *testing.T) {
-	config := new(Config)
-	handshaker := &hybiServerHandshaker{Config: config}
-	br := bufio.NewReader(strings.NewReader(`GET /chat HTTP/1.1
-Host: server.example.com
-Upgrade: websocket
-Connection: Upgrade
-Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
-Sec-WebSocket-Origin: http://example.com
-Sec-WebSocket-Protocol: chat, superchat
-Sec-WebSocket-Version: 8
-
-`))
-	req, err := http.ReadRequest(br)
-	if err != nil {
-		t.Fatal("request", err)
-	}
-	code, err := handshaker.ReadHandshake(br, req)
-	if err != nil {
-		t.Errorf("handshake failed: %v", err)
-	}
-	if code != http.StatusSwitchingProtocols {
-		t.Errorf("status expected %q but got %q", http.StatusSwitchingProtocols, code)
-	}
-	b := bytes.NewBuffer([]byte{})
-	bw := bufio.NewWriter(b)
-
-	config.Protocol = []string{"chat"}
-
-	err = handshaker.AcceptHandshake(bw)
-	if err != nil {
-		t.Errorf("handshake response failed: %v", err)
-	}
-	expectedResponse := strings.Join([]string{
-		"HTTP/1.1 101 Switching Protocols",
-		"Upgrade: websocket",
-		"Connection: Upgrade",
-		"Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",
-		"Sec-WebSocket-Protocol: chat",
-		"", ""}, "\r\n")
-
-	if b.String() != expectedResponse {
-		t.Errorf("handshake expected %q but got %q", expectedResponse, b.String())
-	}
-}
-
 func TestHybiServerHandshakeHybiBadVersion(t *testing.T) {
 	config := new(Config)
 	handshaker := &hybiServerHandshaker{Config: config}

+ 0 - 8
third_party/code.google.com/p/go.net/websocket/server.go

@@ -22,14 +22,6 @@ func newServerConn(rwc io.ReadWriteCloser, buf *bufio.ReadWriter, req *http.Requ
 		buf.Flush()
 		return
 	}
-	if err != nil {
-		hs = &hixie76ServerHandshaker{Config: config}
-		code, err = hs.ReadHandshake(buf.Reader, req)
-	}
-	if err != nil {
-		hs = &hixie75ServerHandshaker{Config: config}
-		code, err = hs.ReadHandshake(buf.Reader, req)
-	}
 	if err != nil {
 		fmt.Fprintf(buf, "HTTP/1.1 %03d %s\r\n", code, http.StatusText(code))
 		buf.WriteString("\r\n")

+ 1 - 5
third_party/code.google.com/p/go.net/websocket/websocket.go

@@ -21,13 +21,9 @@ import (
 )
 
 const (
-	ProtocolVersionHixie75   = -75
-	ProtocolVersionHixie76   = -76
-	ProtocolVersionHybi00    = 0
-	ProtocolVersionHybi08    = 8
 	ProtocolVersionHybi13    = 13
 	ProtocolVersionHybi      = ProtocolVersionHybi13
-	SupportedProtocolVersion = "13, 8"
+	SupportedProtocolVersion = "13"
 
 	ContinuationFrame = 0
 	TextFrame         = 1

+ 14 - 0
third_party/code.google.com/p/go.net/websocket/websocket_test.go

@@ -286,6 +286,20 @@ func TestTrailingSpaces(t *testing.T) {
 	}
 }
 
+func TestDialConfigBadVersion(t *testing.T) {
+	once.Do(startServer)
+	config := newConfig(t, "/echo")
+	config.Version = 1234
+
+	_, err := DialConfig(config)
+
+	if dialerr, ok := err.(*DialError); ok {
+		if dialerr.Err != ErrBadProtocolVersion {
+			t.Errorf("dial expected err %q but got %q", ErrBadProtocolVersion, dialerr.Err)
+		}
+	}
+}
+
 func TestSmallBuffer(t *testing.T) {
 	// http://code.google.com/p/go/issues/detail?id=1145
 	// Read should be able to handle reading a fragment of a frame.

+ 17 - 4
third_party/github.com/coreos/go-etcd/etcd/client.go

@@ -36,12 +36,16 @@ type Client struct {
 }
 
 // Setup a basic conf and cluster
-func NewClient() *Client {
+func NewClient(machines []string) *Client {
+	// if an empty slice was sent in then just assume localhost
+	if len(machines) == 0 {
+		machines = []string{"http://127.0.0.1:4001"}
+	}
 
 	// default leader and machines
 	cluster := Cluster{
-		Leader:   "http://127.0.0.1:4001",
-		Machines: []string{"http://127.0.0.1:4001"},
+		Leader:   machines[0],
+		Machines: machines,
 	}
 
 	config := Config{
@@ -107,6 +111,10 @@ func (c *Client) SetCluster(machines []string) bool {
 	return success
 }
 
+func (c *Client) GetCluster() []string {
+	return c.cluster.Machines
+}
+
 // sycn cluster information using the existing machine list
 func (c *Client) SyncCluster() bool {
 	success := c.internalSyncCluster(c.cluster.Machines)
@@ -128,14 +136,16 @@ func (c *Client) internalSyncCluster(machines []string) bool {
 				// try another machine in the cluster
 				continue
 			}
+
 			// update Machines List
-			c.cluster.Machines = strings.Split(string(b), ",")
+			c.cluster.Machines = strings.Split(string(b), ", ")
 
 			// update leader
 			// the first one in the machine list is the leader
 			logger.Debugf("update.leader[%s,%s]", c.cluster.Leader, c.cluster.Machines[0])
 			c.cluster.Leader = c.cluster.Machines[0]
 
+			logger.Debug("sync.machines ", c.cluster.Machines)
 			return true
 		}
 	}
@@ -146,6 +156,9 @@ func (c *Client) internalSyncCluster(machines []string) bool {
 func (c *Client) createHttpPath(serverName string, _path string) string {
 	u, _ := url.Parse(serverName)
 	u.Path = path.Join(u.Path, "/", _path)
+	if u.Scheme == "" {
+		u.Scheme = "http"
+	}
 	return u.String()
 }
 

+ 21 - 1
third_party/github.com/coreos/go-etcd/etcd/client_test.go

@@ -3,6 +3,8 @@ package etcd
 import (
 	"fmt"
 	"testing"
+	"net/url"
+	"net"
 )
 
 // To pass this test, we need to create a cluster of 3 machines
@@ -10,13 +12,31 @@ import (
 func TestSync(t *testing.T) {
 	fmt.Println("Make sure there are three nodes at 0.0.0.0:4001-4003")
 
-	c := NewClient()
+	c := NewClient(nil)
 
 	success := c.SyncCluster()
 	if !success {
 		t.Fatal("cannot sync machines")
 	}
 
+	for _, m := range(c.GetCluster()) {
+		u, err := url.Parse(m)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if u.Scheme != "http" {
+			t.Fatal("scheme must be http")
+		}
+		
+		host, _, err := net.SplitHostPort(u.Host)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if host != "127.0.0.1" {
+			t.Fatal("Host must be 127.0.0.1")
+		}
+	}
+
 	badMachines := []string{"abc", "edef"}
 
 	success = c.SetCluster(badMachines)

+ 1 - 1
third_party/github.com/coreos/go-etcd/etcd/delete_test.go

@@ -6,7 +6,7 @@ import (
 
 func TestDelete(t *testing.T) {
 
-	c := NewClient()
+	c := NewClient(nil)
 
 	c.Set("foo", "bar", 100)
 	result, err := c.Delete("foo")

+ 1 - 1
third_party/github.com/coreos/go-etcd/etcd/get_test.go

@@ -7,7 +7,7 @@ import (
 
 func TestGet(t *testing.T) {
 
-	c := NewClient()
+	c := NewClient(nil)
 
 	c.Set("foo", "bar", 100)
 

+ 1 - 1
third_party/github.com/coreos/go-etcd/etcd/list_test.go

@@ -6,7 +6,7 @@ import (
 )
 
 func TestList(t *testing.T) {
-	c := NewClient()
+	c := NewClient(nil)
 
 	c.Set("foo_list/foo", "bar", 100)
 	c.Set("foo_list/fooo", "barbar", 100)

+ 1 - 1
third_party/github.com/coreos/go-etcd/etcd/set_test.go

@@ -6,7 +6,7 @@ import (
 )
 
 func TestSet(t *testing.T) {
-	c := NewClient()
+	c := NewClient(nil)
 
 	result, err := c.Set("foo", "bar", 100)
 

+ 1 - 1
third_party/github.com/coreos/go-etcd/etcd/testAndSet_test.go

@@ -6,7 +6,7 @@ import (
 )
 
 func TestTestAndSet(t *testing.T) {
-	c := NewClient()
+	c := NewClient(nil)
 
 	c.Set("foo_testAndSet", "bar", 100)
 

+ 6 - 1
third_party/github.com/coreos/go-etcd/etcd/watch.go

@@ -16,6 +16,11 @@ type respAndErr struct {
 	err  error
 }
 
+// Errors introduced by the Watch command.
+var (
+	ErrWatchStoppedByUser = errors.New("Watch stopped by the user via stop channel")
+)
+
 // Watch any change under the given prefix.
 // When a sinceIndex is given, watch will try to scan from that index to the last index
 // and will return any changes under the given prefix during the history
@@ -66,7 +71,7 @@ func (c *Client) watchOnce(key string, sinceIndex uint64, stop chan bool) (*stor
 			resp, err = res.resp, res.err
 
 		case <-stop:
-			resp, err = nil, errors.New("User stoped watch")
+			resp, err = nil, ErrWatchStoppedByUser
 		}
 	} else {
 		resp, err = c.sendWatchRequest(key, sinceIndex)

+ 7 - 4
third_party/github.com/coreos/go-etcd/etcd/watch_test.go

@@ -8,7 +8,7 @@ import (
 )
 
 func TestWatch(t *testing.T) {
-	c := NewClient()
+	c := NewClient(nil)
 
 	go setHelper("bar", c)
 
@@ -35,9 +35,12 @@ func TestWatch(t *testing.T) {
 
 	go setLoop("bar", c)
 
-	go reciver(ch, stop)
+	go receiver(ch, stop)
 
-	c.Watch("watch_foo", 0, ch, stop)
+	_, err = c.Watch("watch_foo", 0, ch, stop)
+	if err != ErrWatchStoppedByUser {
+		t.Fatalf("Watch returned a non-user stop error")
+	}
 }
 
 func setHelper(value string, c *Client) {
@@ -54,7 +57,7 @@ func setLoop(value string, c *Client) {
 	}
 }
 
-func reciver(c chan *store.Response, stop chan bool) {
+func receiver(c chan *store.Response, stop chan bool) {
 	for i := 0; i < 10; i++ {
 		<-c
 	}

+ 3 - 0
third_party/github.com/coreos/go-etcd/examples/sync-cluster/README.md

@@ -0,0 +1,3 @@
+Example script from the sync-cluster bug https://github.com/coreos/go-etcd/issues/27
+
+TODO: turn this into a test case

+ 51 - 0
third_party/github.com/coreos/go-etcd/examples/sync-cluster/sync-cluster.go

@@ -0,0 +1,51 @@
+
+package main
+
+import (
+	"fmt"
+	"github.com/coreos/go-etcd/etcd"
+	"strconv"
+	"time"
+)
+
+func main() {
+	fmt.Println("etcd-client started")
+	c := etcd.NewClient(nil)
+	c.SetCluster([]string{
+		"http://127.0.0.1:4001",
+		"http://127.0.0.1:4002",
+		"http://127.0.0.1:4003",
+	})
+
+	ticker := time.NewTicker(time.Second * 3)
+
+	for {
+		select {
+		case d := <-ticker.C:
+			n := d.Second()
+			if n <= 0 {
+				n = 60
+			}
+
+			for ok := c.SyncCluster(); ok == false; {
+				fmt.Println("SyncCluster failed, trying again")
+				time.Sleep(100 * time.Millisecond)
+			}
+
+			result, err := c.Set("foo", "exp_"+strconv.Itoa(n), 0)
+			if err != nil {
+				fmt.Println("set error", err)
+			} else {
+				fmt.Printf("set %+v\n", result)
+			}
+
+			ss, err := c.Get("foo")
+			if err != nil {
+				fmt.Println("get error", err)
+			} else {
+				fmt.Println(len(ss))
+			}
+
+		}
+	}
+}

+ 16 - 14
third_party/github.com/coreos/go-log/log/commands.go

@@ -1,6 +1,5 @@
 package log
-
-// Copyright 2013, David Fisher. All rights reserved.
+// Copyright 2013, CoreOS, Inc. All rights reserved.
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -43,6 +42,7 @@ func (logger *Logger) Logf(priority Priority, format string, v ...interface{}) {
 	logger.Log(priority, fmt.Sprintf(format, v...))
 }
 
+
 func (logger *Logger) Emergency(v ...interface{}) {
 	logger.Log(PriEmerg, v...)
 }
@@ -99,6 +99,7 @@ func (logger *Logger) Debugf(format string, v ...interface{}) {
 	logger.Log(PriDebug, fmt.Sprintf(format, v...))
 }
 
+
 func Emergency(v ...interface{}) {
 	defaultLogger.Log(PriEmerg, v...)
 }
@@ -157,56 +158,57 @@ func Debugf(format string, v ...interface{}) {
 
 // Standard library log functions
 
-func (logger *Logger) Fatalln(v ...interface{}) {
+func (logger *Logger)Fatalln (v ...interface{}) {
 	logger.Log(PriCrit, v...)
 	os.Exit(1)
 }
-func (logger *Logger) Fatalf(format string, v ...interface{}) {
+func (logger *Logger)Fatalf (format string, v ...interface{}) {
 	logger.Logf(PriCrit, format, v...)
 	os.Exit(1)
 }
 
-func (logger *Logger) Panicln(v ...interface{}) {
+func (logger *Logger)Panicln (v ...interface{}) {
 	s := fmt.Sprint(v...)
 	logger.Log(PriErr, s)
 	panic(s)
 }
-func (logger *Logger) Panicf(format string, v ...interface{}) {
+func (logger *Logger)Panicf (format string, v ...interface{}) {
 	s := fmt.Sprintf(format, v...)
 	logger.Log(PriErr, s)
 	panic(s)
 }
 
-func (logger *Logger) Println(v ...interface{}) {
+func (logger *Logger)Println (v ...interface{}) {
 	logger.Log(PriInfo, v...)
 }
-func (logger *Logger) Printf(format string, v ...interface{}) {
+func (logger *Logger)Printf (format string, v ...interface{}) {
 	logger.Logf(PriInfo, format, v...)
 }
 
-func Fatalln(v ...interface{}) {
+
+func Fatalln (v ...interface{}) {
 	defaultLogger.Log(PriCrit, v...)
 	os.Exit(1)
 }
-func Fatalf(format string, v ...interface{}) {
+func Fatalf (format string, v ...interface{}) {
 	defaultLogger.Logf(PriCrit, format, v...)
 	os.Exit(1)
 }
 
-func Panicln(v ...interface{}) {
+func Panicln (v ...interface{}) {
 	s := fmt.Sprint(v...)
 	defaultLogger.Log(PriErr, s)
 	panic(s)
 }
-func Panicf(format string, v ...interface{}) {
+func Panicf (format string, v ...interface{}) {
 	s := fmt.Sprintf(format, v...)
 	defaultLogger.Log(PriErr, s)
 	panic(s)
 }
 
-func Println(v ...interface{}) {
+func Println (v ...interface{}) {
 	defaultLogger.Log(PriInfo, v...)
 }
-func Printf(format string, v ...interface{}) {
+func Printf (format string, v ...interface{}) {
 	defaultLogger.Logf(PriInfo, format, v...)
 }

+ 1 - 2
third_party/github.com/coreos/go-log/log/fields.go

@@ -1,6 +1,5 @@
 package log
-
-// Copyright 2013, David Fisher. All rights reserved.
+// Copyright 2013, CoreOS, Inc. All rights reserved.
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.

+ 1 - 2
third_party/github.com/coreos/go-log/log/logger.go

@@ -1,6 +1,5 @@
 package log
-
-// Copyright 2013, David Fisher. All rights reserved.
+// Copyright 2013, CoreOS, Inc. All rights reserved.
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.

+ 1 - 2
third_party/github.com/coreos/go-log/log/priority.go

@@ -1,6 +1,5 @@
 package log
-
-// Copyright 2013, David Fisher. All rights reserved.
+// Copyright 2013, CoreOS, Inc. All rights reserved.
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.

+ 1 - 2
third_party/github.com/coreos/go-log/log/sinks.go

@@ -1,6 +1,5 @@
 package log
-
-// Copyright 2013, David Fisher. All rights reserved.
+// Copyright 2013, CoreOS, Inc. All rights reserved.
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.

+ 1 - 1
third_party/github.com/coreos/go-raft/server.go

@@ -854,7 +854,7 @@ func (s *Server) processAppendEntriesResponse(resp *AppendEntriesResponse) {
 	for _, peer := range s.peers {
 		indices = append(indices, peer.getPrevLogIndex())
 	}
-	sort.Sort(uint64Slice(indices))
+	sort.Sort(sort.Reverse(uint64Slice(indices)))
 
 	// We can commit up to the index which the majority of the members have appended.
 	commitIndex := indices[s.QuorumSize()-1]

+ 2 - 1
third_party/github.com/coreos/go-systemd/activation/files.go

@@ -1,3 +1,4 @@
+// Package activation implements primitives for systemd socket activation.
 package activation
 
 import (
@@ -23,7 +24,7 @@ func Files() []*os.File {
 	files := []*os.File(nil)
 	for fd := listenFdsStart; fd < listenFdsStart+nfds; fd++ {
 		syscall.CloseOnExec(fd)
-		files = append(files, os.NewFile(uintptr(fd), "LISTEN_FD_"+strconv.Itoa(fd)))
+		files = append(files, os.NewFile(uintptr(fd), "LISTEN_FD_" + strconv.Itoa(fd)))
 	}
 	return files
 }

+ 100 - 0
third_party/github.com/coreos/go-systemd/dbus/dbus.go

@@ -0,0 +1,100 @@
+// Integration with the systemd D-Bus API.  See http://www.freedesktop.org/wiki/Software/systemd/dbus/
+package dbus
+
+import (
+	"github.com/guelfey/go.dbus"
+	"sync"
+)
+
+const signalBuffer = 100
+
+type Conn struct {
+	sysconn     *dbus.Conn
+	sysobj      *dbus.Object
+	jobListener struct {
+		jobs map[dbus.ObjectPath]chan string
+		sync.Mutex
+	}
+	subscriber struct {
+		updateCh chan<- *SubStateUpdate
+		errCh    chan<- error
+		sync.Mutex
+		ignore      map[dbus.ObjectPath]int64
+		cleanIgnore int64
+	}
+	dispatch map[string]func(dbus.Signal)
+}
+
+func New() *Conn {
+	c := new(Conn)
+	c.initConnection()
+	c.initJobs()
+	c.initSubscription()
+	c.initDispatch()
+	return c
+}
+
+func (c *Conn) initConnection() {
+	var err error
+	c.sysconn, err = dbus.SystemBusPrivate()
+	if err != nil {
+		return
+	}
+
+	err = c.sysconn.Auth(nil)
+	if err != nil {
+		c.sysconn.Close()
+		return
+	}
+
+	err = c.sysconn.Hello()
+	if err != nil {
+		c.sysconn.Close()
+		return
+	}
+
+	c.sysobj = c.sysconn.Object("org.freedesktop.systemd1", dbus.ObjectPath("/org/freedesktop/systemd1"))
+
+	c.sysconn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0,
+		"type='signal',interface='org.freedesktop.systemd1.Manager',member='JobRemoved'")
+	c.sysconn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0,
+		"type='signal',interface='org.freedesktop.systemd1.Manager',member='UnitNew'")
+	c.sysconn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0,
+		"type='signal',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged'")
+
+	err = c.sysobj.Call("org.freedesktop.systemd1.Manager.Subscribe", 0).Store()
+	if err != nil {
+		c.sysconn.Close()
+		return
+	}
+}
+
+func (c *Conn) initDispatch() {
+	ch := make(chan *dbus.Signal, signalBuffer)
+
+	c.sysconn.Signal(ch)
+
+	go func() {
+		for {
+			signal := <-ch
+			switch signal.Name {
+			case "org.freedesktop.systemd1.Manager.JobRemoved":
+				c.jobComplete(signal)
+
+				unitName := signal.Body[2].(string)
+				var unitPath dbus.ObjectPath
+				c.sysobj.Call("GetUnit", 0, unitName).Store(&unitPath)
+				if unitPath != dbus.ObjectPath("") {
+					c.sendSubStateUpdate(unitPath)
+				}
+			case "org.freedesktop.systemd1.Manager.UnitNew":
+				c.sendSubStateUpdate(signal.Body[1].(dbus.ObjectPath))
+			case "org.freedesktop.DBus.Properties.PropertiesChanged":
+				if signal.Body[0].(string) == "org.freedesktop.systemd1.Unit" {
+					// we only care about SubState updates, which are a Unit property
+					c.sendSubStateUpdate(signal.Path)
+				}
+			}
+		}
+	}()
+}

+ 166 - 0
third_party/github.com/coreos/go-systemd/dbus/methods.go

@@ -0,0 +1,166 @@
+package dbus
+
+import (
+	"github.com/guelfey/go.dbus"
+)
+
+func (c *Conn) initJobs() {
+	c.jobListener.jobs = make(map[dbus.ObjectPath]chan string)
+}
+
+func (c *Conn) jobComplete(signal *dbus.Signal) {
+	var id uint32
+	var job dbus.ObjectPath
+	var unit string
+	var result string
+	dbus.Store(signal.Body, &id, &job, &unit, &result)
+	c.jobListener.Lock()
+	out, ok := c.jobListener.jobs[job]
+	if ok {
+		out <- result
+	}
+	c.jobListener.Unlock()
+}
+
+func (c *Conn) startJob(job string, args ...interface{}) (<-chan string, error) {
+	c.jobListener.Lock()
+	defer c.jobListener.Unlock()
+
+	ch := make(chan string, 1)
+	var path dbus.ObjectPath
+	err := c.sysobj.Call(job, 0, args...).Store(&path)
+	if err != nil {
+		return nil, err
+	}
+	c.jobListener.jobs[path] = ch
+	return ch, nil
+}
+
+func (c *Conn) runJob(job string, args ...interface{}) (string, error) {
+	respCh, err := c.startJob(job, args...)
+	if err != nil {
+		return "", err
+	}
+	return <-respCh, nil
+}
+
+// StartUnit enqeues a start job and depending jobs, if any (unless otherwise
+// specified by the mode string).
+//
+// Takes the unit to activate, plus a mode string. The mode needs to be one of
+// replace, fail, isolate, ignore-dependencies, ignore-requirements. If
+// "replace" the call will start the unit and its dependencies, possibly
+// replacing already queued jobs that conflict with this. If "fail" the call
+// will start the unit and its dependencies, but will fail if this would change
+// an already queued job. If "isolate" the call will start the unit in question
+// and terminate all units that aren't dependencies of it. If
+// "ignore-dependencies" it will start a unit but ignore all its dependencies.
+// If "ignore-requirements" it will start a unit but only ignore the
+// requirement dependencies. It is not recommended to make use of the latter
+// two options.
+//
+// Result string: one of done, canceled, timeout, failed, dependency, skipped.
+// done indicates successful execution of a job. canceled indicates that a job
+// has been canceled  before it finished execution. timeout indicates that the
+// job timeout was reached. failed indicates that the job failed. dependency
+// indicates that a job this job has been depending on failed and the job hence
+// has been removed too. skipped indicates that a job was skipped because it
+// didn't apply to the units current state.
+func (c *Conn) StartUnit(name string, mode string) (string, error) {
+	return c.runJob("StartUnit", name, mode)
+}
+
+// StopUnit is similar to StartUnit but stops the specified unit rather
+// than starting it.
+func (c *Conn) StopUnit(name string, mode string) (string, error) {
+	return c.runJob("StopUnit", name, mode)
+}
+
+// ReloadUnit reloads a unit.  Reloading is done only if the unit is already running and fails otherwise.
+func (c *Conn) ReloadUnit(name string, mode string) (string, error) {
+	return c.runJob("ReloadUnit", name, mode)
+}
+
+// RestartUnit restarts a service.  If a service is restarted that isn't
+// running it will be started.
+func (c *Conn) RestartUnit(name string, mode string) (string, error) {
+	return c.runJob("RestartUnit", name, mode)
+}
+
+// TryRestartUnit is like RestartUnit, except that a service that isn't running
+// is not affected by the restart.
+func (c *Conn) TryRestartUnit(name string, mode string) (string, error) {
+	return c.runJob("TryRestartUnit", name, mode)
+}
+
+// ReloadOrRestart attempts a reload if the unit supports it and use a restart
+// otherwise.
+func (c *Conn) ReloadOrRestartUnit(name string, mode string) (string, error) {
+	return c.runJob("ReloadOrRestartUnit", name, mode)
+}
+
+// ReloadOrTryRestart attempts a reload if the unit supports it and use a "Try"
+// flavored restart otherwise.
+func (c *Conn) ReloadOrTryRestartUnit(name string, mode string) (string, error) {
+	return c.runJob("ReloadOrTryRestartUnit", name, mode)
+}
+
+// StartTransientUnit() may be used to create and start a transient unit, which
+// will be released as soon as it is not running or referenced anymore or the
+// system is rebooted. name is the unit name including suffix, and must be
+// unique. mode is the same as in StartUnit(), properties contains properties
+// of the unit.
+func (c *Conn) StartTransientUnit(name string, mode string, properties ...Property) (string, error) {
+	// the dbus interface for this method does not use the last argument and
+	// should simply be given an empty list.  We use a concrete type here
+	// (instead of the more appropriate interface{}) to satisfy the dbus library.
+	return c.runJob("StartTransientUnit", name, mode, properties, make([]string, 0))
+}
+
+// KillUnit takes the unit name and a UNIX signal number to send.  All of the unit's
+// processes are killed.
+func (c *Conn) KillUnit(name string, signal int32) {
+	c.sysobj.Call("KillUnit", 0, name, "all", signal).Store()
+}
+
+// ListUnits returns an array with all currently loaded units. Note that
+// units may be known by multiple names at the same time, and hence there might
+// be more unit names loaded than actual units behind them.
+func (c *Conn) ListUnits() ([]UnitStatus, error) {
+	result := make([][]interface{}, 0)
+	err := c.sysobj.Call("ListUnits", 0).Store(&result)
+	if err != nil {
+		return nil, err
+	}
+
+	resultInterface := make([]interface{}, len(result))
+	for i := range result {
+		resultInterface[i] = result[i]
+	}
+
+	status := make([]UnitStatus, len(result))
+	statusInterface := make([]interface{}, len(status))
+	for i := range status {
+		statusInterface[i] = &status[i]
+	}
+
+	err = dbus.Store(resultInterface, statusInterface...)
+	if err != nil {
+		return nil, err
+	}
+
+	return status, nil
+}
+
+type UnitStatus struct {
+	Name        string          // The primary unit name as string
+	Description string          // The human readable description string
+	LoadState   string          // The load state (i.e. whether the unit file has been loaded successfully)
+	ActiveState string          // The active state (i.e. whether the unit is currently started or not)
+	SubState    string          // The sub state (a more fine-grained version of the active state that is specific to the unit type, which the active state is not)
+	Followed    string          // A unit that is being followed in its state by this unit, if there is any, otherwise the empty string.
+	Path        dbus.ObjectPath // The unit object path
+	JobId       uint32          // If there is a job queued for the job unit the numeric job id, 0 otherwise
+	JobType     string          // The job type as string
+	JobPath     dbus.ObjectPath // The job object path
+}

+ 193 - 0
third_party/github.com/coreos/go-systemd/dbus/properties.go

@@ -0,0 +1,193 @@
+package dbus
+
+import (
+	"github.com/guelfey/go.dbus"
+)
+
+// From the systemd docs:
+//
+// The properties array of StartTransientUnit() may take many of the settings
+// that may also be configured in unit files. Not all parameters are currently
+// accepted though, but we plan to cover more properties with future release.
+// Currently you may set the Description, Slice and all dependency types of
+// units, as well as RemainAfterExit, ExecStart for service units,
+// TimeoutStopUSec and PIDs for scope units, and CPUAccounting, CPUShares,
+// BlockIOAccounting, BlockIOWeight, BlockIOReadBandwidth,
+// BlockIOWriteBandwidth, BlockIODeviceWeight, MemoryAccounting, MemoryLimit,
+// DevicePolicy, DeviceAllow for services/scopes/slices. These fields map
+// directly to their counterparts in unit files and as normal D-Bus object
+// properties. The exception here is the PIDs field of scope units which is
+// used for construction of the scope only and specifies the initial PIDs to
+// add to the scope object.
+
+type Property property
+
+type property struct {
+	Name  string
+	Value dbus.Variant
+}
+
+type execStart struct {
+	Path             string   // the binary path to execute
+	Args             []string // an array with all arguments to pass to the executed command, starting with argument 0
+	UncleanIsFailure bool     // a boolean whether it should be considered a failure if the process exits uncleanly
+}
+
+// PropExecStart sets the ExecStart service property.  The first argument is a
+// slice with the binary path to execute followed by the arguments to pass to
+// the executed command. See
+// http://www.freedesktop.org/software/systemd/man/systemd.service.html#ExecStart=
+func PropExecStart(command []string, uncleanIsFailure bool) Property {
+	return Property(
+		property{
+			Name: "ExecStart",
+			Value: dbus.MakeVariant(
+				[]execStart{
+					execStart{
+						Path:             command[0],
+						Args:             command,
+						UncleanIsFailure: uncleanIsFailure,
+					}})})
+}
+
+// PropRemainAfterExit sets the RemainAfterExit service property. See
+// http://www.freedesktop.org/software/systemd/man/systemd.service.html#RemainAfterExit=
+func PropRemainAfterExit(b bool) Property {
+	return Property(
+		property{
+			Name:  "RemainAfterExit",
+			Value: dbus.MakeVariant(b),
+		})
+}
+
+// PropDescription sets the Description unit property. See
+// http://www.freedesktop.org/software/systemd/man/systemd.unit#Description=
+func PropDescription(desc string) Property {
+	return Property(
+		property{
+			Name:  "Description",
+			Value: dbus.MakeVariant(desc),
+		})
+}
+
+func propDependency(name string, units []string) Property {
+	return Property(
+		property{
+			Name:  name,
+			Value: dbus.MakeVariant(units),
+		})
+}
+
+// PropRequires sets the Requires unit property.  See
+// http://www.freedesktop.org/software/systemd/main/systemd.unit.html#Requires=
+func PropRequires(units ...string) Property {
+	return propDependency("Requires", units)
+}
+
+// PropRequiresOverridable sets the RequiresOverridable unit property.  See
+// http://www.freedesktop.org/software/systemd/main/systemd.unit.html#RequiresOverridable=
+func PropRequiresOverridable(units ...string) Property {
+	return propDependency("RequiresOverridable", units)
+}
+
+// PropRequisite sets the Requisite unit property.  See
+// http://www.freedesktop.org/software/systemd/main/systemd.unit.html#Requisite=
+func PropRequisite(units ...string) Property {
+	return propDependency("Requisite", units)
+}
+
+// PropRequisiteOverridable sets the RequisiteOverridable unit property.  See
+// http://www.freedesktop.org/software/systemd/main/systemd.unit.html#RequisiteOverridable=
+func PropRequisiteOverridable(units ...string) Property {
+	return propDependency("RequisiteOverridable", units)
+}
+
+// PropWants sets the Wants unit property.  See
+// http://www.freedesktop.org/software/systemd/main/systemd.unit.html#Wants=
+func PropWants(units ...string) Property {
+	return propDependency("Wants", units)
+}
+
+// PropBindsTo sets the BindsTo unit property.  See
+// http://www.freedesktop.org/software/systemd/main/systemd.unit.html#BindsTo=
+func PropBindsTo(units ...string) Property {
+	return propDependency("BindsTo", units)
+}
+
+// PropRequiredBy sets the RequiredBy unit property.  See
+// http://www.freedesktop.org/software/systemd/main/systemd.unit.html#RequiredBy=
+func PropRequiredBy(units ...string) Property {
+	return propDependency("RequiredBy", units)
+}
+
+// PropRequiredByOverridable sets the RequiredByOverridable unit property.  See
+// http://www.freedesktop.org/software/systemd/main/systemd.unit.html#RequiredByOverridable=
+func PropRequiredByOverridable(units ...string) Property {
+	return propDependency("RequiredByOverridable", units)
+}
+
+// PropWantedBy sets the WantedBy unit property.  See
+// http://www.freedesktop.org/software/systemd/main/systemd.unit.html#WantedBy=
+func PropWantedBy(units ...string) Property {
+	return propDependency("WantedBy", units)
+}
+
+// PropBoundBy sets the BoundBy unit property.  See
+// http://www.freedesktop.org/software/systemd/main/systemd.unit.html#BoundBy=
+func PropBoundBy(units ...string) Property {
+	return propDependency("BoundBy", units)
+}
+
+// PropConflicts sets the Conflicts unit property.  See
+// http://www.freedesktop.org/software/systemd/main/systemd.unit.html#Conflicts=
+func PropConflicts(units ...string) Property {
+	return propDependency("Conflicts", units)
+}
+
+// PropConflictedBy sets the ConflictedBy unit property.  See
+// http://www.freedesktop.org/software/systemd/main/systemd.unit.html#ConflictedBy=
+func PropConflictedBy(units ...string) Property {
+	return propDependency("ConflictedBy", units)
+}
+
+// PropBefore sets the Before unit property.  See
+// http://www.freedesktop.org/software/systemd/main/systemd.unit.html#Before=
+func PropBefore(units ...string) Property {
+	return propDependency("Before", units)
+}
+
+// PropAfter sets the After unit property.  See
+// http://www.freedesktop.org/software/systemd/main/systemd.unit.html#After=
+func PropAfter(units ...string) Property {
+	return propDependency("After", units)
+}
+
+// PropOnFailure sets the OnFailure unit property.  See
+// http://www.freedesktop.org/software/systemd/main/systemd.unit.html#OnFailure=
+func PropOnFailure(units ...string) Property {
+	return propDependency("OnFailure", units)
+}
+
+// PropTriggers sets the Triggers unit property.  See
+// http://www.freedesktop.org/software/systemd/main/systemd.unit.html#Triggers=
+func PropTriggers(units ...string) Property {
+	return propDependency("Triggers", units)
+}
+
+// PropTriggeredBy sets the TriggeredBy unit property.  See
+// http://www.freedesktop.org/software/systemd/main/systemd.unit.html#TriggeredBy=
+func PropTriggeredBy(units ...string) Property {
+	return propDependency("TriggeredBy", units)
+}
+
+// PropPropagatesReloadTo sets the PropagatesReloadTo unit property.  See
+// http://www.freedesktop.org/software/systemd/main/systemd.unit.html#PropagatesReloadTo=
+func PropPropagatesReloadTo(units ...string) Property {
+	return propDependency("PropagatesReloadTo", units)
+}
+
+// PropRequiresMountsFor sets the RequiresMountsFor unit property.  See
+// http://www.freedesktop.org/software/systemd/main/systemd.unit.html#RequiresMountsFor=
+func PropRequiresMountsFor(units ...string) Property {
+	return propDependency("RequiresMountsFor", units)
+}

+ 182 - 0
third_party/github.com/coreos/go-systemd/dbus/subscription.go

@@ -0,0 +1,182 @@
+package dbus
+
+import (
+	"github.com/guelfey/go.dbus"
+	"time"
+)
+
+const (
+	cleanIgnoreInterval = int64(10 * time.Second)
+	ignoreInterval      = int64(30 * time.Millisecond)
+)
+
+func (c *Conn) initSubscription() {
+	c.subscriber.ignore = make(map[dbus.ObjectPath]int64)
+}
+
+// Returns two unbuffered channels which will receive all changed units every
+// @interval@ seconds.  Deleted units are sent as nil.
+func (c *Conn) SubscribeUnits(interval time.Duration) (<-chan map[string]*UnitStatus, <-chan error) {
+	return c.SubscribeUnitsCustom(interval, 0, func(u1, u2 *UnitStatus) bool { return *u1 != *u2 })
+}
+
+// SubscribeUnitsCustom is like SubscribeUnits but lets you specify the buffer
+// size of the channels and the comparison function for detecting changes.
+func (c *Conn) SubscribeUnitsCustom(interval time.Duration, buffer int, isChanged func(*UnitStatus, *UnitStatus) bool) (<-chan map[string]*UnitStatus, <-chan error) {
+	old := make(map[string]*UnitStatus)
+	statusChan := make(chan map[string]*UnitStatus, buffer)
+	errChan := make(chan error, buffer)
+
+	go func() {
+		for {
+			timerChan := time.After(interval)
+
+			units, err := c.ListUnits()
+			if err == nil {
+				cur := make(map[string]*UnitStatus)
+				for i := range units {
+					cur[units[i].Name] = &units[i]
+				}
+
+				// add all new or changed units
+				changed := make(map[string]*UnitStatus)
+				for n, u := range cur {
+					if oldU, ok := old[n]; !ok || isChanged(oldU, u) {
+						changed[n] = u
+					}
+					delete(old, n)
+				}
+
+				// add all deleted units
+				for oldN := range old {
+					changed[oldN] = nil
+				}
+
+				old = cur
+
+				statusChan <- changed
+			} else {
+				errChan <- err
+			}
+
+			<-timerChan
+		}
+	}()
+
+	return statusChan, errChan
+}
+
+type SubStateUpdate struct {
+	UnitName string
+	SubState string
+}
+
+type Error string
+
+func (e Error) Error() string {
+	return string(e)
+}
+
+// SetSubStateSubscriber writes to updateCh when any unit's substate changes.
+// Althrough this writes to updateCh on every state change, the reported state
+// may be more recent than the change that generated it (due to an unavoidable
+// race in the systemd dbus interface).  That is, this method provides a good
+// way to keep a current view of all units' states, but is not guaranteed to
+// show every state transition they go through.  Furthermore, state changes
+// will only be written to the channel with non-blocking writes.  If updateCh
+// is full, it attempts to write an error to errCh; if errCh is full, the error
+// passes silently.
+func (c *Conn) SetSubStateSubscriber(updateCh chan<- *SubStateUpdate, errCh chan<- error) {
+	c.subscriber.Lock()
+	defer c.subscriber.Unlock()
+	c.subscriber.updateCh = updateCh
+	c.subscriber.errCh = errCh
+}
+
+func (c *Conn) sendSubStateUpdate(path dbus.ObjectPath) {
+	c.subscriber.Lock()
+	defer c.subscriber.Unlock()
+	if c.subscriber.updateCh == nil {
+		return
+	}
+
+	if c.shouldIgnore(path) {
+		return
+	}
+
+	info, err := c.getUnitInfo(path)
+	if err != nil {
+		select {
+		case c.subscriber.errCh <- err:
+		default:
+		}
+	}
+
+	name := info["Id"].Value().(string)
+	substate := info["SubState"].Value().(string)
+
+	update := &SubStateUpdate{name, substate}
+	select {
+	case c.subscriber.updateCh <- update:
+	default:
+		select {
+		case c.subscriber.errCh <- Error("update channel full!"):
+		default:
+		}
+	}
+
+	c.updateIgnore(path, info)
+}
+
+func (c *Conn) getUnitInfo(path dbus.ObjectPath) (map[string]dbus.Variant, error) {
+	var err error
+	var props map[string]dbus.Variant
+	obj := c.sysconn.Object("org.freedesktop.systemd1", path)
+	err = obj.Call("GetAll", 0, "org.freedesktop.systemd1.Unit").Store(&props)
+	if err != nil {
+		return nil, err
+	}
+	return props, nil
+}
+
+// The ignore functions work around a wart in the systemd dbus interface.
+// Requesting the properties of an unloaded unit will cause systemd to send a
+// pair of UnitNew/UnitRemoved signals.  Because we need to get a unit's
+// properties on UnitNew (as that's the only indication of a new unit coming up
+// for the first time), we would enter an infinite loop if we did not attempt
+// to detect and ignore these spurious signals.  The signal themselves are
+// indistinguishable from relevant ones, so we (somewhat hackishly) ignore an
+// unloaded unit's signals for a short time after requesting its properties.
+// This means that we will miss e.g. a transient unit being restarted
+// *immediately* upon failure and also a transient unit being started
+// immediately after requesting its status (with systemctl status, for example,
+// because this causes a UnitNew signal to be sent which then causes us to fetch
+// the properties).
+
+func (c *Conn) shouldIgnore(path dbus.ObjectPath) bool {
+	t, ok := c.subscriber.ignore[path]
+	return ok && t >= time.Now().UnixNano()
+}
+
+func (c *Conn) updateIgnore(path dbus.ObjectPath, info map[string]dbus.Variant) {
+	c.cleanIgnore()
+
+	// unit is unloaded - it will trigger bad systemd dbus behavior
+	if info["LoadState"].Value().(string) == "not-found" {
+		c.subscriber.ignore[path] = time.Now().UnixNano() + ignoreInterval
+	}
+}
+
+// without this, ignore would grow unboundedly over time
+func (c *Conn) cleanIgnore() {
+	now := time.Now().UnixNano()
+	if c.subscriber.cleanIgnore < now {
+		c.subscriber.cleanIgnore = now + cleanIgnoreInterval
+
+		for p, t := range c.subscriber.ignore {
+			if t < now {
+				delete(c.subscriber.ignore, p)
+			}
+		}
+	}
+}

+ 5 - 1
third_party/github.com/coreos/go-systemd/journal/send.go

@@ -32,7 +32,11 @@ const (
 var conn net.Conn
 
 func init() {
-	conn, _ = net.Dial("unixgram", "/run/systemd/journal/socket")
+	var err error
+	conn, err = net.Dial("unixgram", "/run/systemd/journal/socket")
+	if err != nil {
+		conn = nil
+	}
 }
 
 // Enabled returns true iff the systemd journal is available for logging