Merge pull request #20909 from Clarifai/instance-type-label

Auto commit by PR queue bot
This commit is contained in:
k8s-merge-robot 2016-02-13 18:51:42 -08:00
commit d6b4ff3884
10 changed files with 85 additions and 5 deletions

View File

@ -18,3 +18,4 @@ package unversioned
const LabelZoneFailureDomain = "failure-domain.alpha.kubernetes.io/zone" const LabelZoneFailureDomain = "failure-domain.alpha.kubernetes.io/zone"
const LabelZoneRegion = "failure-domain.alpha.kubernetes.io/region" const LabelZoneRegion = "failure-domain.alpha.kubernetes.io/region"
const LabelInstanceType = "beta.kubernetes.io/instance-type"

View File

@ -108,6 +108,9 @@ type Instances interface {
// InstanceID returns the cloud provider ID of the specified instance. // InstanceID returns the cloud provider ID of the specified instance.
// Note that if the instance does not exist or is no longer running, we must return ("", cloudprovider.InstanceNotFound) // Note that if the instance does not exist or is no longer running, we must return ("", cloudprovider.InstanceNotFound)
InstanceID(name string) (string, error) InstanceID(name string) (string, error)
// InstanceType returns the type of the specified instance.
// Note that if the instance does not exist or is no longer running, we must return ("", cloudprovider.InstanceNotFound)
InstanceType(name string) (string, error)
// List lists instances that match 'filter' which is a regular expression which must match the entire instance name (fqdn) // List lists instances that match 'filter' which is a regular expression which must match the entire instance name (fqdn)
List(filter string) ([]string, error) List(filter string) ([]string, error)
// AddSSHKeyToAllInstances adds an SSH public key as a legal identity for all instances // AddSSHKeyToAllInstances adds an SSH public key as a legal identity for all instances

View File

@ -491,6 +491,10 @@ func readAWSCloudConfig(config io.Reader, metadata EC2Metadata) (*AWSCloudConfig
return &cfg, nil return &cfg, nil
} }
func getInstanceType(metadata EC2Metadata) (string, error) {
return metadata.GetMetadata("instance-type")
}
func getAvailabilityZone(metadata EC2Metadata) (string, error) { func getAvailabilityZone(metadata EC2Metadata) (string, error) {
return metadata.GetMetadata("placement/availability-zone") return metadata.GetMetadata("placement/availability-zone")
} }
@ -751,6 +755,24 @@ func (aws *AWSCloud) InstanceID(name string) (string, error) {
} }
} }
// InstanceType returns the type of the specified instance.
func (aws *AWSCloud) InstanceType(name string) (string, error) {
awsInstance, err := aws.getSelfAWSInstance()
if err != nil {
return "", err
}
if awsInstance.nodeName == name {
return awsInstance.instanceType, nil
} else {
inst, err := aws.getInstanceByNodeName(name)
if err != nil {
return "", err
}
return orEmpty(inst.InstanceType), nil
}
}
// Check if the instance is alive (running or pending) // Check if the instance is alive (running or pending)
// We typically ignore instances that are not alive // We typically ignore instances that are not alive
func isAlive(instance *ec2.Instance) bool { func isAlive(instance *ec2.Instance) bool {
@ -873,6 +895,9 @@ type awsInstance struct {
// availability zone the instance resides in // availability zone the instance resides in
availabilityZone string availabilityZone string
// instance type
instanceType string
mutex sync.Mutex mutex sync.Mutex
// We must cache because otherwise there is a race condition, // We must cache because otherwise there is a race condition,
@ -880,8 +905,8 @@ type awsInstance struct {
deviceMappings map[mountDevice]string deviceMappings map[mountDevice]string
} }
func newAWSInstance(ec2 EC2, awsID, nodeName string, availabilityZone string) *awsInstance { func newAWSInstance(ec2 EC2, awsID, nodeName, availabilityZone, instanceType string) *awsInstance {
self := &awsInstance{ec2: ec2, awsID: awsID, nodeName: nodeName, availabilityZone: availabilityZone} self := &awsInstance{ec2: ec2, awsID: awsID, nodeName: nodeName, availabilityZone: availabilityZone, instanceType: instanceType}
// We lazy-init deviceMappings // We lazy-init deviceMappings
self.deviceMappings = nil self.deviceMappings = nil
@ -1157,8 +1182,12 @@ func (s *AWSCloud) getSelfAWSInstance() (*awsInstance, error) {
if err != nil { if err != nil {
return nil, fmt.Errorf("error fetching availability zone from ec2 metadata service: %v", err) return nil, fmt.Errorf("error fetching availability zone from ec2 metadata service: %v", err)
} }
instanceType, err := getInstanceType(s.metadata)
if err != nil {
return nil, fmt.Errorf("error fetching instance type from ec2 metadata service: %v", err)
}
i = newAWSInstance(s.ec2, instanceId, privateDnsName, availabilityZone) i = newAWSInstance(s.ec2, instanceId, privateDnsName, availabilityZone, instanceType)
s.selfAWSInstance = i s.selfAWSInstance = i
} }
@ -1180,7 +1209,7 @@ func (aws *AWSCloud) getAwsInstance(nodeName string) (*awsInstance, error) {
return nil, fmt.Errorf("error finding instance %s: %v", nodeName, err) return nil, fmt.Errorf("error finding instance %s: %v", nodeName, err)
} }
awsInstance = newAWSInstance(aws.ec2, orEmpty(instance.InstanceId), orEmpty(instance.PrivateDnsName), orEmpty(instance.Placement.AvailabilityZone)) awsInstance = newAWSInstance(aws.ec2, orEmpty(instance.InstanceId), orEmpty(instance.PrivateDnsName), orEmpty(instance.Placement.AvailabilityZone), orEmpty(instance.InstanceType))
} }
return awsInstance, nil return awsInstance, nil

View File

@ -52,6 +52,7 @@ type FakeCloud struct {
Calls []string Calls []string
Addresses []api.NodeAddress Addresses []api.NodeAddress
ExtID map[string]string ExtID map[string]string
InstanceTypes map[string]string
Machines []string Machines []string
NodeResources *api.NodeResources NodeResources *api.NodeResources
ClusterList []string ClusterList []string
@ -189,6 +190,12 @@ func (f *FakeCloud) InstanceID(instance string) (string, error) {
return f.ExtID[instance], nil return f.ExtID[instance], nil
} }
// InstanceType returns the type of the specified instance.
func (f *FakeCloud) InstanceType(instance string) (string, error) {
f.addCall("instance-type")
return f.InstanceTypes[instance], nil
}
// List is a test-spy implementation of Instances.List. // List is a test-spy implementation of Instances.List.
// It adds an entry "list" into the internal method call record. // It adds an entry "list" into the internal method call record.
func (f *FakeCloud) List(filter string) ([]string, error) { func (f *FakeCloud) List(filter string) ([]string, error) {

View File

@ -1797,6 +1797,15 @@ func (gce *GCECloud) InstanceID(instanceName string) (string, error) {
return gce.projectID + "/" + instance.Zone + "/" + instance.Name, nil return gce.projectID + "/" + instance.Zone + "/" + instance.Name, nil
} }
// InstanceType returns the type of the specified instance.
func (gce *GCECloud) InstanceType(instanceName string) (string, error) {
instance, err := gce.getInstanceByName(instanceName)
if err != nil {
return "", err
}
return instance.Type, nil
}
// List is an implementation of Instances.List. // List is an implementation of Instances.List.
func (gce *GCECloud) List(filter string) ([]string, error) { func (gce *GCECloud) List(filter string) ([]string, error) {
var instances []string var instances []string
@ -2151,6 +2160,7 @@ type gceInstance struct {
Name string Name string
ID uint64 ID uint64
Disks []*compute.AttachedDisk Disks []*compute.AttachedDisk
Type string
} }
type gceDisk struct { type gceDisk struct {
@ -2185,7 +2195,7 @@ func (gce *GCECloud) getInstancesByNames(names []string) ([]*gceInstance, error)
// Add the filter for hosts // Add the filter for hosts
listCall = listCall.Filter("name eq (" + strings.Join(remaining, "|") + ")") listCall = listCall.Filter("name eq (" + strings.Join(remaining, "|") + ")")
listCall = listCall.Fields("items(name,id,disks)") listCall = listCall.Fields("items(name,id,disks,machineType)")
res, err := listCall.Do() res, err := listCall.Do()
if err != nil { if err != nil {
@ -2199,6 +2209,7 @@ func (gce *GCECloud) getInstancesByNames(names []string) ([]*gceInstance, error)
Name: name, Name: name,
ID: i.Id, ID: i.Id,
Disks: i.Disks, Disks: i.Disks,
Type: lastComponent(i.MachineType),
} }
instances[name] = instance instances[name] = instance
} }
@ -2236,6 +2247,7 @@ func (gce *GCECloud) getInstanceByName(name string) (*gceInstance, error) {
Name: res.Name, Name: res.Name,
ID: res.Id, ID: res.Id,
Disks: res.Disks, Disks: res.Disks,
Type: lastComponent(res.MachineType),
}, nil }, nil
} }

View File

@ -216,6 +216,11 @@ func (c *MesosCloud) InstanceID(name string) (string, error) {
return "", nil return "", nil
} }
// InstanceType returns the type of the specified instance.
func (c *MesosCloud) InstanceType(name string) (string, error) {
return "", nil
}
func (c *MesosCloud) listNodes() (map[string]*slaveNode, error) { func (c *MesosCloud) listNodes() (map[string]*slaveNode, error) {
//TODO(jdef) use a timeout here? 15s? //TODO(jdef) use a timeout here? 15s?
ctx, cancel := context.WithCancel(context.TODO()) ctx, cancel := context.WithCancel(context.TODO())

View File

@ -480,6 +480,11 @@ func (i *Instances) InstanceID(name string) (string, error) {
return "/" + srv.ID, nil return "/" + srv.ID, nil
} }
// InstanceType returns the type of the specified instance.
func (i *Instances) InstanceType(name string) (string, error) {
return "", nil
}
func (os *OpenStack) Clusters() (cloudprovider.Clusters, bool) { func (os *OpenStack) Clusters() (cloudprovider.Clusters, bool) {
return nil, false return nil, false
} }

View File

@ -193,6 +193,11 @@ func (v *OVirtCloud) InstanceID(name string) (string, error) {
return "/" + instance.UUID, err return "/" + instance.UUID, err
} }
// InstanceType returns the type of the specified instance.
func (v *OVirtCloud) InstanceType(name string) (string, error) {
return "", nil
}
func getInstancesFromXml(body io.Reader) (OVirtInstanceMap, error) { func getInstancesFromXml(body io.Reader) (OVirtInstanceMap, error) {
if body == nil { if body == nil {
return nil, fmt.Errorf("ovirt rest-api response body is missing") return nil, fmt.Errorf("ovirt rest-api response body is missing")

View File

@ -344,6 +344,11 @@ func (i *Instances) InstanceID(name string) (string, error) {
return "", nil return "", nil
} }
// InstanceType returns the type of the specified instance.
func (i *Instances) InstanceType(name string) (string, error) {
return "", nil
}
func (i *Instances) AddSSHKeyToAllInstances(user string, keyData []byte) error { func (i *Instances) AddSSHKeyToAllInstances(user string, keyData []byte) error {
return errors.New("unimplemented") return errors.New("unimplemented")
} }

View File

@ -1010,6 +1010,14 @@ func (kl *Kubelet) initialNodeStatus() (*api.Node, error) {
return nil, err return nil, err
} }
instanceType, err := instances.InstanceType(kl.nodeName)
if err != nil {
return nil, err
}
if instanceType != "" {
glog.Infof("Adding node label from cloud provider: %s=%s", unversioned.LabelInstanceType, instanceType)
node.ObjectMeta.Labels[unversioned.LabelInstanceType] = instanceType
}
// If the cloud has zone information, label the node with the zone information // If the cloud has zone information, label the node with the zone information
zones, ok := kl.cloud.Zones() zones, ok := kl.cloud.Zones()
if ok { if ok {