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 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.
// Note that if the instance does not exist or is no longer running, we must return ("", cloudprovider.InstanceNotFound)
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(filter string) ([]string, error)
// 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
}
func getInstanceType(metadata EC2Metadata) (string, error) {
return metadata.GetMetadata("instance-type")
}
func getAvailabilityZone(metadata EC2Metadata) (string, error) {
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)
// We typically ignore instances that are not alive
func isAlive(instance *ec2.Instance) bool {
@ -873,6 +895,9 @@ type awsInstance struct {
// availability zone the instance resides in
availabilityZone string
// instance type
instanceType string
mutex sync.Mutex
// We must cache because otherwise there is a race condition,
@ -880,8 +905,8 @@ type awsInstance struct {
deviceMappings map[mountDevice]string
}
func newAWSInstance(ec2 EC2, awsID, nodeName string, availabilityZone string) *awsInstance {
self := &awsInstance{ec2: ec2, awsID: awsID, nodeName: nodeName, availabilityZone: availabilityZone}
func newAWSInstance(ec2 EC2, awsID, nodeName, availabilityZone, instanceType string) *awsInstance {
self := &awsInstance{ec2: ec2, awsID: awsID, nodeName: nodeName, availabilityZone: availabilityZone, instanceType: instanceType}
// We lazy-init deviceMappings
self.deviceMappings = nil
@ -1157,8 +1182,12 @@ func (s *AWSCloud) getSelfAWSInstance() (*awsInstance, error) {
if err != nil {
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
}
@ -1180,7 +1209,7 @@ func (aws *AWSCloud) getAwsInstance(nodeName string) (*awsInstance, error) {
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

View File

@ -52,6 +52,7 @@ type FakeCloud struct {
Calls []string
Addresses []api.NodeAddress
ExtID map[string]string
InstanceTypes map[string]string
Machines []string
NodeResources *api.NodeResources
ClusterList []string
@ -189,6 +190,12 @@ func (f *FakeCloud) InstanceID(instance string) (string, error) {
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.
// It adds an entry "list" into the internal method call record.
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
}
// 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.
func (gce *GCECloud) List(filter string) ([]string, error) {
var instances []string
@ -2151,6 +2160,7 @@ type gceInstance struct {
Name string
ID uint64
Disks []*compute.AttachedDisk
Type string
}
type gceDisk struct {
@ -2185,7 +2195,7 @@ func (gce *GCECloud) getInstancesByNames(names []string) ([]*gceInstance, error)
// Add the filter for hosts
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()
if err != nil {
@ -2199,6 +2209,7 @@ func (gce *GCECloud) getInstancesByNames(names []string) ([]*gceInstance, error)
Name: name,
ID: i.Id,
Disks: i.Disks,
Type: lastComponent(i.MachineType),
}
instances[name] = instance
}
@ -2236,6 +2247,7 @@ func (gce *GCECloud) getInstanceByName(name string) (*gceInstance, error) {
Name: res.Name,
ID: res.Id,
Disks: res.Disks,
Type: lastComponent(res.MachineType),
}, nil
}

View File

@ -216,6 +216,11 @@ func (c *MesosCloud) InstanceID(name string) (string, error) {
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) {
//TODO(jdef) use a timeout here? 15s?
ctx, cancel := context.WithCancel(context.TODO())

View File

@ -480,6 +480,11 @@ func (i *Instances) InstanceID(name string) (string, error) {
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) {
return nil, false
}

View File

@ -193,6 +193,11 @@ func (v *OVirtCloud) InstanceID(name string) (string, error) {
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) {
if body == nil {
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
}
// 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 {
return errors.New("unimplemented")
}

View File

@ -1010,6 +1010,14 @@ func (kl *Kubelet) initialNodeStatus() (*api.Node, error) {
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
zones, ok := kl.cloud.Zones()
if ok {