etcdctl: support basic operations with etcd 0.4.
For CoreOS users, they will get a updated version of etcdctl without updating the etcd server version. And the users cannot really control this behavior. We do not want to suddenly break them without enough communication. So we still want the most basic opeartions like get, set, watch of etcdctl2 work with etcd 0.4. This patches solve the incompability issue.release-2.3
parent
5587c4aa9a
commit
541f2e5200
|
@ -208,8 +208,19 @@ func mustNewClient(c *cli.Context) client.Client {
|
||||||
if err == client.ErrNoEndpoints {
|
if err == client.ErrNoEndpoints {
|
||||||
fmt.Fprintf(os.Stderr, "etcd cluster has no published client endpoints.\n")
|
fmt.Fprintf(os.Stderr, "etcd cluster has no published client endpoints.\n")
|
||||||
fmt.Fprintf(os.Stderr, "Try '--no-sync' if you want to access non-published client endpoints(%s).\n", strings.Join(hc.Endpoints(), ","))
|
fmt.Fprintf(os.Stderr, "Try '--no-sync' if you want to access non-published client endpoints(%s).\n", strings.Join(hc.Endpoints(), ","))
|
||||||
|
handleError(ExitServerError, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// fail-back to try sync cluster with peer API. this is for making etcdctl work with etcd 0.4.x.
|
||||||
|
// TODO: remove this when we deprecate the support for etcd 0.4.
|
||||||
|
eps, serr := syncWithPeerAPI(c, ctx, hc.Endpoints())
|
||||||
|
if serr != nil {
|
||||||
|
handleError(ExitServerError, serr)
|
||||||
|
}
|
||||||
|
err = hc.SetEndpoints(eps)
|
||||||
|
if err != nil {
|
||||||
|
handleError(ExitServerError, err)
|
||||||
}
|
}
|
||||||
handleError(ExitServerError, err)
|
|
||||||
}
|
}
|
||||||
if debug {
|
if debug {
|
||||||
fmt.Fprintf(os.Stderr, "got endpoints(%s) after sync\n", strings.Join(hc.Endpoints(), ","))
|
fmt.Fprintf(os.Stderr, "got endpoints(%s) after sync\n", strings.Join(hc.Endpoints(), ","))
|
||||||
|
@ -271,3 +282,44 @@ func newClient(c *cli.Context) (client.Client, error) {
|
||||||
func contextWithTotalTimeout(c *cli.Context) (context.Context, context.CancelFunc) {
|
func contextWithTotalTimeout(c *cli.Context) (context.Context, context.CancelFunc) {
|
||||||
return context.WithTimeout(context.Background(), c.GlobalDuration("total-timeout"))
|
return context.WithTimeout(context.Background(), c.GlobalDuration("total-timeout"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// syncWithPeerAPI syncs cluster with peer API defined at
|
||||||
|
// https://github.com/coreos/etcd/blob/v0.4.9/server/server.go#L311.
|
||||||
|
// This exists for backward compatibility with etcd 0.4.x.
|
||||||
|
func syncWithPeerAPI(c *cli.Context, ctx context.Context, knownPeers []string) ([]string, error) {
|
||||||
|
tr, err := getTransport(c)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
body []byte
|
||||||
|
resp *http.Response
|
||||||
|
)
|
||||||
|
for _, p := range knownPeers {
|
||||||
|
var req *http.Request
|
||||||
|
req, err = http.NewRequest("GET", p+"/v2/peers", nil)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
resp, err = tr.RoundTrip(req)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
resp.Body.Close()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
body, err = ioutil.ReadAll(resp.Body)
|
||||||
|
resp.Body.Close()
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the peers API format: https://github.com/coreos/etcd/blob/v0.4.9/server/server.go#L311
|
||||||
|
return strings.Split(string(body), ", "), nil
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue