diff --git a/pkg/cloudprovider/gce/gce.go b/pkg/cloudprovider/gce/gce.go index 4fdaa889c7a..d7cdb8a8d05 100644 --- a/pkg/cloudprovider/gce/gce.go +++ b/pkg/cloudprovider/gce/gce.go @@ -32,6 +32,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource" "github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" + "github.com/GoogleCloudPlatform/kubernetes/pkg/util/wait" "code.google.com/p/gcfg" compute "code.google.com/p/google-api-go-client/compute/v1" @@ -483,37 +484,46 @@ func (gce *GCECloud) getInstanceByName(name string) (*compute.Instance, error) { } func (gce *GCECloud) AddSSHKeyToAllInstances(user string, keyData []byte) error { - project, err := gce.service.Projects.Get(gce.projectID).Do() - if err != nil { - return err - } - hostname, err := os.Hostname() - if err != nil { - return err - } - keyString := fmt.Sprintf("%s:%s %s@%s", user, strings.TrimSpace(string(keyData)), user, hostname) - found := false - for _, item := range project.CommonInstanceMetadata.Items { - if item.Key == "sshKeys" { - item.Value = addKey(item.Value, keyString) - found = true - break + return wait.Poll(2*time.Second, 30*time.Second, func() (bool, error) { + project, err := gce.service.Projects.Get(gce.projectID).Do() + if err != nil { + glog.Errorf("Could not get project: %v", err) + return false, nil } - } - if !found { - // This is super unlikely, so log. - glog.Infof("Failed to find sshKeys metadata, creating a new item") - project.CommonInstanceMetadata.Items = append(project.CommonInstanceMetadata.Items, - &compute.MetadataItems{ - Key: "sshKeys", - Value: keyString, - }) - } - op, err := gce.service.Projects.SetCommonInstanceMetadata(gce.projectID, project.CommonInstanceMetadata).Do() - if err != nil { - return err - } - return gce.waitForGlobalOp(op) + hostname, err := os.Hostname() + if err != nil { + glog.Errorf("Could not get hostname: %v", err) + return false, nil + } + keyString := fmt.Sprintf("%s:%s %s@%s", user, strings.TrimSpace(string(keyData)), user, hostname) + found := false + for _, item := range project.CommonInstanceMetadata.Items { + if item.Key == "sshKeys" { + item.Value = addKey(item.Value, keyString) + found = true + break + } + } + if !found { + // This is super unlikely, so log. + glog.Infof("Failed to find sshKeys metadata, creating a new item") + project.CommonInstanceMetadata.Items = append(project.CommonInstanceMetadata.Items, + &compute.MetadataItems{ + Key: "sshKeys", + Value: keyString, + }) + } + op, err := gce.service.Projects.SetCommonInstanceMetadata(gce.projectID, project.CommonInstanceMetadata).Do() + if err != nil { + glog.Errorf("Could not Set Metadata: %v", err) + return false, nil + } + if err := gce.waitForGlobalOp(op); err != nil { + glog.Errorf("Could not Set Metadata: %v", err) + return false, nil + } + return true, nil + }) } func addKey(metadataBefore, keyString string) string { diff --git a/pkg/util/ssh.go b/pkg/util/ssh.go index d4eed8a3795..b5f441597ef 100644 --- a/pkg/util/ssh.go +++ b/pkg/util/ssh.go @@ -223,11 +223,12 @@ func MakeSSHTunnels(user, keyfile string, addresses []string) (SSHTunnelList, er } func (l SSHTunnelList) Open() error { - for ix := range l { + for ix := 0; ix < len(l); ix++ { if err := l[ix].Tunnel.Open(); err != nil { // Remove a failed Open from the list. glog.Errorf("Failed to open tunnel %v: %v", l[ix], err) l = append(l[:ix], l[ix+1:]...) + ix-- } } if len(l) == 0 {