Browse Source

etcdmain: support sdnotify for readiness

Xiang Li 10 years ago
parent
commit
0cbac56fa2

+ 10 - 0
Godeps/Godeps.json

@@ -36,6 +36,16 @@
 			"ImportPath": "github.com/coreos/go-semver/semver",
 			"Rev": "568e959cd89871e61434c1143528d9162da89ef2"
 		},
+		{
+			"ImportPath": "github.com/coreos/go-systemd/daemon",
+			"Comment": "v3-6-gcea488b",
+			"Rev": "cea488b4e6855fee89b6c22a811e3c5baca861b6"
+		},
+		{
+			"ImportPath": "github.com/coreos/go-systemd/util",
+			"Comment": "v3-6-gcea488b",
+			"Rev": "cea488b4e6855fee89b6c22a811e3c5baca861b6"
+		},
 		{
 			"ImportPath": "github.com/coreos/pkg/capnslog",
 			"Rev": "99f6e6b8f8ea30b0f82769c1411691c44a66d015"

+ 31 - 0
Godeps/_workspace/src/github.com/coreos/go-systemd/daemon/sdnotify.go

@@ -0,0 +1,31 @@
+// Code forked from Docker project
+package daemon
+
+import (
+	"errors"
+	"net"
+	"os"
+)
+
+var SdNotifyNoSocket = errors.New("No socket")
+
+// SdNotify sends a message to the init daemon. It is common to ignore the error.
+func SdNotify(state string) error {
+	socketAddr := &net.UnixAddr{
+		Name: os.Getenv("NOTIFY_SOCKET"),
+		Net:  "unixgram",
+	}
+
+	if socketAddr.Name == "" {
+		return SdNotifyNoSocket
+	}
+
+	conn, err := net.DialUnix(socketAddr.Net, nil, socketAddr)
+	if err != nil {
+		return err
+	}
+	defer conn.Close()
+
+	_, err = conn.Write([]byte(state))
+	return err
+}

+ 33 - 0
Godeps/_workspace/src/github.com/coreos/go-systemd/util/util.go

@@ -0,0 +1,33 @@
+// 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 util contains utility functions related to systemd that applications
+// can use to check things like whether systemd is running.
+package util
+
+import (
+	"os"
+)
+
+// IsRunningSystemd checks whether the host was booted with systemd as its init
+// system. This functions similar to systemd's `sd_booted(3)`: internally, it
+// checks whether /run/systemd/system/ exists and is a directory.
+// http://www.freedesktop.org/software/systemd/man/sd_booted.html
+func IsRunningSystemd() bool {
+	fi, err := os.Lstat("/run/systemd/system")
+	if err != nil {
+		return false
+	}
+	return fi.IsDir()
+}

+ 17 - 3
etcdmain/etcd.go

@@ -27,6 +27,10 @@ import (
 	"strconv"
 	"time"
 
+	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/coreos/go-systemd/daemon"
+	systemdutil "github.com/coreos/etcd/Godeps/_workspace/src/github.com/coreos/go-systemd/util"
+	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/coreos/pkg/capnslog"
+	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus"
 	"github.com/coreos/etcd/discovery"
 	"github.com/coreos/etcd/etcdserver"
 	"github.com/coreos/etcd/etcdserver/etcdhttp"
@@ -37,9 +41,6 @@ import (
 	"github.com/coreos/etcd/pkg/types"
 	"github.com/coreos/etcd/proxy"
 	"github.com/coreos/etcd/rafthttp"
-
-	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/coreos/pkg/capnslog"
-	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus"
 )
 
 type dirType string
@@ -134,6 +135,19 @@ func Main() {
 
 	osutil.HandleInterrupts()
 
+	if systemdutil.IsRunningSystemd() {
+		// At this point, the initialization of etcd is done.
+		// The listeners are listening on the TCP ports and ready
+		// for accepting connections.
+		// The http server is probably ready for serving incoming
+		// connections. If it is not, the connection might be pending
+		// for less than one second.
+		err := daemon.SdNotify("READY=1")
+		if err != nil {
+			plog.Errorf("failed to notify systemd for readiness")
+		}
+	}
+
 	<-stopped
 	osutil.Exit(0)
 }