Commit 54195d59 authored by Justin Santa Barbara's avatar Justin Santa Barbara

Use strongly-typed types.NodeName for a node name

We had another bug where we confused the hostname with the NodeName. To avoid this happening again, and to make the code more self-documenting, we use types.NodeName (a typedef alias for string) whenever we are referring to the Node.Name. A tedious but mechanical commit therefore, to change all uses of the node name to use types.NodeName Also clean up some of the (many) places where the NodeName is referred to as a hostname (not true on AWS), or an instanceID (not true on GCE), etc.
parent 294c9aa6
...@@ -16549,7 +16549,7 @@ ...@@ -16549,7 +16549,7 @@
}, },
"host": { "host": {
"type": "string", "type": "string",
"description": "Host name on which the event is generated." "description": "Node name on which the event is generated."
} }
} }
}, },
......
...@@ -20,6 +20,7 @@ import ( ...@@ -20,6 +20,7 @@ import (
"fmt" "fmt"
"os" "os"
"github.com/golang/glog"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/api" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/api"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
"k8s.io/kubernetes/pkg/apis/certificates" "k8s.io/kubernetes/pkg/apis/certificates"
...@@ -29,6 +30,7 @@ import ( ...@@ -29,6 +30,7 @@ import (
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api" clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
"k8s.io/kubernetes/pkg/kubelet/util/csr" "k8s.io/kubernetes/pkg/kubelet/util/csr"
"k8s.io/kubernetes/pkg/types"
certutil "k8s.io/kubernetes/pkg/util/cert" certutil "k8s.io/kubernetes/pkg/util/cert"
) )
...@@ -37,11 +39,16 @@ func PerformTLSBootstrap(s *kubeadmapi.KubeadmConfig, apiEndpoint string, caCert ...@@ -37,11 +39,16 @@ func PerformTLSBootstrap(s *kubeadmapi.KubeadmConfig, apiEndpoint string, caCert
// TODO(phase1+) try all the api servers until we find one that works // TODO(phase1+) try all the api servers until we find one that works
bareClientConfig := kubeadmutil.CreateBasicClientConfig("kubernetes", apiEndpoint, caCert) bareClientConfig := kubeadmutil.CreateBasicClientConfig("kubernetes", apiEndpoint, caCert)
nodeName, err := os.Hostname() hostName, err := os.Hostname()
if err != nil { if err != nil {
return nil, fmt.Errorf("<node/csr> failed to get node hostname [%v]", err) return nil, fmt.Errorf("<node/csr> failed to get node hostname [%v]", err)
} }
// TODO: hostname == nodename doesn't hold on all clouds (AWS).
// But we don't have a cloudprovider, so we're stuck.
glog.Errorf("assuming that hostname is the same as NodeName")
nodeName := types.NodeName(hostName)
bootstrapClientConfig, err := clientcmd.NewDefaultClientConfig( bootstrapClientConfig, err := clientcmd.NewDefaultClientConfig(
*kubeadmutil.MakeClientConfigWithToken( *kubeadmutil.MakeClientConfigWithToken(
bareClientConfig, "kubernetes", fmt.Sprintf("kubelet-%s", nodeName), s.Secrets.BearerToken, bareClientConfig, "kubernetes", fmt.Sprintf("kubelet-%s", nodeName), s.Secrets.BearerToken,
......
...@@ -30,6 +30,7 @@ import ( ...@@ -30,6 +30,7 @@ import (
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api" clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
"k8s.io/kubernetes/pkg/kubelet/util/csr" "k8s.io/kubernetes/pkg/kubelet/util/csr"
"k8s.io/kubernetes/pkg/types"
certutil "k8s.io/kubernetes/pkg/util/cert" certutil "k8s.io/kubernetes/pkg/util/cert"
) )
...@@ -42,7 +43,7 @@ const ( ...@@ -42,7 +43,7 @@ const (
// The kubeconfig at bootstrapPath is used to request a client certificate from the API server. // The kubeconfig at bootstrapPath is used to request a client certificate from the API server.
// On success, a kubeconfig file referencing the generated key and obtained certificate is written to kubeconfigPath. // On success, a kubeconfig file referencing the generated key and obtained certificate is written to kubeconfigPath.
// The certificate and key file are stored in certDir. // The certificate and key file are stored in certDir.
func bootstrapClientCert(kubeconfigPath string, bootstrapPath string, certDir string, nodeName string) error { func bootstrapClientCert(kubeconfigPath string, bootstrapPath string, certDir string, nodeName types.NodeName) error {
// Short-circuit if the kubeconfig file already exists. // Short-circuit if the kubeconfig file already exists.
// TODO: inspect the kubeconfig, ensure a rest client can be built from it, verify client cert expiration, etc. // TODO: inspect the kubeconfig, ensure a rest client can be built from it, verify client cert expiration, etc.
_, err := os.Stat(kubeconfigPath) _, err := os.Stat(kubeconfigPath)
......
...@@ -61,6 +61,7 @@ import ( ...@@ -61,6 +61,7 @@ import (
"k8s.io/kubernetes/pkg/kubelet/server" "k8s.io/kubernetes/pkg/kubelet/server"
kubetypes "k8s.io/kubernetes/pkg/kubelet/types" kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/types"
certutil "k8s.io/kubernetes/pkg/util/cert" certutil "k8s.io/kubernetes/pkg/util/cert"
utilconfig "k8s.io/kubernetes/pkg/util/config" utilconfig "k8s.io/kubernetes/pkg/util/config"
"k8s.io/kubernetes/pkg/util/configz" "k8s.io/kubernetes/pkg/util/configz"
...@@ -169,7 +170,7 @@ func getRemoteKubeletConfig(s *options.KubeletServer, kubeDeps *kubelet.KubeletD ...@@ -169,7 +170,7 @@ func getRemoteKubeletConfig(s *options.KubeletServer, kubeDeps *kubelet.KubeletD
} }
configmap, err := func() (*api.ConfigMap, error) { configmap, err := func() (*api.ConfigMap, error) {
var nodename string var nodename types.NodeName
hostname := nodeutil.GetHostname(s.HostnameOverride) hostname := nodeutil.GetHostname(s.HostnameOverride)
if kubeDeps != nil && kubeDeps.Cloud != nil { if kubeDeps != nil && kubeDeps.Cloud != nil {
...@@ -460,9 +461,9 @@ func run(s *options.KubeletServer, kubeDeps *kubelet.KubeletDeps) (err error) { ...@@ -460,9 +461,9 @@ func run(s *options.KubeletServer, kubeDeps *kubelet.KubeletDeps) (err error) {
// getNodeName returns the node name according to the cloud provider // getNodeName returns the node name according to the cloud provider
// if cloud provider is specified. Otherwise, returns the hostname of the node. // if cloud provider is specified. Otherwise, returns the hostname of the node.
func getNodeName(cloud cloudprovider.Interface, hostname string) (string, error) { func getNodeName(cloud cloudprovider.Interface, hostname string) (types.NodeName, error) {
if cloud == nil { if cloud == nil {
return hostname, nil return types.NodeName(hostname), nil
} }
instances, ok := cloud.Instances() instances, ok := cloud.Instances()
...@@ -607,7 +608,7 @@ func RunKubelet(kubeCfg *componentconfig.KubeletConfiguration, kubeDeps *kubelet ...@@ -607,7 +608,7 @@ func RunKubelet(kubeCfg *componentconfig.KubeletConfiguration, kubeDeps *kubelet
} }
eventBroadcaster := record.NewBroadcaster() eventBroadcaster := record.NewBroadcaster()
kubeDeps.Recorder = eventBroadcaster.NewRecorder(api.EventSource{Component: "kubelet", Host: nodeName}) kubeDeps.Recorder = eventBroadcaster.NewRecorder(api.EventSource{Component: "kubelet", Host: string(nodeName)})
eventBroadcaster.StartLogging(glog.V(3).Infof) eventBroadcaster.StartLogging(glog.V(3).Infof)
if kubeDeps.EventClient != nil { if kubeDeps.EventClient != nil {
glog.V(4).Infof("Sending events to api server.") glog.V(4).Infof("Sending events to api server.")
......
...@@ -44,6 +44,7 @@ import ( ...@@ -44,6 +44,7 @@ import (
kconfig "k8s.io/kubernetes/pkg/kubelet/config" kconfig "k8s.io/kubernetes/pkg/kubelet/config"
"k8s.io/kubernetes/pkg/kubelet/dockertools" "k8s.io/kubernetes/pkg/kubelet/dockertools"
kubetypes "k8s.io/kubernetes/pkg/kubelet/types" kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
"k8s.io/kubernetes/pkg/types"
) )
// TODO(jdef): passing the value of envContainerID to all docker containers instantiated // TODO(jdef): passing the value of envContainerID to all docker containers instantiated
......
...@@ -5008,7 +5008,7 @@ The resulting set of endpoints can be viewed as:<br> ...@@ -5008,7 +5008,7 @@ The resulting set of endpoints can be viewed as:<br>
</tr> </tr>
<tr> <tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">host</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">host</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Host name on which the event is generated.</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Node name on which the event is generated.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td> <td class="tableblock halign-left valign-top"></td>
......
...@@ -2568,7 +2568,7 @@ type SerializedReference struct { ...@@ -2568,7 +2568,7 @@ type SerializedReference struct {
type EventSource struct { type EventSource struct {
// Component from which the event is generated. // Component from which the event is generated.
Component string `json:"component,omitempty"` Component string `json:"component,omitempty"`
// Host name on which the event is generated. // Node name on which the event is generated.
Host string `json:"host,omitempty"` Host string `json:"host,omitempty"`
} }
......
...@@ -769,7 +769,7 @@ message EventSource { ...@@ -769,7 +769,7 @@ message EventSource {
// Component from which the event is generated. // Component from which the event is generated.
optional string component = 1; optional string component = 1;
// Host name on which the event is generated. // Node name on which the event is generated.
optional string host = 2; optional string host = 2;
} }
......
...@@ -3017,7 +3017,7 @@ type SerializedReference struct { ...@@ -3017,7 +3017,7 @@ type SerializedReference struct {
type EventSource struct { type EventSource struct {
// Component from which the event is generated. // Component from which the event is generated.
Component string `json:"component,omitempty" protobuf:"bytes,1,opt,name=component"` Component string `json:"component,omitempty" protobuf:"bytes,1,opt,name=component"`
// Host name on which the event is generated. // Node name on which the event is generated.
Host string `json:"host,omitempty" protobuf:"bytes,2,opt,name=host"` Host string `json:"host,omitempty" protobuf:"bytes,2,opt,name=host"`
} }
......
...@@ -477,7 +477,7 @@ func (EventList) SwaggerDoc() map[string]string { ...@@ -477,7 +477,7 @@ func (EventList) SwaggerDoc() map[string]string {
var map_EventSource = map[string]string{ var map_EventSource = map[string]string{
"": "EventSource contains information for an event.", "": "EventSource contains information for an event.",
"component": "Component from which the event is generated.", "component": "Component from which the event is generated.",
"host": "Host name on which the event is generated.", "host": "Node name on which the event is generated.",
} }
func (EventSource) SwaggerDoc() map[string]string { func (EventSource) SwaggerDoc() map[string]string {
......
...@@ -22,6 +22,7 @@ import ( ...@@ -22,6 +22,7 @@ import (
"strings" "strings"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/types"
) )
// Interface is an abstract, pluggable interface for cloud providers. // Interface is an abstract, pluggable interface for cloud providers.
...@@ -63,7 +64,7 @@ func GetLoadBalancerName(service *api.Service) string { ...@@ -63,7 +64,7 @@ func GetLoadBalancerName(service *api.Service) string {
return ret return ret
} }
func GetInstanceProviderID(cloud Interface, nodeName string) (string, error) { func GetInstanceProviderID(cloud Interface, nodeName types.NodeName) (string, error) {
instances, ok := cloud.Instances() instances, ok := cloud.Instances()
if !ok { if !ok {
return "", fmt.Errorf("failed to get instances from cloud provider") return "", fmt.Errorf("failed to get instances from cloud provider")
...@@ -86,11 +87,11 @@ type LoadBalancer interface { ...@@ -86,11 +87,11 @@ type LoadBalancer interface {
// EnsureLoadBalancer creates a new load balancer 'name', or updates the existing one. Returns the status of the balancer // EnsureLoadBalancer creates a new load balancer 'name', or updates the existing one. Returns the status of the balancer
// Implementations must treat the *api.Service parameter as read-only and not modify it. // Implementations must treat the *api.Service parameter as read-only and not modify it.
// Parameter 'clusterName' is the name of the cluster as presented to kube-controller-manager // Parameter 'clusterName' is the name of the cluster as presented to kube-controller-manager
EnsureLoadBalancer(clusterName string, service *api.Service, hosts []string) (*api.LoadBalancerStatus, error) EnsureLoadBalancer(clusterName string, service *api.Service, nodeNames []string) (*api.LoadBalancerStatus, error)
// UpdateLoadBalancer updates hosts under the specified load balancer. // UpdateLoadBalancer updates hosts under the specified load balancer.
// Implementations must treat the *api.Service parameter as read-only and not modify it. // Implementations must treat the *api.Service parameter as read-only and not modify it.
// Parameter 'clusterName' is the name of the cluster as presented to kube-controller-manager // Parameter 'clusterName' is the name of the cluster as presented to kube-controller-manager
UpdateLoadBalancer(clusterName string, service *api.Service, hosts []string) error UpdateLoadBalancer(clusterName string, service *api.Service, nodeNames []string) error
// EnsureLoadBalancerDeleted deletes the specified load balancer if it // EnsureLoadBalancerDeleted deletes the specified load balancer if it
// exists, returning nil if the load balancer specified either didn't exist or // exists, returning nil if the load balancer specified either didn't exist or
// was successfully deleted. // was successfully deleted.
...@@ -108,22 +109,22 @@ type Instances interface { ...@@ -108,22 +109,22 @@ type Instances interface {
// TODO(roberthbailey): This currently is only used in such a way that it // TODO(roberthbailey): This currently is only used in such a way that it
// returns the address of the calling instance. We should do a rename to // returns the address of the calling instance. We should do a rename to
// make this clearer. // make this clearer.
NodeAddresses(name string) ([]api.NodeAddress, error) NodeAddresses(name types.NodeName) ([]api.NodeAddress, error)
// ExternalID returns the cloud provider ID of the specified instance (deprecated). // ExternalID returns the cloud provider ID of the node with the specified NodeName.
// 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)
ExternalID(name string) (string, error) ExternalID(nodeName types.NodeName) (string, error)
// InstanceID returns the cloud provider ID of the specified instance. // InstanceID returns the cloud provider ID of the node with the specified NodeName.
InstanceID(name string) (string, error) InstanceID(nodeName types.NodeName) (string, error)
// InstanceType returns the type of the specified instance. // InstanceType returns the type of the specified instance.
InstanceType(name string) (string, error) InstanceType(name types.NodeName) (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) ([]types.NodeName, 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
// expected format for the key is standard ssh-keygen format: <protocol> <blob> // expected format for the key is standard ssh-keygen format: <protocol> <blob>
AddSSHKeyToAllInstances(user string, keyData []byte) error AddSSHKeyToAllInstances(user string, keyData []byte) error
// CurrentNodeName returns the name of the node we are currently running on // CurrentNodeName returns the name of the node we are currently running on
// On most clouds (e.g. GCE) this is the hostname, so we provide the hostname // On most clouds (e.g. GCE) this is the hostname, so we provide the hostname
CurrentNodeName(hostname string) (string, error) CurrentNodeName(hostname string) (types.NodeName, error)
} }
// Route is a representation of an advanced routing rule. // Route is a representation of an advanced routing rule.
...@@ -131,9 +132,8 @@ type Route struct { ...@@ -131,9 +132,8 @@ type Route struct {
// Name is the name of the routing rule in the cloud-provider. // Name is the name of the routing rule in the cloud-provider.
// It will be ignored in a Create (although nameHint may influence it) // It will be ignored in a Create (although nameHint may influence it)
Name string Name string
// TargetInstance is the name of the instance as specified in routing rules // TargetNode is the NodeName of the target instance.
// for the cloud-provider (in gce: the Instance Name). TargetNode types.NodeName
TargetInstance string
// DestinationCIDR is the CIDR format IP range that this routing rule // DestinationCIDR is the CIDR format IP range that this routing rule
// applies to. // applies to.
DestinationCIDR string DestinationCIDR string
......
...@@ -86,9 +86,9 @@ func (c *Cloud) ListRoutes(clusterName string) ([]*cloudprovider.Route, error) { ...@@ -86,9 +86,9 @@ func (c *Cloud) ListRoutes(clusterName string) ([]*cloudprovider.Route, error) {
glog.Warningf("unable to find instance ID %s in the list of instances being routed to", instanceID) glog.Warningf("unable to find instance ID %s in the list of instances being routed to", instanceID)
continue continue
} }
instanceName := orEmpty(instance.PrivateDnsName) nodeName := mapInstanceToNodeName(instance)
routeName := clusterName + "-" + destinationCIDR routeName := clusterName + "-" + destinationCIDR
routes = append(routes, &cloudprovider.Route{Name: routeName, TargetInstance: instanceName, DestinationCIDR: destinationCIDR}) routes = append(routes, &cloudprovider.Route{Name: routeName, TargetNode: nodeName, DestinationCIDR: destinationCIDR})
} }
return routes, nil return routes, nil
...@@ -110,7 +110,7 @@ func (c *Cloud) configureInstanceSourceDestCheck(instanceID string, sourceDestCh ...@@ -110,7 +110,7 @@ func (c *Cloud) configureInstanceSourceDestCheck(instanceID string, sourceDestCh
// CreateRoute implements Routes.CreateRoute // CreateRoute implements Routes.CreateRoute
// Create the described route // Create the described route
func (c *Cloud) CreateRoute(clusterName string, nameHint string, route *cloudprovider.Route) error { func (c *Cloud) CreateRoute(clusterName string, nameHint string, route *cloudprovider.Route) error {
instance, err := c.getInstanceByNodeName(route.TargetInstance) instance, err := c.getInstanceByNodeName(route.TargetNode)
if err != nil { if err != nil {
return err return err
} }
......
...@@ -34,6 +34,7 @@ import ( ...@@ -34,6 +34,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock" "github.com/stretchr/testify/mock"
"k8s.io/kubernetes/pkg/types"
) )
const TestClusterId = "clusterid.test" const TestClusterId = "clusterid.test"
...@@ -605,11 +606,11 @@ func TestList(t *testing.T) { ...@@ -605,11 +606,11 @@ func TestList(t *testing.T) {
table := []struct { table := []struct {
input string input string
expect []string expect []types.NodeName
}{ }{
{"blahonga", []string{}}, {"blahonga", []types.NodeName{}},
{"quux", []string{"instance3.ec2.internal"}}, {"quux", []types.NodeName{"instance3.ec2.internal"}},
{"a", []string{"instance1.ec2.internal", "instance2.ec2.internal"}}, {"a", []types.NodeName{"instance1.ec2.internal", "instance2.ec2.internal"}},
} }
for _, item := range table { for _, item := range table {
...@@ -705,7 +706,7 @@ func TestNodeAddresses(t *testing.T) { ...@@ -705,7 +706,7 @@ func TestNodeAddresses(t *testing.T) {
fakeServices.selfInstance.PublicIpAddress = aws.String("2.3.4.5") fakeServices.selfInstance.PublicIpAddress = aws.String("2.3.4.5")
fakeServices.selfInstance.PrivateIpAddress = aws.String("192.168.0.2") fakeServices.selfInstance.PrivateIpAddress = aws.String("192.168.0.2")
addrs4, err4 := aws4.NodeAddresses(*instance0.PrivateDnsName) addrs4, err4 := aws4.NodeAddresses(mapInstanceToNodeName(&instance0))
if err4 != nil { if err4 != nil {
t.Errorf("unexpected error: %v", err4) t.Errorf("unexpected error: %v", err4)
} }
...@@ -1062,7 +1063,7 @@ func TestIpPermissionExistsHandlesMultipleGroupIdsWithUserIds(t *testing.T) { ...@@ -1062,7 +1063,7 @@ func TestIpPermissionExistsHandlesMultipleGroupIdsWithUserIds(t *testing.T) {
func TestFindInstanceByNodeNameExcludesTerminatedInstances(t *testing.T) { func TestFindInstanceByNodeNameExcludesTerminatedInstances(t *testing.T) {
awsServices := NewFakeAWSServices() awsServices := NewFakeAWSServices()
nodeName := "my-dns.internal" nodeName := types.NodeName("my-dns.internal")
var tag ec2.Tag var tag ec2.Tag
tag.Key = aws.String(TagNameKubernetesCluster) tag.Key = aws.String(TagNameKubernetesCluster)
...@@ -1071,13 +1072,13 @@ func TestFindInstanceByNodeNameExcludesTerminatedInstances(t *testing.T) { ...@@ -1071,13 +1072,13 @@ func TestFindInstanceByNodeNameExcludesTerminatedInstances(t *testing.T) {
var runningInstance ec2.Instance var runningInstance ec2.Instance
runningInstance.InstanceId = aws.String("i-running") runningInstance.InstanceId = aws.String("i-running")
runningInstance.PrivateDnsName = aws.String(nodeName) runningInstance.PrivateDnsName = aws.String(string(nodeName))
runningInstance.State = &ec2.InstanceState{Code: aws.Int64(16), Name: aws.String("running")} runningInstance.State = &ec2.InstanceState{Code: aws.Int64(16), Name: aws.String("running")}
runningInstance.Tags = tags runningInstance.Tags = tags
var terminatedInstance ec2.Instance var terminatedInstance ec2.Instance
terminatedInstance.InstanceId = aws.String("i-terminated") terminatedInstance.InstanceId = aws.String("i-terminated")
terminatedInstance.PrivateDnsName = aws.String(nodeName) terminatedInstance.PrivateDnsName = aws.String(string(nodeName))
terminatedInstance.State = &ec2.InstanceState{Code: aws.Int64(48), Name: aws.String("terminated")} terminatedInstance.State = &ec2.InstanceState{Code: aws.Int64(48), Name: aws.String("terminated")}
terminatedInstance.Tags = tags terminatedInstance.Tags = tags
......
...@@ -24,10 +24,11 @@ import ( ...@@ -24,10 +24,11 @@ import (
"k8s.io/kubernetes/pkg/cloudprovider" "k8s.io/kubernetes/pkg/cloudprovider"
"github.com/Azure/azure-sdk-for-go/arm/compute" "github.com/Azure/azure-sdk-for-go/arm/compute"
"k8s.io/kubernetes/pkg/types"
) )
// NodeAddresses returns the addresses of the specified instance. // NodeAddresses returns the addresses of the specified instance.
func (az *Cloud) NodeAddresses(name string) ([]api.NodeAddress, error) { func (az *Cloud) NodeAddresses(name types.NodeName) ([]api.NodeAddress, error) {
ip, err := az.getIPForMachine(name) ip, err := az.getIPForMachine(name)
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -35,18 +36,18 @@ func (az *Cloud) NodeAddresses(name string) ([]api.NodeAddress, error) { ...@@ -35,18 +36,18 @@ func (az *Cloud) NodeAddresses(name string) ([]api.NodeAddress, error) {
return []api.NodeAddress{ return []api.NodeAddress{
{Type: api.NodeInternalIP, Address: ip}, {Type: api.NodeInternalIP, Address: ip},
{Type: api.NodeHostName, Address: name}, {Type: api.NodeHostName, Address: string(name)},
}, nil }, nil
} }
// ExternalID returns the cloud provider ID of the specified instance (deprecated). // ExternalID returns the cloud provider ID of the specified instance (deprecated).
func (az *Cloud) ExternalID(name string) (string, error) { func (az *Cloud) ExternalID(name types.NodeName) (string, error) {
return az.InstanceID(name) return az.InstanceID(name)
} }
// 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)
func (az *Cloud) InstanceID(name string) (string, error) { func (az *Cloud) InstanceID(name types.NodeName) (string, error) {
machine, exists, err := az.getVirtualMachine(name) machine, exists, err := az.getVirtualMachine(name)
if err != nil { if err != nil {
return "", err return "", err
...@@ -60,7 +61,7 @@ func (az *Cloud) InstanceID(name string) (string, error) { ...@@ -60,7 +61,7 @@ func (az *Cloud) InstanceID(name string) (string, error) {
// 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)
// (Implementer Note): This is used by kubelet. Kubelet will label the node. Real log from kubelet: // (Implementer Note): This is used by kubelet. Kubelet will label the node. Real log from kubelet:
// Adding node label from cloud provider: beta.kubernetes.io/instance-type=[value] // Adding node label from cloud provider: beta.kubernetes.io/instance-type=[value]
func (az *Cloud) InstanceType(name string) (string, error) { func (az *Cloud) InstanceType(name types.NodeName) (string, error) {
machine, exists, err := az.getVirtualMachine(name) machine, exists, err := az.getVirtualMachine(name)
if err != nil { if err != nil {
return "", err return "", err
...@@ -71,7 +72,7 @@ func (az *Cloud) InstanceType(name string) (string, error) { ...@@ -71,7 +72,7 @@ func (az *Cloud) 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)
func (az *Cloud) List(filter string) ([]string, error) { func (az *Cloud) List(filter string) ([]types.NodeName, error) {
allNodes, err := az.listAllNodesInResourceGroup() allNodes, err := az.listAllNodesInResourceGroup()
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -82,9 +83,9 @@ func (az *Cloud) List(filter string) ([]string, error) { ...@@ -82,9 +83,9 @@ func (az *Cloud) List(filter string) ([]string, error) {
return nil, err return nil, err
} }
nodeNames := make([]string, len(filteredNodes)) nodeNames := make([]types.NodeName, len(filteredNodes))
for i, v := range filteredNodes { for i, v := range filteredNodes {
nodeNames[i] = *v.Name nodeNames[i] = types.NodeName(*v.Name)
} }
return nodeNames, nil return nodeNames, nil
...@@ -98,8 +99,8 @@ func (az *Cloud) AddSSHKeyToAllInstances(user string, keyData []byte) error { ...@@ -98,8 +99,8 @@ func (az *Cloud) AddSSHKeyToAllInstances(user string, keyData []byte) error {
// CurrentNodeName returns the name of the node we are currently running on // CurrentNodeName returns the name of the node we are currently running on
// On most clouds (e.g. GCE) this is the hostname, so we provide the hostname // On most clouds (e.g. GCE) this is the hostname, so we provide the hostname
func (az *Cloud) CurrentNodeName(hostname string) (string, error) { func (az *Cloud) CurrentNodeName(hostname string) (types.NodeName, error) {
return hostname, nil return types.NodeName(hostname), nil
} }
func (az *Cloud) listAllNodesInResourceGroup() ([]compute.VirtualMachine, error) { func (az *Cloud) listAllNodesInResourceGroup() ([]compute.VirtualMachine, error) {
...@@ -144,3 +145,15 @@ func filterNodes(nodes []compute.VirtualMachine, filter string) ([]compute.Virtu ...@@ -144,3 +145,15 @@ func filterNodes(nodes []compute.VirtualMachine, filter string) ([]compute.Virtu
return filteredNodes, nil return filteredNodes, nil
} }
// mapNodeNameToVMName maps a k8s NodeName to an Azure VM Name
// This is a simple string cast.
func mapNodeNameToVMName(nodeName types.NodeName) string {
return string(nodeName)
}
// mapVMNameToNodeName maps an Azure VM Name to a k8s NodeName
// This is a simple string cast.
func mapVMNameToNodeName(vmName string) types.NodeName {
return types.NodeName(vmName)
}
...@@ -27,6 +27,7 @@ import ( ...@@ -27,6 +27,7 @@ import (
"github.com/Azure/azure-sdk-for-go/arm/network" "github.com/Azure/azure-sdk-for-go/arm/network"
"github.com/Azure/go-autorest/autorest/to" "github.com/Azure/go-autorest/autorest/to"
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kubernetes/pkg/types"
) )
// GetLoadBalancer returns whether the specified load balancer exists, and // GetLoadBalancer returns whether the specified load balancer exists, and
...@@ -60,7 +61,7 @@ func (az *Cloud) GetLoadBalancer(clusterName string, service *api.Service) (stat ...@@ -60,7 +61,7 @@ func (az *Cloud) GetLoadBalancer(clusterName string, service *api.Service) (stat
} }
// EnsureLoadBalancer creates a new load balancer 'name', or updates the existing one. Returns the status of the balancer // EnsureLoadBalancer creates a new load balancer 'name', or updates the existing one. Returns the status of the balancer
func (az *Cloud) EnsureLoadBalancer(clusterName string, service *api.Service, hosts []string) (*api.LoadBalancerStatus, error) { func (az *Cloud) EnsureLoadBalancer(clusterName string, service *api.Service, nodeNames []string) (*api.LoadBalancerStatus, error) {
lbName := getLoadBalancerName(clusterName) lbName := getLoadBalancerName(clusterName)
pipName := getPublicIPName(clusterName, service) pipName := getPublicIPName(clusterName, service)
serviceName := getServiceName(service) serviceName := getServiceName(service)
...@@ -99,7 +100,7 @@ func (az *Cloud) EnsureLoadBalancer(clusterName string, service *api.Service, ho ...@@ -99,7 +100,7 @@ func (az *Cloud) EnsureLoadBalancer(clusterName string, service *api.Service, ho
} }
} }
lb, lbNeedsUpdate, err := az.reconcileLoadBalancer(lb, pip, clusterName, service, hosts) lb, lbNeedsUpdate, err := az.reconcileLoadBalancer(lb, pip, clusterName, service, nodeNames)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -114,11 +115,11 @@ func (az *Cloud) EnsureLoadBalancer(clusterName string, service *api.Service, ho ...@@ -114,11 +115,11 @@ func (az *Cloud) EnsureLoadBalancer(clusterName string, service *api.Service, ho
// Add the machines to the backend pool if they're not already // Add the machines to the backend pool if they're not already
lbBackendName := getBackendPoolName(clusterName) lbBackendName := getBackendPoolName(clusterName)
lbBackendPoolID := az.getBackendPoolID(lbName, lbBackendName) lbBackendPoolID := az.getBackendPoolID(lbName, lbBackendName)
hostUpdates := make([]func() error, len(hosts)) hostUpdates := make([]func() error, len(nodeNames))
for i, host := range hosts { for i, nodeName := range nodeNames {
localHost := host localNodeName := nodeName
f := func() error { f := func() error {
err := az.ensureHostInPool(serviceName, localHost, lbBackendPoolID) err := az.ensureHostInPool(serviceName, types.NodeName(localNodeName), lbBackendPoolID)
if err != nil { if err != nil {
return fmt.Errorf("ensure(%s): lb(%s) - failed to ensure host in pool: %q", serviceName, lbName, err) return fmt.Errorf("ensure(%s): lb(%s) - failed to ensure host in pool: %q", serviceName, lbName, err)
} }
...@@ -139,8 +140,8 @@ func (az *Cloud) EnsureLoadBalancer(clusterName string, service *api.Service, ho ...@@ -139,8 +140,8 @@ func (az *Cloud) EnsureLoadBalancer(clusterName string, service *api.Service, ho
} }
// UpdateLoadBalancer updates hosts under the specified load balancer. // UpdateLoadBalancer updates hosts under the specified load balancer.
func (az *Cloud) UpdateLoadBalancer(clusterName string, service *api.Service, hosts []string) error { func (az *Cloud) UpdateLoadBalancer(clusterName string, service *api.Service, nodeNames []string) error {
_, err := az.EnsureLoadBalancer(clusterName, service, hosts) _, err := az.EnsureLoadBalancer(clusterName, service, nodeNames)
return err return err
} }
...@@ -257,7 +258,7 @@ func (az *Cloud) ensurePublicIPDeleted(serviceName, pipName string) error { ...@@ -257,7 +258,7 @@ func (az *Cloud) ensurePublicIPDeleted(serviceName, pipName string) error {
// This ensures load balancer exists and the frontend ip config is setup. // This ensures load balancer exists and the frontend ip config is setup.
// This also reconciles the Service's Ports with the LoadBalancer config. // This also reconciles the Service's Ports with the LoadBalancer config.
// This entails adding rules/probes for expected Ports and removing stale rules/ports. // This entails adding rules/probes for expected Ports and removing stale rules/ports.
func (az *Cloud) reconcileLoadBalancer(lb network.LoadBalancer, pip *network.PublicIPAddress, clusterName string, service *api.Service, hosts []string) (network.LoadBalancer, bool, error) { func (az *Cloud) reconcileLoadBalancer(lb network.LoadBalancer, pip *network.PublicIPAddress, clusterName string, service *api.Service, nodeNames []string) (network.LoadBalancer, bool, error) {
lbName := getLoadBalancerName(clusterName) lbName := getLoadBalancerName(clusterName)
serviceName := getServiceName(service) serviceName := getServiceName(service)
lbFrontendIPConfigName := getFrontendIPConfigName(service) lbFrontendIPConfigName := getFrontendIPConfigName(service)
...@@ -556,8 +557,9 @@ func findSecurityRule(rules []network.SecurityRule, rule network.SecurityRule) b ...@@ -556,8 +557,9 @@ func findSecurityRule(rules []network.SecurityRule, rule network.SecurityRule) b
// This ensures the given VM's Primary NIC's Primary IP Configuration is // This ensures the given VM's Primary NIC's Primary IP Configuration is
// participating in the specified LoadBalancer Backend Pool. // participating in the specified LoadBalancer Backend Pool.
func (az *Cloud) ensureHostInPool(serviceName, machineName string, backendPoolID string) error { func (az *Cloud) ensureHostInPool(serviceName string, nodeName types.NodeName, backendPoolID string) error {
machine, err := az.VirtualMachinesClient.Get(az.ResourceGroup, machineName, "") vmName := mapNodeNameToVMName(nodeName)
machine, err := az.VirtualMachinesClient.Get(az.ResourceGroup, vmName, "")
if err != nil { if err != nil {
return err return err
} }
......
...@@ -24,6 +24,7 @@ import ( ...@@ -24,6 +24,7 @@ import (
"github.com/Azure/azure-sdk-for-go/arm/network" "github.com/Azure/azure-sdk-for-go/arm/network"
"github.com/Azure/go-autorest/autorest/to" "github.com/Azure/go-autorest/autorest/to"
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kubernetes/pkg/types"
) )
// ListRoutes lists all managed routes that belong to the specified clusterName // ListRoutes lists all managed routes that belong to the specified clusterName
...@@ -41,13 +42,13 @@ func (az *Cloud) ListRoutes(clusterName string) (routes []*cloudprovider.Route, ...@@ -41,13 +42,13 @@ func (az *Cloud) ListRoutes(clusterName string) (routes []*cloudprovider.Route,
if routeTable.Properties.Routes != nil { if routeTable.Properties.Routes != nil {
kubeRoutes = make([]*cloudprovider.Route, len(*routeTable.Properties.Routes)) kubeRoutes = make([]*cloudprovider.Route, len(*routeTable.Properties.Routes))
for i, route := range *routeTable.Properties.Routes { for i, route := range *routeTable.Properties.Routes {
instance := getInstanceName(*route.Name) instance := mapRouteNameToNodeName(*route.Name)
cidr := *route.Properties.AddressPrefix cidr := *route.Properties.AddressPrefix
glog.V(10).Infof("list: * instance=%q, cidr=%q", instance, cidr) glog.V(10).Infof("list: * instance=%q, cidr=%q", instance, cidr)
kubeRoutes[i] = &cloudprovider.Route{ kubeRoutes[i] = &cloudprovider.Route{
Name: *route.Name, Name: *route.Name,
TargetInstance: instance, TargetNode: instance,
DestinationCIDR: cidr, DestinationCIDR: cidr,
} }
} }
...@@ -61,7 +62,7 @@ func (az *Cloud) ListRoutes(clusterName string) (routes []*cloudprovider.Route, ...@@ -61,7 +62,7 @@ func (az *Cloud) ListRoutes(clusterName string) (routes []*cloudprovider.Route,
// route.Name will be ignored, although the cloud-provider may use nameHint // route.Name will be ignored, although the cloud-provider may use nameHint
// to create a more user-meaningful name. // to create a more user-meaningful name.
func (az *Cloud) CreateRoute(clusterName string, nameHint string, kubeRoute *cloudprovider.Route) error { func (az *Cloud) CreateRoute(clusterName string, nameHint string, kubeRoute *cloudprovider.Route) error {
glog.V(2).Infof("create: creating route. clusterName=%q instance=%q cidr=%q", clusterName, kubeRoute.TargetInstance, kubeRoute.DestinationCIDR) glog.V(2).Infof("create: creating route. clusterName=%q instance=%q cidr=%q", clusterName, kubeRoute.TargetNode, kubeRoute.DestinationCIDR)
routeTable, existsRouteTable, err := az.getRouteTable() routeTable, existsRouteTable, err := az.getRouteTable()
if err != nil { if err != nil {
...@@ -107,12 +108,12 @@ func (az *Cloud) CreateRoute(clusterName string, nameHint string, kubeRoute *clo ...@@ -107,12 +108,12 @@ func (az *Cloud) CreateRoute(clusterName string, nameHint string, kubeRoute *clo
} }
} }
targetIP, err := az.getIPForMachine(kubeRoute.TargetInstance) targetIP, err := az.getIPForMachine(kubeRoute.TargetNode)
if err != nil { if err != nil {
return err return err
} }
routeName := getRouteName(kubeRoute.TargetInstance) routeName := mapNodeNameToRouteName(kubeRoute.TargetNode)
route := network.Route{ route := network.Route{
Name: to.StringPtr(routeName), Name: to.StringPtr(routeName),
Properties: &network.RoutePropertiesFormat{ Properties: &network.RoutePropertiesFormat{
...@@ -122,40 +123,40 @@ func (az *Cloud) CreateRoute(clusterName string, nameHint string, kubeRoute *clo ...@@ -122,40 +123,40 @@ func (az *Cloud) CreateRoute(clusterName string, nameHint string, kubeRoute *clo
}, },
} }
glog.V(3).Infof("create: creating route: instance=%q cidr=%q", kubeRoute.TargetInstance, kubeRoute.DestinationCIDR) glog.V(3).Infof("create: creating route: instance=%q cidr=%q", kubeRoute.TargetNode, kubeRoute.DestinationCIDR)
_, err = az.RoutesClient.CreateOrUpdate(az.ResourceGroup, az.RouteTableName, *route.Name, route, nil) _, err = az.RoutesClient.CreateOrUpdate(az.ResourceGroup, az.RouteTableName, *route.Name, route, nil)
if err != nil { if err != nil {
return err return err
} }
glog.V(2).Infof("create: route created. clusterName=%q instance=%q cidr=%q", clusterName, kubeRoute.TargetInstance, kubeRoute.DestinationCIDR) glog.V(2).Infof("create: route created. clusterName=%q instance=%q cidr=%q", clusterName, kubeRoute.TargetNode, kubeRoute.DestinationCIDR)
return nil return nil
} }
// DeleteRoute deletes the specified managed route // DeleteRoute deletes the specified managed route
// Route should be as returned by ListRoutes // Route should be as returned by ListRoutes
func (az *Cloud) DeleteRoute(clusterName string, kubeRoute *cloudprovider.Route) error { func (az *Cloud) DeleteRoute(clusterName string, kubeRoute *cloudprovider.Route) error {
glog.V(2).Infof("delete: deleting route. clusterName=%q instance=%q cidr=%q", clusterName, kubeRoute.TargetInstance, kubeRoute.DestinationCIDR) glog.V(2).Infof("delete: deleting route. clusterName=%q instance=%q cidr=%q", clusterName, kubeRoute.TargetNode, kubeRoute.DestinationCIDR)
routeName := getRouteName(kubeRoute.TargetInstance) routeName := mapNodeNameToRouteName(kubeRoute.TargetNode)
_, err := az.RoutesClient.Delete(az.ResourceGroup, az.RouteTableName, routeName, nil) _, err := az.RoutesClient.Delete(az.ResourceGroup, az.RouteTableName, routeName, nil)
if err != nil { if err != nil {
return err return err
} }
glog.V(2).Infof("delete: route deleted. clusterName=%q instance=%q cidr=%q", clusterName, kubeRoute.TargetInstance, kubeRoute.DestinationCIDR) glog.V(2).Infof("delete: route deleted. clusterName=%q instance=%q cidr=%q", clusterName, kubeRoute.TargetNode, kubeRoute.DestinationCIDR)
return nil return nil
} }
// This must be kept in sync with getInstanceName. // This must be kept in sync with mapRouteNameToNodeName.
// These two functions enable stashing the instance name in the route // These two functions enable stashing the instance name in the route
// and then retrieving it later when listing. This is needed because // and then retrieving it later when listing. This is needed because
// Azure does not let you put tags/descriptions on the Route itself. // Azure does not let you put tags/descriptions on the Route itself.
func getRouteName(instanceName string) string { func mapNodeNameToRouteName(nodeName types.NodeName) string {
return fmt.Sprintf("%s", instanceName) return fmt.Sprintf("%s", nodeName)
} }
// Used with getRouteName. See comment on getRouteName. // Used with mapNodeNameToRouteName. See comment on mapNodeNameToRouteName.
func getInstanceName(routeName string) string { func mapRouteNameToNodeName(routeName string) types.NodeName {
return fmt.Sprintf("%s", routeName) return types.NodeName(fmt.Sprintf("%s", routeName))
} }
...@@ -23,6 +23,7 @@ import ( ...@@ -23,6 +23,7 @@ import (
"github.com/Azure/azure-sdk-for-go/arm/compute" "github.com/Azure/azure-sdk-for-go/arm/compute"
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kubernetes/pkg/cloudprovider" "k8s.io/kubernetes/pkg/cloudprovider"
"k8s.io/kubernetes/pkg/types"
) )
const ( const (
...@@ -31,8 +32,8 @@ const ( ...@@ -31,8 +32,8 @@ const (
// AttachDisk attaches a vhd to vm // AttachDisk attaches a vhd to vm
// the vhd must exist, can be identified by diskName, diskURI, and lun. // the vhd must exist, can be identified by diskName, diskURI, and lun.
func (az *Cloud) AttachDisk(diskName, diskURI, vmName string, lun int32, cachingMode compute.CachingTypes) error { func (az *Cloud) AttachDisk(diskName, diskURI string, nodeName types.NodeName, lun int32, cachingMode compute.CachingTypes) error {
vm, exists, err := az.getVirtualMachine(vmName) vm, exists, err := az.getVirtualMachine(nodeName)
if err != nil { if err != nil {
return err return err
} else if !exists { } else if !exists {
...@@ -58,6 +59,7 @@ func (az *Cloud) AttachDisk(diskName, diskURI, vmName string, lun int32, caching ...@@ -58,6 +59,7 @@ func (az *Cloud) AttachDisk(diskName, diskURI, vmName string, lun int32, caching
}, },
}, },
} }
vmName := mapNodeNameToVMName(nodeName)
_, err = az.VirtualMachinesClient.CreateOrUpdate(az.ResourceGroup, vmName, newVM, nil) _, err = az.VirtualMachinesClient.CreateOrUpdate(az.ResourceGroup, vmName, newVM, nil)
if err != nil { if err != nil {
glog.Errorf("azure attach failed, err: %v", err) glog.Errorf("azure attach failed, err: %v", err)
...@@ -65,7 +67,7 @@ func (az *Cloud) AttachDisk(diskName, diskURI, vmName string, lun int32, caching ...@@ -65,7 +67,7 @@ func (az *Cloud) AttachDisk(diskName, diskURI, vmName string, lun int32, caching
if strings.Contains(detail, "Code=\"AcquireDiskLeaseFailed\"") { if strings.Contains(detail, "Code=\"AcquireDiskLeaseFailed\"") {
// if lease cannot be acquired, immediately detach the disk and return the original error // if lease cannot be acquired, immediately detach the disk and return the original error
glog.Infof("failed to acquire disk lease, try detach") glog.Infof("failed to acquire disk lease, try detach")
az.DetachDiskByName(diskName, diskURI, vmName) az.DetachDiskByName(diskName, diskURI, nodeName)
} }
} else { } else {
glog.V(4).Infof("azure attach succeeded") glog.V(4).Infof("azure attach succeeded")
...@@ -75,11 +77,11 @@ func (az *Cloud) AttachDisk(diskName, diskURI, vmName string, lun int32, caching ...@@ -75,11 +77,11 @@ func (az *Cloud) AttachDisk(diskName, diskURI, vmName string, lun int32, caching
// DetachDiskByName detaches a vhd from host // DetachDiskByName detaches a vhd from host
// the vhd can be identified by diskName or diskURI // the vhd can be identified by diskName or diskURI
func (az *Cloud) DetachDiskByName(diskName, diskURI, vmName string) error { func (az *Cloud) DetachDiskByName(diskName, diskURI string, nodeName types.NodeName) error {
vm, exists, err := az.getVirtualMachine(vmName) vm, exists, err := az.getVirtualMachine(nodeName)
if err != nil || !exists { if err != nil || !exists {
// if host doesn't exist, no need to detach // if host doesn't exist, no need to detach
glog.Warningf("cannot find node %s, skip detaching disk %s", vmName, diskName) glog.Warningf("cannot find node %s, skip detaching disk %s", nodeName, diskName)
return nil return nil
} }
...@@ -100,6 +102,7 @@ func (az *Cloud) DetachDiskByName(diskName, diskURI, vmName string) error { ...@@ -100,6 +102,7 @@ func (az *Cloud) DetachDiskByName(diskName, diskURI, vmName string) error {
}, },
}, },
} }
vmName := mapNodeNameToVMName(nodeName)
_, err = az.VirtualMachinesClient.CreateOrUpdate(az.ResourceGroup, vmName, newVM, nil) _, err = az.VirtualMachinesClient.CreateOrUpdate(az.ResourceGroup, vmName, newVM, nil)
if err != nil { if err != nil {
glog.Errorf("azure disk detach failed, err: %v", err) glog.Errorf("azure disk detach failed, err: %v", err)
...@@ -110,8 +113,8 @@ func (az *Cloud) DetachDiskByName(diskName, diskURI, vmName string) error { ...@@ -110,8 +113,8 @@ func (az *Cloud) DetachDiskByName(diskName, diskURI, vmName string) error {
} }
// GetDiskLun finds the lun on the host that the vhd is attached to, given a vhd's diskName and diskURI // GetDiskLun finds the lun on the host that the vhd is attached to, given a vhd's diskName and diskURI
func (az *Cloud) GetDiskLun(diskName, diskURI, vmName string) (int32, error) { func (az *Cloud) GetDiskLun(diskName, diskURI string, nodeName types.NodeName) (int32, error) {
vm, exists, err := az.getVirtualMachine(vmName) vm, exists, err := az.getVirtualMachine(nodeName)
if err != nil { if err != nil {
return -1, err return -1, err
} else if !exists { } else if !exists {
...@@ -130,8 +133,8 @@ func (az *Cloud) GetDiskLun(diskName, diskURI, vmName string) (int32, error) { ...@@ -130,8 +133,8 @@ func (az *Cloud) GetDiskLun(diskName, diskURI, vmName string) (int32, error) {
// GetNextDiskLun searches all vhd attachment on the host and find unused lun // GetNextDiskLun searches all vhd attachment on the host and find unused lun
// return -1 if all luns are used // return -1 if all luns are used
func (az *Cloud) GetNextDiskLun(vmName string) (int32, error) { func (az *Cloud) GetNextDiskLun(nodeName types.NodeName) (int32, error) {
vm, exists, err := az.getVirtualMachine(vmName) vm, exists, err := az.getVirtualMachine(nodeName)
if err != nil { if err != nil {
return -1, err return -1, err
} else if !exists { } else if !exists {
......
...@@ -25,6 +25,7 @@ import ( ...@@ -25,6 +25,7 @@ import (
"github.com/Azure/azure-sdk-for-go/arm/compute" "github.com/Azure/azure-sdk-for-go/arm/compute"
"github.com/Azure/azure-sdk-for-go/arm/network" "github.com/Azure/azure-sdk-for-go/arm/network"
"k8s.io/kubernetes/pkg/types"
) )
const ( const (
...@@ -202,8 +203,8 @@ outer: ...@@ -202,8 +203,8 @@ outer:
return -1, fmt.Errorf("SecurityGroup priorities are exhausted") return -1, fmt.Errorf("SecurityGroup priorities are exhausted")
} }
func (az *Cloud) getIPForMachine(machineName string) (string, error) { func (az *Cloud) getIPForMachine(nodeName types.NodeName) (string, error) {
machine, exists, err := az.getVirtualMachine(machineName) machine, exists, err := az.getVirtualMachine(nodeName)
if !exists { if !exists {
return "", cloudprovider.InstanceNotFound return "", cloudprovider.InstanceNotFound
} }
......
...@@ -22,6 +22,7 @@ import ( ...@@ -22,6 +22,7 @@ import (
"github.com/Azure/azure-sdk-for-go/arm/compute" "github.com/Azure/azure-sdk-for-go/arm/compute"
"github.com/Azure/azure-sdk-for-go/arm/network" "github.com/Azure/azure-sdk-for-go/arm/network"
"github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest"
"k8s.io/kubernetes/pkg/types"
) )
// checkExistsFromError inspects an error and returns a true if err is nil, // checkExistsFromError inspects an error and returns a true if err is nil,
...@@ -38,10 +39,11 @@ func checkResourceExistsFromError(err error) (bool, error) { ...@@ -38,10 +39,11 @@ func checkResourceExistsFromError(err error) (bool, error) {
return false, v return false, v
} }
func (az *Cloud) getVirtualMachine(machineName string) (vm compute.VirtualMachine, exists bool, err error) { func (az *Cloud) getVirtualMachine(nodeName types.NodeName) (vm compute.VirtualMachine, exists bool, err error) {
var realErr error var realErr error
vm, err = az.VirtualMachinesClient.Get(az.ResourceGroup, machineName, "") vmName := string(nodeName)
vm, err = az.VirtualMachinesClient.Get(az.ResourceGroup, vmName, "")
exists, realErr = checkResourceExistsFromError(err) exists, realErr = checkResourceExistsFromError(err)
if realErr != nil { if realErr != nil {
......
...@@ -25,6 +25,7 @@ import ( ...@@ -25,6 +25,7 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/cloudprovider" "k8s.io/kubernetes/pkg/cloudprovider"
"k8s.io/kubernetes/pkg/types"
) )
const ProviderName = "fake" const ProviderName = "fake"
...@@ -49,9 +50,9 @@ type FakeCloud struct { ...@@ -49,9 +50,9 @@ type FakeCloud struct {
Err error Err error
Calls []string Calls []string
Addresses []api.NodeAddress Addresses []api.NodeAddress
ExtID map[string]string ExtID map[types.NodeName]string
InstanceTypes map[string]string InstanceTypes map[types.NodeName]string
Machines []string Machines []types.NodeName
NodeResources *api.NodeResources NodeResources *api.NodeResources
ClusterList []string ClusterList []string
MasterName string MasterName string
...@@ -173,13 +174,13 @@ func (f *FakeCloud) AddSSHKeyToAllInstances(user string, keyData []byte) error { ...@@ -173,13 +174,13 @@ func (f *FakeCloud) AddSSHKeyToAllInstances(user string, keyData []byte) error {
} }
// Implementation of Instances.CurrentNodeName // Implementation of Instances.CurrentNodeName
func (f *FakeCloud) CurrentNodeName(hostname string) (string, error) { func (f *FakeCloud) CurrentNodeName(hostname string) (types.NodeName, error) {
return hostname, nil return types.NodeName(hostname), nil
} }
// NodeAddresses is a test-spy implementation of Instances.NodeAddresses. // NodeAddresses is a test-spy implementation of Instances.NodeAddresses.
// It adds an entry "node-addresses" into the internal method call record. // It adds an entry "node-addresses" into the internal method call record.
func (f *FakeCloud) NodeAddresses(instance string) ([]api.NodeAddress, error) { func (f *FakeCloud) NodeAddresses(instance types.NodeName) ([]api.NodeAddress, error) {
f.addCall("node-addresses") f.addCall("node-addresses")
return f.Addresses, f.Err return f.Addresses, f.Err
} }
...@@ -187,30 +188,30 @@ func (f *FakeCloud) NodeAddresses(instance string) ([]api.NodeAddress, error) { ...@@ -187,30 +188,30 @@ func (f *FakeCloud) NodeAddresses(instance string) ([]api.NodeAddress, error) {
// ExternalID is a test-spy implementation of Instances.ExternalID. // ExternalID is a test-spy implementation of Instances.ExternalID.
// It adds an entry "external-id" into the internal method call record. // It adds an entry "external-id" into the internal method call record.
// It returns an external id to the mapped instance name, if not found, it will return "ext-{instance}" // It returns an external id to the mapped instance name, if not found, it will return "ext-{instance}"
func (f *FakeCloud) ExternalID(instance string) (string, error) { func (f *FakeCloud) ExternalID(nodeName types.NodeName) (string, error) {
f.addCall("external-id") f.addCall("external-id")
return f.ExtID[instance], f.Err return f.ExtID[nodeName], f.Err
} }
// InstanceID returns the cloud provider ID of the specified instance. // InstanceID returns the cloud provider ID of the node with the specified Name.
func (f *FakeCloud) InstanceID(instance string) (string, error) { func (f *FakeCloud) InstanceID(nodeName types.NodeName) (string, error) {
f.addCall("instance-id") f.addCall("instance-id")
return f.ExtID[instance], nil return f.ExtID[nodeName], nil
} }
// InstanceType returns the type of the specified instance. // InstanceType returns the type of the specified instance.
func (f *FakeCloud) InstanceType(instance string) (string, error) { func (f *FakeCloud) InstanceType(instance types.NodeName) (string, error) {
f.addCall("instance-type") f.addCall("instance-type")
return f.InstanceTypes[instance], nil 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) ([]types.NodeName, error) {
f.addCall("list") f.addCall("list")
result := []string{} result := []types.NodeName{}
for _, machine := range f.Machines { for _, machine := range f.Machines {
if match, _ := regexp.MatchString(filter, machine); match { if match, _ := regexp.MatchString(filter, string(machine)); match {
result = append(result, machine) result = append(result, machine)
} }
} }
......
...@@ -122,16 +122,16 @@ const ( ...@@ -122,16 +122,16 @@ const (
// Disks is interface for manipulation with GCE PDs. // Disks is interface for manipulation with GCE PDs.
type Disks interface { type Disks interface {
// AttachDisk attaches given disk to given instance. Current instance // AttachDisk attaches given disk to the node with the specified NodeName.
// is used when instanceID is empty string. // Current instance is used when instanceID is empty string.
AttachDisk(diskName, instanceID string, readOnly bool) error AttachDisk(diskName string, nodeName types.NodeName, readOnly bool) error
// DetachDisk detaches given disk to given instance. Current instance // DetachDisk detaches given disk to the node with the specified NodeName.
// is used when instanceID is empty string. // Current instance is used when nodeName is empty string.
DetachDisk(devicePath, instanceID string) error DetachDisk(devicePath string, nodeName types.NodeName) error
// DiskIsAttached checks if a disk is attached to the given node. // DiskIsAttached checks if a disk is attached to the node with the specified NodeName.
DiskIsAttached(diskName, instanceID string) (bool, error) DiskIsAttached(diskName string, nodeName types.NodeName) (bool, error)
// CreateDisk creates a new PD with given properties. Tags are serialized // CreateDisk creates a new PD with given properties. Tags are serialized
// as JSON into Description field. // as JSON into Description field.
...@@ -2095,8 +2095,8 @@ func canonicalizeInstanceName(name string) string { ...@@ -2095,8 +2095,8 @@ func canonicalizeInstanceName(name string) string {
} }
// Implementation of Instances.CurrentNodeName // Implementation of Instances.CurrentNodeName
func (gce *GCECloud) CurrentNodeName(hostname string) (string, error) { func (gce *GCECloud) CurrentNodeName(hostname string) (types.NodeName, error) {
return hostname, nil return types.NodeName(hostname), nil
} }
func (gce *GCECloud) AddSSHKeyToAllInstances(user string, keyData []byte) error { func (gce *GCECloud) AddSSHKeyToAllInstances(user string, keyData []byte) error {
...@@ -2145,7 +2145,7 @@ func (gce *GCECloud) AddSSHKeyToAllInstances(user string, keyData []byte) error ...@@ -2145,7 +2145,7 @@ func (gce *GCECloud) AddSSHKeyToAllInstances(user string, keyData []byte) error
} }
// NodeAddresses is an implementation of Instances.NodeAddresses. // NodeAddresses is an implementation of Instances.NodeAddresses.
func (gce *GCECloud) NodeAddresses(_ string) ([]api.NodeAddress, error) { func (gce *GCECloud) NodeAddresses(_ types.NodeName) ([]api.NodeAddress, error) {
internalIP, err := metadata.Get("instance/network-interfaces/0/ip") internalIP, err := metadata.Get("instance/network-interfaces/0/ip")
if err != nil { if err != nil {
return nil, fmt.Errorf("couldn't get internal IP: %v", err) return nil, fmt.Errorf("couldn't get internal IP: %v", err)
...@@ -2172,11 +2172,23 @@ func (gce *GCECloud) isCurrentInstance(instanceID string) bool { ...@@ -2172,11 +2172,23 @@ func (gce *GCECloud) isCurrentInstance(instanceID string) bool {
return currentInstanceID == canonicalizeInstanceName(instanceID) return currentInstanceID == canonicalizeInstanceName(instanceID)
} }
// ExternalID returns the cloud provider ID of the specified instance (deprecated). // mapNodeNameToInstanceName maps a k8s NodeName to a GCE Instance Name
func (gce *GCECloud) ExternalID(instance string) (string, error) { // This is a simple string cast.
func mapNodeNameToInstanceName(nodeName types.NodeName) string {
return string(nodeName)
}
// mapInstanceToNodeName maps a GCE Instance to a k8s NodeName
func mapInstanceToNodeName(instance *compute.Instance) types.NodeName {
return types.NodeName(instance.Name)
}
// ExternalID returns the cloud provider ID of the node with the specified NodeName (deprecated).
func (gce *GCECloud) ExternalID(nodeName types.NodeName) (string, error) {
instanceName := mapNodeNameToInstanceName(nodeName)
if gce.useMetadataServer { if gce.useMetadataServer {
// Use metadata, if possible, to fetch ID. See issue #12000 // Use metadata, if possible, to fetch ID. See issue #12000
if gce.isCurrentInstance(instance) { if gce.isCurrentInstance(instanceName) {
externalInstanceID, err := getCurrentExternalIDViaMetadata() externalInstanceID, err := getCurrentExternalIDViaMetadata()
if err == nil { if err == nil {
return externalInstanceID, nil return externalInstanceID, nil
...@@ -2185,15 +2197,16 @@ func (gce *GCECloud) ExternalID(instance string) (string, error) { ...@@ -2185,15 +2197,16 @@ func (gce *GCECloud) ExternalID(instance string) (string, error) {
} }
// Fallback to GCE API call if metadata server fails to retrieve ID // Fallback to GCE API call if metadata server fails to retrieve ID
inst, err := gce.getInstanceByName(instance) inst, err := gce.getInstanceByName(instanceName)
if err != nil { if err != nil {
return "", err return "", err
} }
return strconv.FormatUint(inst.ID, 10), nil return strconv.FormatUint(inst.ID, 10), nil
} }
// InstanceID returns the cloud provider ID of the specified instance. // InstanceID returns the cloud provider ID of the node with the specified NodeName.
func (gce *GCECloud) InstanceID(instanceName string) (string, error) { func (gce *GCECloud) InstanceID(nodeName types.NodeName) (string, error) {
instanceName := mapNodeNameToInstanceName(nodeName)
if gce.useMetadataServer { if gce.useMetadataServer {
// Use metadata, if possible, to fetch ID. See issue #12000 // Use metadata, if possible, to fetch ID. See issue #12000
if gce.isCurrentInstance(instanceName) { if gce.isCurrentInstance(instanceName) {
...@@ -2210,8 +2223,9 @@ func (gce *GCECloud) InstanceID(instanceName string) (string, error) { ...@@ -2210,8 +2223,9 @@ 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. // InstanceType returns the type of the specified node with the specified NodeName.
func (gce *GCECloud) InstanceType(instanceName string) (string, error) { func (gce *GCECloud) InstanceType(nodeName types.NodeName) (string, error) {
instanceName := mapNodeNameToInstanceName(nodeName)
if gce.useMetadataServer { if gce.useMetadataServer {
// Use metadata, if possible, to fetch ID. See issue #12000 // Use metadata, if possible, to fetch ID. See issue #12000
if gce.isCurrentInstance(instanceName) { if gce.isCurrentInstance(instanceName) {
...@@ -2229,8 +2243,8 @@ func (gce *GCECloud) InstanceType(instanceName string) (string, error) { ...@@ -2229,8 +2243,8 @@ func (gce *GCECloud) InstanceType(instanceName string) (string, error) {
} }
// 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) ([]types.NodeName, error) {
var instances []string var instances []types.NodeName
// TODO: Parallelize, although O(zones) so not too bad (N <= 3 typically) // TODO: Parallelize, although O(zones) so not too bad (N <= 3 typically)
for _, zone := range gce.managedZones { for _, zone := range gce.managedZones {
pageToken := "" pageToken := ""
...@@ -2249,7 +2263,7 @@ func (gce *GCECloud) List(filter string) ([]string, error) { ...@@ -2249,7 +2263,7 @@ func (gce *GCECloud) List(filter string) ([]string, error) {
} }
pageToken = res.NextPageToken pageToken = res.NextPageToken
for _, instance := range res.Items { for _, instance := range res.Items {
instances = append(instances, instance.Name) instances = append(instances, mapInstanceToNodeName(instance))
} }
} }
if page >= maxPages { if page >= maxPages {
...@@ -2349,7 +2363,9 @@ func (gce *GCECloud) ListRoutes(clusterName string) ([]*cloudprovider.Route, err ...@@ -2349,7 +2363,9 @@ func (gce *GCECloud) ListRoutes(clusterName string) ([]*cloudprovider.Route, err
} }
target := path.Base(r.NextHopInstance) target := path.Base(r.NextHopInstance)
routes = append(routes, &cloudprovider.Route{Name: r.Name, TargetInstance: target, DestinationCIDR: r.DestRange}) // TODO: Should we lastComponent(target) this?
targetNodeName := types.NodeName(target) // NodeName == Instance Name on GCE
routes = append(routes, &cloudprovider.Route{Name: r.Name, TargetNode: targetNodeName, DestinationCIDR: r.DestRange})
} }
} }
if page >= maxPages { if page >= maxPages {
...@@ -2365,7 +2381,8 @@ func gceNetworkURL(project, network string) string { ...@@ -2365,7 +2381,8 @@ func gceNetworkURL(project, network string) string {
func (gce *GCECloud) CreateRoute(clusterName string, nameHint string, route *cloudprovider.Route) error { func (gce *GCECloud) CreateRoute(clusterName string, nameHint string, route *cloudprovider.Route) error {
routeName := truncateClusterName(clusterName) + "-" + nameHint routeName := truncateClusterName(clusterName) + "-" + nameHint
targetInstance, err := gce.getInstanceByName(route.TargetInstance) instanceName := mapNodeNameToInstanceName(route.TargetNode)
targetInstance, err := gce.getInstanceByName(instanceName)
if err != nil { if err != nil {
return err return err
} }
...@@ -2545,10 +2562,11 @@ func (gce *GCECloud) GetAutoLabelsForPD(name string, zone string) (map[string]st ...@@ -2545,10 +2562,11 @@ func (gce *GCECloud) GetAutoLabelsForPD(name string, zone string) (map[string]st
return labels, nil return labels, nil
} }
func (gce *GCECloud) AttachDisk(diskName, instanceID string, readOnly bool) error { func (gce *GCECloud) AttachDisk(diskName string, nodeName types.NodeName, readOnly bool) error {
instance, err := gce.getInstanceByName(instanceID) instanceName := mapNodeNameToInstanceName(nodeName)
instance, err := gce.getInstanceByName(instanceName)
if err != nil { if err != nil {
return fmt.Errorf("error getting instance %q", instanceID) return fmt.Errorf("error getting instance %q", instanceName)
} }
disk, err := gce.getDiskByName(diskName, instance.Zone) disk, err := gce.getDiskByName(diskName, instance.Zone)
if err != nil { if err != nil {
...@@ -2560,7 +2578,7 @@ func (gce *GCECloud) AttachDisk(diskName, instanceID string, readOnly bool) erro ...@@ -2560,7 +2578,7 @@ func (gce *GCECloud) AttachDisk(diskName, instanceID string, readOnly bool) erro
} }
attachedDisk := gce.convertDiskToAttachedDisk(disk, readWrite) attachedDisk := gce.convertDiskToAttachedDisk(disk, readWrite)
attachOp, err := gce.service.Instances.AttachDisk(gce.projectID, disk.Zone, instanceID, attachedDisk).Do() attachOp, err := gce.service.Instances.AttachDisk(gce.projectID, disk.Zone, instanceName, attachedDisk).Do()
if err != nil { if err != nil {
return err return err
} }
...@@ -2568,19 +2586,20 @@ func (gce *GCECloud) AttachDisk(diskName, instanceID string, readOnly bool) erro ...@@ -2568,19 +2586,20 @@ func (gce *GCECloud) AttachDisk(diskName, instanceID string, readOnly bool) erro
return gce.waitForZoneOp(attachOp, disk.Zone) return gce.waitForZoneOp(attachOp, disk.Zone)
} }
func (gce *GCECloud) DetachDisk(devicePath, instanceID string) error { func (gce *GCECloud) DetachDisk(devicePath string, nodeName types.NodeName) error {
inst, err := gce.getInstanceByName(instanceID) instanceName := mapNodeNameToInstanceName(nodeName)
inst, err := gce.getInstanceByName(instanceName)
if err != nil { if err != nil {
if err == cloudprovider.InstanceNotFound { if err == cloudprovider.InstanceNotFound {
// If instance no longer exists, safe to assume volume is not attached. // If instance no longer exists, safe to assume volume is not attached.
glog.Warningf( glog.Warningf(
"Instance %q does not exist. DetachDisk will assume PD %q is not attached to it.", "Instance %q does not exist. DetachDisk will assume PD %q is not attached to it.",
instanceID, instanceName,
devicePath) devicePath)
return nil return nil
} }
return fmt.Errorf("error getting instance %q", instanceID) return fmt.Errorf("error getting instance %q", instanceName)
} }
detachOp, err := gce.service.Instances.DetachDisk(gce.projectID, inst.Zone, inst.Name, devicePath).Do() detachOp, err := gce.service.Instances.DetachDisk(gce.projectID, inst.Zone, inst.Name, devicePath).Do()
...@@ -2591,14 +2610,15 @@ func (gce *GCECloud) DetachDisk(devicePath, instanceID string) error { ...@@ -2591,14 +2610,15 @@ func (gce *GCECloud) DetachDisk(devicePath, instanceID string) error {
return gce.waitForZoneOp(detachOp, inst.Zone) return gce.waitForZoneOp(detachOp, inst.Zone)
} }
func (gce *GCECloud) DiskIsAttached(diskName, instanceID string) (bool, error) { func (gce *GCECloud) DiskIsAttached(diskName string, nodeName types.NodeName) (bool, error) {
instance, err := gce.getInstanceByName(instanceID) instanceName := mapNodeNameToInstanceName(nodeName)
instance, err := gce.getInstanceByName(instanceName)
if err != nil { if err != nil {
if err == cloudprovider.InstanceNotFound { if err == cloudprovider.InstanceNotFound {
// If instance no longer exists, safe to assume volume is not attached. // If instance no longer exists, safe to assume volume is not attached.
glog.Warningf( glog.Warningf(
"Instance %q does not exist. DiskIsAttached will assume PD %q is not attached to it.", "Instance %q does not exist. DiskIsAttached will assume PD %q is not attached to it.",
instanceID, instanceName,
diskName) diskName)
return false, nil return false, nil
} }
......
...@@ -30,6 +30,7 @@ import ( ...@@ -30,6 +30,7 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/cloudprovider" "k8s.io/kubernetes/pkg/cloudprovider"
"k8s.io/kubernetes/pkg/types"
) )
const ( const (
...@@ -89,8 +90,8 @@ func newMesosCloud(configReader io.Reader) (*MesosCloud, error) { ...@@ -89,8 +90,8 @@ func newMesosCloud(configReader io.Reader) (*MesosCloud, error) {
} }
// Implementation of Instances.CurrentNodeName // Implementation of Instances.CurrentNodeName
func (c *MesosCloud) CurrentNodeName(hostname string) (string, error) { func (c *MesosCloud) CurrentNodeName(hostname string) (types.NodeName, error) {
return hostname, nil return types.NodeName(hostname), nil
} }
func (c *MesosCloud) AddSSHKeyToAllInstances(user string, keyData []byte) error { func (c *MesosCloud) AddSSHKeyToAllInstances(user string, keyData []byte) error {
...@@ -190,8 +191,15 @@ func ipAddress(name string) (net.IP, error) { ...@@ -190,8 +191,15 @@ func ipAddress(name string) (net.IP, error) {
return ipaddr, nil return ipaddr, nil
} }
// ExternalID returns the cloud provider ID of the specified instance (deprecated). // mapNodeNameToPrivateDNSName maps a k8s NodeName to an mesos hostname.
func (c *MesosCloud) ExternalID(instance string) (string, error) { // This is a simple string cast
func mapNodeNameToHostname(nodeName types.NodeName) string {
return string(nodeName)
}
// ExternalID returns the cloud provider ID of the instance with the specified nodeName (deprecated).
func (c *MesosCloud) ExternalID(nodeName types.NodeName) (string, error) {
hostname := mapNodeNameToHostname(nodeName)
//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())
defer cancel() defer cancel()
...@@ -201,7 +209,7 @@ func (c *MesosCloud) ExternalID(instance string) (string, error) { ...@@ -201,7 +209,7 @@ func (c *MesosCloud) ExternalID(instance string) (string, error) {
return "", err return "", err
} }
node := nodes[instance] node := nodes[hostname]
if node == nil { if node == nil {
return "", cloudprovider.InstanceNotFound return "", cloudprovider.InstanceNotFound
} }
...@@ -213,13 +221,13 @@ func (c *MesosCloud) ExternalID(instance string) (string, error) { ...@@ -213,13 +221,13 @@ func (c *MesosCloud) ExternalID(instance string) (string, error) {
return ip.String(), nil return ip.String(), nil
} }
// InstanceID returns the cloud provider ID of the specified instance. // InstanceID returns the cloud provider ID of the instance with the specified nodeName.
func (c *MesosCloud) InstanceID(name string) (string, error) { func (c *MesosCloud) InstanceID(nodeName types.NodeName) (string, error) {
return "", nil return "", nil
} }
// InstanceType returns the type of the specified instance. // InstanceType returns the type of the instance with the specified nodeName.
func (c *MesosCloud) InstanceType(name string) (string, error) { func (c *MesosCloud) InstanceType(nodeName types.NodeName) (string, error) {
return "", nil return "", nil
} }
...@@ -241,7 +249,7 @@ func (c *MesosCloud) listNodes() (map[string]*slaveNode, error) { ...@@ -241,7 +249,7 @@ func (c *MesosCloud) listNodes() (map[string]*slaveNode, error) {
// List lists instances that match 'filter' which is a regular expression // List lists instances that match 'filter' which is a regular expression
// which must match the entire instance name (fqdn). // which must match the entire instance name (fqdn).
func (c *MesosCloud) List(filter string) ([]string, error) { func (c *MesosCloud) List(filter string) ([]types.NodeName, error) {
nodes, err := c.listNodes() nodes, err := c.listNodes()
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -250,13 +258,13 @@ func (c *MesosCloud) List(filter string) ([]string, error) { ...@@ -250,13 +258,13 @@ func (c *MesosCloud) List(filter string) ([]string, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
addr := []string{} names := []types.NodeName{}
for _, node := range nodes { for _, node := range nodes {
if filterRegex.MatchString(node.hostname) { if filterRegex.MatchString(node.hostname) {
addr = append(addr, node.hostname) names = append(names, types.NodeName(node.hostname))
} }
} }
return addr, nil return names, nil
} }
// ListWithKubelet list those instance which have no running kubelet, i.e. the // ListWithKubelet list those instance which have no running kubelet, i.e. the
...@@ -275,8 +283,9 @@ func (c *MesosCloud) ListWithoutKubelet() ([]string, error) { ...@@ -275,8 +283,9 @@ func (c *MesosCloud) ListWithoutKubelet() ([]string, error) {
return addr, nil return addr, nil
} }
// NodeAddresses returns the addresses of the specified instance. // NodeAddresses returns the addresses of the instance with the specified nodeName.
func (c *MesosCloud) NodeAddresses(name string) ([]api.NodeAddress, error) { func (c *MesosCloud) NodeAddresses(nodeName types.NodeName) ([]api.NodeAddress, error) {
name := mapNodeNameToHostname(nodeName)
ip, err := ipAddress(name) ip, err := ipAddress(name)
if err != nil { if err != nil {
return nil, err return nil, err
......
...@@ -25,6 +25,7 @@ import ( ...@@ -25,6 +25,7 @@ import (
log "github.com/golang/glog" log "github.com/golang/glog"
"k8s.io/kubernetes/pkg/cloudprovider" "k8s.io/kubernetes/pkg/cloudprovider"
"k8s.io/kubernetes/pkg/types"
) )
func TestIPAddress(t *testing.T) { func TestIPAddress(t *testing.T) {
...@@ -268,7 +269,7 @@ func Test_ExternalID(t *testing.T) { ...@@ -268,7 +269,7 @@ func Test_ExternalID(t *testing.T) {
t.Fatalf("ExternalID did not return InstanceNotFound on an unknown instance") t.Fatalf("ExternalID did not return InstanceNotFound on an unknown instance")
} }
slaveName := "mesos3.internal.company.com" slaveName := types.NodeName("mesos3.internal.company.com")
id, err := mesosCloud.ExternalID(slaveName) id, err := mesosCloud.ExternalID(slaveName)
if id != "" { if id != "" {
t.Fatalf("ExternalID should not be able to resolve %q", slaveName) t.Fatalf("ExternalID should not be able to resolve %q", slaveName)
......
...@@ -37,6 +37,7 @@ import ( ...@@ -37,6 +37,7 @@ import (
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/cloudprovider" "k8s.io/kubernetes/pkg/cloudprovider"
"k8s.io/kubernetes/pkg/types"
) )
const ProviderName = "openstack" const ProviderName = "openstack"
...@@ -237,9 +238,20 @@ func newOpenStack(cfg Config) (*OpenStack, error) { ...@@ -237,9 +238,20 @@ func newOpenStack(cfg Config) (*OpenStack, error) {
return &os, nil return &os, nil
} }
func getServerByName(client *gophercloud.ServiceClient, name string) (*servers.Server, error) { // mapNodeNameToServerName maps a k8s NodeName to an OpenStack Server Name
// This is a simple string cast.
func mapNodeNameToServerName(nodeName types.NodeName) string {
return string(nodeName)
}
// mapServerToNodeName maps an OpenStack Server to a k8s NodeName
func mapServerToNodeName(server *servers.Server) types.NodeName {
return types.NodeName(server.Name)
}
func getServerByName(client *gophercloud.ServiceClient, name types.NodeName) (*servers.Server, error) {
opts := servers.ListOpts{ opts := servers.ListOpts{
Name: fmt.Sprintf("^%s$", regexp.QuoteMeta(name)), Name: fmt.Sprintf("^%s$", regexp.QuoteMeta(mapNodeNameToServerName(name))),
Status: "ACTIVE", Status: "ACTIVE",
} }
pager := servers.List(client, opts) pager := servers.List(client, opts)
...@@ -270,7 +282,7 @@ func getServerByName(client *gophercloud.ServiceClient, name string) (*servers.S ...@@ -270,7 +282,7 @@ func getServerByName(client *gophercloud.ServiceClient, name string) (*servers.S
return &serverList[0], nil return &serverList[0], nil
} }
func getAddressesByName(client *gophercloud.ServiceClient, name string) ([]api.NodeAddress, error) { func getAddressesByName(client *gophercloud.ServiceClient, name types.NodeName) ([]api.NodeAddress, error) {
srv, err := getServerByName(client, name) srv, err := getServerByName(client, name)
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -339,7 +351,7 @@ func getAddressesByName(client *gophercloud.ServiceClient, name string) ([]api.N ...@@ -339,7 +351,7 @@ func getAddressesByName(client *gophercloud.ServiceClient, name string) ([]api.N
return addrs, nil return addrs, nil
} }
func getAddressByName(client *gophercloud.ServiceClient, name string) (string, error) { func getAddressByName(client *gophercloud.ServiceClient, name types.NodeName) (string, error) {
addrs, err := getAddressesByName(client, name) addrs, err := getAddressesByName(client, name)
if err != nil { if err != nil {
return "", err return "", err
......
...@@ -29,6 +29,7 @@ import ( ...@@ -29,6 +29,7 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/api/resource"
"k8s.io/kubernetes/pkg/cloudprovider" "k8s.io/kubernetes/pkg/cloudprovider"
"k8s.io/kubernetes/pkg/types"
) )
type Instances struct { type Instances struct {
...@@ -81,7 +82,7 @@ func (os *OpenStack) Instances() (cloudprovider.Instances, bool) { ...@@ -81,7 +82,7 @@ func (os *OpenStack) Instances() (cloudprovider.Instances, bool) {
return &Instances{compute, flavor_to_resource}, true return &Instances{compute, flavor_to_resource}, true
} }
func (i *Instances) List(name_filter string) ([]string, error) { func (i *Instances) List(name_filter string) ([]types.NodeName, error) {
glog.V(4).Infof("openstack List(%v) called", name_filter) glog.V(4).Infof("openstack List(%v) called", name_filter)
opts := servers.ListOpts{ opts := servers.ListOpts{
...@@ -90,14 +91,14 @@ func (i *Instances) List(name_filter string) ([]string, error) { ...@@ -90,14 +91,14 @@ func (i *Instances) List(name_filter string) ([]string, error) {
} }
pager := servers.List(i.compute, opts) pager := servers.List(i.compute, opts)
ret := make([]string, 0) ret := make([]types.NodeName, 0)
err := pager.EachPage(func(page pagination.Page) (bool, error) { err := pager.EachPage(func(page pagination.Page) (bool, error) {
sList, err := servers.ExtractServers(page) sList, err := servers.ExtractServers(page)
if err != nil { if err != nil {
return false, err return false, err
} }
for _, server := range sList { for i := range sList {
ret = append(ret, server.Name) ret = append(ret, mapServerToNodeName(&sList[i]))
} }
return true, nil return true, nil
}) })
...@@ -112,15 +113,15 @@ func (i *Instances) List(name_filter string) ([]string, error) { ...@@ -112,15 +113,15 @@ func (i *Instances) List(name_filter string) ([]string, error) {
} }
// Implementation of Instances.CurrentNodeName // Implementation of Instances.CurrentNodeName
func (i *Instances) CurrentNodeName(hostname string) (string, error) { func (i *Instances) CurrentNodeName(hostname string) (types.NodeName, error) {
return hostname, nil return types.NodeName(hostname), 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")
} }
func (i *Instances) NodeAddresses(name string) ([]api.NodeAddress, error) { func (i *Instances) NodeAddresses(name types.NodeName) ([]api.NodeAddress, error) {
glog.V(4).Infof("NodeAddresses(%v) called", name) glog.V(4).Infof("NodeAddresses(%v) called", name)
addrs, err := getAddressesByName(i.compute, name) addrs, err := getAddressesByName(i.compute, name)
...@@ -133,7 +134,7 @@ func (i *Instances) NodeAddresses(name string) ([]api.NodeAddress, error) { ...@@ -133,7 +134,7 @@ func (i *Instances) NodeAddresses(name string) ([]api.NodeAddress, error) {
} }
// ExternalID returns the cloud provider ID of the specified instance (deprecated). // ExternalID returns the cloud provider ID of the specified instance (deprecated).
func (i *Instances) ExternalID(name string) (string, error) { func (i *Instances) ExternalID(name types.NodeName) (string, error) {
srv, err := getServerByName(i.compute, name) srv, err := getServerByName(i.compute, name)
if err != nil { if err != nil {
if err == ErrNotFound { if err == ErrNotFound {
...@@ -150,7 +151,7 @@ func (os *OpenStack) InstanceID() (string, error) { ...@@ -150,7 +151,7 @@ func (os *OpenStack) InstanceID() (string, error) {
} }
// InstanceID returns the cloud provider ID of the specified instance. // InstanceID returns the cloud provider ID of the specified instance.
func (i *Instances) InstanceID(name string) (string, error) { func (i *Instances) InstanceID(name types.NodeName) (string, error) {
srv, err := getServerByName(i.compute, name) srv, err := getServerByName(i.compute, name)
if err != nil { if err != nil {
return "", err return "", err
...@@ -161,6 +162,6 @@ func (i *Instances) InstanceID(name string) (string, error) { ...@@ -161,6 +162,6 @@ func (i *Instances) InstanceID(name string) (string, error) {
} }
// InstanceType returns the type of the specified instance. // InstanceType returns the type of the specified instance.
func (i *Instances) InstanceType(name string) (string, error) { func (i *Instances) InstanceType(name types.NodeName) (string, error) {
return "", nil return "", nil
} }
...@@ -39,6 +39,7 @@ import ( ...@@ -39,6 +39,7 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/service" "k8s.io/kubernetes/pkg/api/service"
"k8s.io/kubernetes/pkg/cloudprovider" "k8s.io/kubernetes/pkg/cloudprovider"
"k8s.io/kubernetes/pkg/types"
) )
// Note: when creating a new Loadbalancer (VM), it can take some time before it is ready for use, // Note: when creating a new Loadbalancer (VM), it can take some time before it is ready for use,
...@@ -303,8 +304,8 @@ func (lbaas *LbaasV2) GetLoadBalancer(clusterName string, service *api.Service) ...@@ -303,8 +304,8 @@ func (lbaas *LbaasV2) GetLoadBalancer(clusterName string, service *api.Service)
// a list of regions (from config) and query/create loadbalancers in // a list of regions (from config) and query/create loadbalancers in
// each region. // each region.
func (lbaas *LbaasV2) EnsureLoadBalancer(clusterName string, apiService *api.Service, hosts []string) (*api.LoadBalancerStatus, error) { func (lbaas *LbaasV2) EnsureLoadBalancer(clusterName string, apiService *api.Service, nodeNames []string) (*api.LoadBalancerStatus, error) {
glog.V(4).Infof("EnsureLoadBalancer(%v, %v, %v, %v, %v, %v, %v)", clusterName, apiService.Namespace, apiService.Name, apiService.Spec.LoadBalancerIP, apiService.Spec.Ports, hosts, apiService.Annotations) glog.V(4).Infof("EnsureLoadBalancer(%v, %v, %v, %v, %v, %v, %v)", clusterName, apiService.Namespace, apiService.Name, apiService.Spec.LoadBalancerIP, apiService.Spec.Ports, nodeNames, apiService.Annotations)
ports := apiService.Spec.Ports ports := apiService.Spec.Ports
if len(ports) == 0 { if len(ports) == 0 {
...@@ -410,8 +411,8 @@ func (lbaas *LbaasV2) EnsureLoadBalancer(clusterName string, apiService *api.Ser ...@@ -410,8 +411,8 @@ func (lbaas *LbaasV2) EnsureLoadBalancer(clusterName string, apiService *api.Ser
waitLoadbalancerActiveProvisioningStatus(lbaas.network, loadbalancer.ID) waitLoadbalancerActiveProvisioningStatus(lbaas.network, loadbalancer.ID)
for _, host := range hosts { for _, nodeName := range nodeNames {
addr, err := getAddressByName(lbaas.compute, host) addr, err := getAddressByName(lbaas.compute, types.NodeName(nodeName))
if err != nil { if err != nil {
// cleanup what was created so far // cleanup what was created so far
_ = lbaas.EnsureLoadBalancerDeleted(clusterName, apiService) _ = lbaas.EnsureLoadBalancerDeleted(clusterName, apiService)
...@@ -478,9 +479,9 @@ func (lbaas *LbaasV2) EnsureLoadBalancer(clusterName string, apiService *api.Ser ...@@ -478,9 +479,9 @@ func (lbaas *LbaasV2) EnsureLoadBalancer(clusterName string, apiService *api.Ser
return status, nil return status, nil
} }
func (lbaas *LbaasV2) UpdateLoadBalancer(clusterName string, service *api.Service, hosts []string) error { func (lbaas *LbaasV2) UpdateLoadBalancer(clusterName string, service *api.Service, nodeNames []string) error {
loadBalancerName := cloudprovider.GetLoadBalancerName(service) loadBalancerName := cloudprovider.GetLoadBalancerName(service)
glog.V(4).Infof("UpdateLoadBalancer(%v, %v, %v)", clusterName, loadBalancerName, hosts) glog.V(4).Infof("UpdateLoadBalancer(%v, %v, %v)", clusterName, loadBalancerName, nodeNames)
ports := service.Spec.Ports ports := service.Spec.Ports
if len(ports) == 0 { if len(ports) == 0 {
...@@ -536,8 +537,8 @@ func (lbaas *LbaasV2) UpdateLoadBalancer(clusterName string, service *api.Servic ...@@ -536,8 +537,8 @@ func (lbaas *LbaasV2) UpdateLoadBalancer(clusterName string, service *api.Servic
// Compose Set of member (addresses) that _should_ exist // Compose Set of member (addresses) that _should_ exist
addrs := map[string]empty{} addrs := map[string]empty{}
for _, host := range hosts { for _, nodeName := range nodeNames {
addr, err := getAddressByName(lbaas.compute, host) addr, err := getAddressByName(lbaas.compute, types.NodeName(nodeName))
if err != nil { if err != nil {
return err return err
} }
...@@ -765,8 +766,8 @@ func (lb *LbaasV1) GetLoadBalancer(clusterName string, service *api.Service) (*a ...@@ -765,8 +766,8 @@ func (lb *LbaasV1) GetLoadBalancer(clusterName string, service *api.Service) (*a
// a list of regions (from config) and query/create loadbalancers in // a list of regions (from config) and query/create loadbalancers in
// each region. // each region.
func (lb *LbaasV1) EnsureLoadBalancer(clusterName string, apiService *api.Service, hosts []string) (*api.LoadBalancerStatus, error) { func (lb *LbaasV1) EnsureLoadBalancer(clusterName string, apiService *api.Service, nodeNames []string) (*api.LoadBalancerStatus, error) {
glog.V(4).Infof("EnsureLoadBalancer(%v, %v, %v, %v, %v, %v, %v)", clusterName, apiService.Namespace, apiService.Name, apiService.Spec.LoadBalancerIP, apiService.Spec.Ports, hosts, apiService.Annotations) glog.V(4).Infof("EnsureLoadBalancer(%v, %v, %v, %v, %v, %v, %v)", clusterName, apiService.Namespace, apiService.Name, apiService.Spec.LoadBalancerIP, apiService.Spec.Ports, nodeNames, apiService.Annotations)
ports := apiService.Spec.Ports ports := apiService.Spec.Ports
if len(ports) > 1 { if len(ports) > 1 {
...@@ -831,8 +832,8 @@ func (lb *LbaasV1) EnsureLoadBalancer(clusterName string, apiService *api.Servic ...@@ -831,8 +832,8 @@ func (lb *LbaasV1) EnsureLoadBalancer(clusterName string, apiService *api.Servic
return nil, err return nil, err
} }
for _, host := range hosts { for _, nodeName := range nodeNames {
addr, err := getAddressByName(lb.compute, host) addr, err := getAddressByName(lb.compute, types.NodeName(nodeName))
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -914,9 +915,9 @@ func (lb *LbaasV1) EnsureLoadBalancer(clusterName string, apiService *api.Servic ...@@ -914,9 +915,9 @@ func (lb *LbaasV1) EnsureLoadBalancer(clusterName string, apiService *api.Servic
} }
func (lb *LbaasV1) UpdateLoadBalancer(clusterName string, service *api.Service, hosts []string) error { func (lb *LbaasV1) UpdateLoadBalancer(clusterName string, service *api.Service, nodeNames []string) error {
loadBalancerName := cloudprovider.GetLoadBalancerName(service) loadBalancerName := cloudprovider.GetLoadBalancerName(service)
glog.V(4).Infof("UpdateLoadBalancer(%v, %v, %v)", clusterName, loadBalancerName, hosts) glog.V(4).Infof("UpdateLoadBalancer(%v, %v, %v)", clusterName, loadBalancerName, nodeNames)
vip, err := getVipByName(lb.network, loadBalancerName) vip, err := getVipByName(lb.network, loadBalancerName)
if err != nil { if err != nil {
...@@ -925,8 +926,8 @@ func (lb *LbaasV1) UpdateLoadBalancer(clusterName string, service *api.Service, ...@@ -925,8 +926,8 @@ func (lb *LbaasV1) UpdateLoadBalancer(clusterName string, service *api.Service,
// Set of member (addresses) that _should_ exist // Set of member (addresses) that _should_ exist
addrs := map[string]bool{} addrs := map[string]bool{}
for _, host := range hosts { for _, nodeName := range nodeNames {
addr, err := getAddressByName(lb.compute, host) addr, err := getAddressByName(lb.compute, types.NodeName(nodeName))
if err != nil { if err != nil {
return err return err
} }
......
...@@ -33,6 +33,7 @@ import ( ...@@ -33,6 +33,7 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/cloudprovider" "k8s.io/kubernetes/pkg/cloudprovider"
"k8s.io/kubernetes/pkg/types"
) )
const ProviderName = "ovirt" const ProviderName = "ovirt"
...@@ -149,8 +150,9 @@ func (v *OVirtCloud) Routes() (cloudprovider.Routes, bool) { ...@@ -149,8 +150,9 @@ func (v *OVirtCloud) Routes() (cloudprovider.Routes, bool) {
return nil, false return nil, false
} }
// NodeAddresses returns the NodeAddresses of a particular machine instance // NodeAddresses returns the NodeAddresses of the instance with the specified nodeName.
func (v *OVirtCloud) NodeAddresses(name string) ([]api.NodeAddress, error) { func (v *OVirtCloud) NodeAddresses(nodeName types.NodeName) ([]api.NodeAddress, error) {
name := mapNodeNameToInstanceName(nodeName)
instance, err := v.fetchInstance(name) instance, err := v.fetchInstance(name)
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -174,8 +176,15 @@ func (v *OVirtCloud) NodeAddresses(name string) ([]api.NodeAddress, error) { ...@@ -174,8 +176,15 @@ func (v *OVirtCloud) NodeAddresses(name string) ([]api.NodeAddress, error) {
return []api.NodeAddress{{Type: api.NodeLegacyHostIP, Address: address.String()}}, nil return []api.NodeAddress{{Type: api.NodeLegacyHostIP, Address: address.String()}}, nil
} }
// ExternalID returns the cloud provider ID of the specified instance (deprecated). // mapNodeNameToInstanceName maps from a k8s NodeName to an ovirt instance name (the hostname)
func (v *OVirtCloud) ExternalID(name string) (string, error) { // This is a simple string cast
func mapNodeNameToInstanceName(nodeName types.NodeName) string {
return string(nodeName)
}
// ExternalID returns the cloud provider ID of the specified node with the specified NodeName (deprecated).
func (v *OVirtCloud) ExternalID(nodeName types.NodeName) (string, error) {
name := mapNodeNameToInstanceName(nodeName)
instance, err := v.fetchInstance(name) instance, err := v.fetchInstance(name)
if err != nil { if err != nil {
return "", err return "", err
...@@ -183,8 +192,9 @@ func (v *OVirtCloud) ExternalID(name string) (string, error) { ...@@ -183,8 +192,9 @@ func (v *OVirtCloud) ExternalID(name string) (string, error) {
return instance.UUID, nil return instance.UUID, nil
} }
// InstanceID returns the cloud provider ID of the specified instance. // InstanceID returns the cloud provider ID of the node with the specified NodeName.
func (v *OVirtCloud) InstanceID(name string) (string, error) { func (v *OVirtCloud) InstanceID(nodeName types.NodeName) (string, error) {
name := mapNodeNameToInstanceName(nodeName)
instance, err := v.fetchInstance(name) instance, err := v.fetchInstance(name)
if err != nil { if err != nil {
return "", err return "", err
...@@ -195,7 +205,7 @@ func (v *OVirtCloud) InstanceID(name string) (string, error) { ...@@ -195,7 +205,7 @@ func (v *OVirtCloud) InstanceID(name string) (string, error) {
} }
// InstanceType returns the type of the specified instance. // InstanceType returns the type of the specified instance.
func (v *OVirtCloud) InstanceType(name string) (string, error) { func (v *OVirtCloud) InstanceType(name types.NodeName) (string, error) {
return "", nil return "", nil
} }
...@@ -274,17 +284,21 @@ func (m *OVirtInstanceMap) ListSortedNames() []string { ...@@ -274,17 +284,21 @@ func (m *OVirtInstanceMap) ListSortedNames() []string {
} }
// List enumerates the set of minions instances known by the cloud provider // List enumerates the set of minions instances known by the cloud provider
func (v *OVirtCloud) List(filter string) ([]string, error) { func (v *OVirtCloud) List(filter string) ([]types.NodeName, error) {
instances, err := v.fetchAllInstances() instances, err := v.fetchAllInstances()
if err != nil { if err != nil {
return nil, err return nil, err
} }
return instances.ListSortedNames(), nil var nodeNames []types.NodeName
for _, s := range instances.ListSortedNames() {
nodeNames = append(nodeNames, types.NodeName(s))
}
return nodeNames, nil
} }
// Implementation of Instances.CurrentNodeName // Implementation of Instances.CurrentNodeName
func (v *OVirtCloud) CurrentNodeName(hostname string) (string, error) { func (v *OVirtCloud) CurrentNodeName(hostname string) (types.NodeName, error) {
return hostname, nil return types.NodeName(hostname), nil
} }
func (v *OVirtCloud) AddSSHKeyToAllInstances(user string, keyData []byte) error { func (v *OVirtCloud) AddSSHKeyToAllInstances(user string, keyData []byte) error {
......
...@@ -42,6 +42,7 @@ import ( ...@@ -42,6 +42,7 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/cloudprovider" "k8s.io/kubernetes/pkg/cloudprovider"
"k8s.io/kubernetes/pkg/types"
) )
const ProviderName = "rackspace" const ProviderName = "rackspace"
...@@ -230,7 +231,7 @@ func (os *Rackspace) Instances() (cloudprovider.Instances, bool) { ...@@ -230,7 +231,7 @@ func (os *Rackspace) Instances() (cloudprovider.Instances, bool) {
return &Instances{compute}, true return &Instances{compute}, true
} }
func (i *Instances) List(name_filter string) ([]string, error) { func (i *Instances) List(name_filter string) ([]types.NodeName, error) {
glog.V(2).Infof("rackspace List(%v) called", name_filter) glog.V(2).Infof("rackspace List(%v) called", name_filter)
opts := osservers.ListOpts{ opts := osservers.ListOpts{
...@@ -239,14 +240,14 @@ func (i *Instances) List(name_filter string) ([]string, error) { ...@@ -239,14 +240,14 @@ func (i *Instances) List(name_filter string) ([]string, error) {
} }
pager := servers.List(i.compute, opts) pager := servers.List(i.compute, opts)
ret := make([]string, 0) ret := make([]types.NodeName, 0)
err := pager.EachPage(func(page pagination.Page) (bool, error) { err := pager.EachPage(func(page pagination.Page) (bool, error) {
sList, err := servers.ExtractServers(page) sList, err := servers.ExtractServers(page)
if err != nil { if err != nil {
return false, err return false, err
} }
for _, server := range sList { for i := range sList {
ret = append(ret, server.Name) ret = append(ret, mapServerToNodeName(&sList[i]))
} }
return true, nil return true, nil
}) })
...@@ -396,23 +397,35 @@ func getAddressByName(api *gophercloud.ServiceClient, name string) (string, erro ...@@ -396,23 +397,35 @@ func getAddressByName(api *gophercloud.ServiceClient, name string) (string, erro
return getAddressByServer(srv) return getAddressByServer(srv)
} }
func (i *Instances) NodeAddresses(name string) ([]api.NodeAddress, error) { func (i *Instances) NodeAddresses(nodeName types.NodeName) ([]api.NodeAddress, error) {
glog.V(2).Infof("NodeAddresses(%v) called", name) glog.V(2).Infof("NodeAddresses(%v) called", nodeName)
serverName := mapNodeNameToServerName(nodeName)
ip, err := probeNodeAddress(i.compute, name) ip, err := probeNodeAddress(i.compute, serverName)
if err != nil { if err != nil {
return nil, err return nil, err
} }
glog.V(2).Infof("NodeAddresses(%v) => %v", name, ip) glog.V(2).Infof("NodeAddresses(%v) => %v", serverName, ip)
// net.ParseIP().String() is to maintain compatibility with the old code // net.ParseIP().String() is to maintain compatibility with the old code
return []api.NodeAddress{{Type: api.NodeLegacyHostIP, Address: net.ParseIP(ip).String()}}, nil return []api.NodeAddress{{Type: api.NodeLegacyHostIP, Address: net.ParseIP(ip).String()}}, nil
} }
// ExternalID returns the cloud provider ID of the specified instance (deprecated). // mapNodeNameToServerName maps from a k8s NodeName to a rackspace Server Name
func (i *Instances) ExternalID(name string) (string, error) { // This is a simple string cast.
return probeInstanceID(i.compute, name) func mapNodeNameToServerName(nodeName types.NodeName) string {
return string(nodeName)
}
// mapServerToNodeName maps a rackspace Server to an k8s NodeName
func mapServerToNodeName(s *osservers.Server) types.NodeName {
return types.NodeName(s.Name)
}
// ExternalID returns the cloud provider ID of the node with the specified Name (deprecated).
func (i *Instances) ExternalID(nodeName types.NodeName) (string, error) {
serverName := mapNodeNameToServerName(nodeName)
return probeInstanceID(i.compute, serverName)
} }
// InstanceID returns the cloud provider ID of the kubelet's instance. // InstanceID returns the cloud provider ID of the kubelet's instance.
...@@ -420,13 +433,14 @@ func (rs *Rackspace) InstanceID() (string, error) { ...@@ -420,13 +433,14 @@ func (rs *Rackspace) InstanceID() (string, error) {
return readInstanceID() return readInstanceID()
} }
// InstanceID returns the cloud provider ID of the specified instance. // InstanceID returns the cloud provider ID of the node with the specified Name.
func (i *Instances) InstanceID(name string) (string, error) { func (i *Instances) InstanceID(nodeName types.NodeName) (string, error) {
return probeInstanceID(i.compute, name) serverName := mapNodeNameToServerName(nodeName)
return probeInstanceID(i.compute, serverName)
} }
// InstanceType returns the type of the specified instance. // InstanceType returns the type of the specified instance.
func (i *Instances) InstanceType(name string) (string, error) { func (i *Instances) InstanceType(name types.NodeName) (string, error) {
return "", nil return "", nil
} }
...@@ -435,10 +449,10 @@ func (i *Instances) AddSSHKeyToAllInstances(user string, keyData []byte) error { ...@@ -435,10 +449,10 @@ func (i *Instances) AddSSHKeyToAllInstances(user string, keyData []byte) error {
} }
// Implementation of Instances.CurrentNodeName // Implementation of Instances.CurrentNodeName
func (i *Instances) CurrentNodeName(hostname string) (string, error) { func (i *Instances) CurrentNodeName(hostname string) (types.NodeName, error) {
// Beware when changing this, nodename == hostname assumption is crucial to // Beware when changing this, nodename == hostname assumption is crucial to
// apiserver => kubelet communication. // apiserver => kubelet communication.
return hostname, nil return types.NodeName(hostname), nil
} }
func (os *Rackspace) Clusters() (cloudprovider.Clusters, bool) { func (os *Rackspace) Clusters() (cloudprovider.Clusters, bool) {
......
...@@ -25,6 +25,7 @@ import ( ...@@ -25,6 +25,7 @@ import (
"golang.org/x/net/context" "golang.org/x/net/context"
"k8s.io/kubernetes/pkg/cloudprovider" "k8s.io/kubernetes/pkg/cloudprovider"
"k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/util/rand" "k8s.io/kubernetes/pkg/util/rand"
) )
...@@ -186,7 +187,7 @@ func TestInstances(t *testing.T) { ...@@ -186,7 +187,7 @@ func TestInstances(t *testing.T) {
} }
t.Logf("Found ExternalID(%s) = %s\n", srvs[0], externalId) t.Logf("Found ExternalID(%s) = %s\n", srvs[0], externalId)
nonExistingVM := rand.String(15) nonExistingVM := types.NodeName(rand.String(15))
externalId, err = i.ExternalID(nonExistingVM) externalId, err = i.ExternalID(nonExistingVM)
if err == cloudprovider.InstanceNotFound { if err == cloudprovider.InstanceNotFound {
t.Logf("VM %s was not found as expected\n", nonExistingVM) t.Logf("VM %s was not found as expected\n", nonExistingVM)
......
...@@ -244,7 +244,7 @@ func nodeRunningOutdatedKubelet(node *api.Node) bool { ...@@ -244,7 +244,7 @@ func nodeRunningOutdatedKubelet(node *api.Node) bool {
return false return false
} }
func nodeExistsInCloudProvider(cloud cloudprovider.Interface, nodeName string) (bool, error) { func nodeExistsInCloudProvider(cloud cloudprovider.Interface, nodeName types.NodeName) (bool, error) {
instances, ok := cloud.Instances() instances, ok := cloud.Instances()
if !ok { if !ok {
return false, fmt.Errorf("%v", ErrCloudInstance) return false, fmt.Errorf("%v", ErrCloudInstance)
......
...@@ -37,6 +37,7 @@ import ( ...@@ -37,6 +37,7 @@ import (
"k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/util/flowcontrol" "k8s.io/kubernetes/pkg/util/flowcontrol"
"k8s.io/kubernetes/pkg/util/metrics" "k8s.io/kubernetes/pkg/util/metrics"
utilnode "k8s.io/kubernetes/pkg/util/node" utilnode "k8s.io/kubernetes/pkg/util/node"
...@@ -147,7 +148,7 @@ type NodeController struct { ...@@ -147,7 +148,7 @@ type NodeController struct {
cidrAllocator CIDRAllocator cidrAllocator CIDRAllocator
forcefullyDeletePod func(*api.Pod) error forcefullyDeletePod func(*api.Pod) error
nodeExistsInCloudProvider func(string) (bool, error) nodeExistsInCloudProvider func(types.NodeName) (bool, error)
computeZoneStateFunc func(nodeConditions []*api.NodeCondition) (int, zoneState) computeZoneStateFunc func(nodeConditions []*api.NodeCondition) (int, zoneState)
enterPartialDisruptionFunc func(nodeNum int) float32 enterPartialDisruptionFunc func(nodeNum int) float32
enterFullDisruptionFunc func(nodeNum int) float32 enterFullDisruptionFunc func(nodeNum int) float32
...@@ -229,7 +230,7 @@ func NewNodeController( ...@@ -229,7 +230,7 @@ func NewNodeController(
serviceCIDR: serviceCIDR, serviceCIDR: serviceCIDR,
allocateNodeCIDRs: allocateNodeCIDRs, allocateNodeCIDRs: allocateNodeCIDRs,
forcefullyDeletePod: func(p *api.Pod) error { return forcefullyDeletePod(kubeClient, p) }, forcefullyDeletePod: func(p *api.Pod) error { return forcefullyDeletePod(kubeClient, p) },
nodeExistsInCloudProvider: func(nodeName string) (bool, error) { return nodeExistsInCloudProvider(cloud, nodeName) }, nodeExistsInCloudProvider: func(nodeName types.NodeName) (bool, error) { return nodeExistsInCloudProvider(cloud, nodeName) },
evictionLimiterQPS: evictionLimiterQPS, evictionLimiterQPS: evictionLimiterQPS,
secondaryEvictionLimiterQPS: secondaryEvictionLimiterQPS, secondaryEvictionLimiterQPS: secondaryEvictionLimiterQPS,
largeClusterThreshold: largeClusterThreshold, largeClusterThreshold: largeClusterThreshold,
...@@ -576,7 +577,7 @@ func (nc *NodeController) monitorNodeStatus() error { ...@@ -576,7 +577,7 @@ func (nc *NodeController) monitorNodeStatus() error {
// Check with the cloud provider to see if the node still exists. If it // Check with the cloud provider to see if the node still exists. If it
// doesn't, delete the node immediately. // doesn't, delete the node immediately.
if currentReadyCondition.Status != api.ConditionTrue && nc.cloud != nil { if currentReadyCondition.Status != api.ConditionTrue && nc.cloud != nil {
exists, err := nc.nodeExistsInCloudProvider(node.Name) exists, err := nc.nodeExistsInCloudProvider(types.NodeName(node.Name))
if err != nil { if err != nil {
glog.Errorf("Error determining if node %v exists in cloud: %v", node.Name, err) glog.Errorf("Error determining if node %v exists in cloud: %v", node.Name, err)
continue continue
......
...@@ -27,6 +27,7 @@ import ( ...@@ -27,6 +27,7 @@ import (
"k8s.io/kubernetes/pkg/client/cache" "k8s.io/kubernetes/pkg/client/cache"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake" "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
fakecloud "k8s.io/kubernetes/pkg/cloudprovider/providers/fake" fakecloud "k8s.io/kubernetes/pkg/cloudprovider/providers/fake"
"k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/util/diff" "k8s.io/kubernetes/pkg/util/diff"
"k8s.io/kubernetes/pkg/util/wait" "k8s.io/kubernetes/pkg/util/wait"
) )
...@@ -1078,7 +1079,7 @@ func TestCloudProviderNoRateLimit(t *testing.T) { ...@@ -1078,7 +1079,7 @@ func TestCloudProviderNoRateLimit(t *testing.T) {
testNodeMonitorPeriod, nil, nil, 0, false) testNodeMonitorPeriod, nil, nil, 0, false)
nodeController.cloud = &fakecloud.FakeCloud{} nodeController.cloud = &fakecloud.FakeCloud{}
nodeController.now = func() unversioned.Time { return unversioned.Date(2016, 1, 1, 12, 0, 0, 0, time.UTC) } nodeController.now = func() unversioned.Time { return unversioned.Date(2016, 1, 1, 12, 0, 0, 0, time.UTC) }
nodeController.nodeExistsInCloudProvider = func(nodeName string) (bool, error) { nodeController.nodeExistsInCloudProvider = func(nodeName types.NodeName) (bool, error) {
return false, nil return false, nil
} }
// monitorNodeStatus should allow this node to be immediately deleted // monitorNodeStatus should allow this node to be immediately deleted
......
...@@ -31,6 +31,7 @@ import ( ...@@ -31,6 +31,7 @@ import (
"k8s.io/kubernetes/pkg/cloudprovider" "k8s.io/kubernetes/pkg/cloudprovider"
"k8s.io/kubernetes/pkg/controller" "k8s.io/kubernetes/pkg/controller"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/util/metrics" "k8s.io/kubernetes/pkg/util/metrics"
nodeutil "k8s.io/kubernetes/pkg/util/node" nodeutil "k8s.io/kubernetes/pkg/util/node"
"k8s.io/kubernetes/pkg/util/wait" "k8s.io/kubernetes/pkg/util/wait"
...@@ -117,11 +118,11 @@ func (rc *RouteController) reconcileNodeRoutes() error { ...@@ -117,11 +118,11 @@ func (rc *RouteController) reconcileNodeRoutes() error {
func (rc *RouteController) reconcile(nodes []api.Node, routes []*cloudprovider.Route) error { func (rc *RouteController) reconcile(nodes []api.Node, routes []*cloudprovider.Route) error {
// nodeCIDRs maps nodeName->nodeCIDR // nodeCIDRs maps nodeName->nodeCIDR
nodeCIDRs := make(map[string]string) nodeCIDRs := make(map[types.NodeName]string)
// routeMap maps routeTargetInstance->route // routeMap maps routeTargetNode->route
routeMap := make(map[string]*cloudprovider.Route) routeMap := make(map[types.NodeName]*cloudprovider.Route)
for _, route := range routes { for _, route := range routes {
routeMap[route.TargetInstance] = route routeMap[route.TargetNode] = route
} }
wg := sync.WaitGroup{} wg := sync.WaitGroup{}
...@@ -132,17 +133,18 @@ func (rc *RouteController) reconcile(nodes []api.Node, routes []*cloudprovider.R ...@@ -132,17 +133,18 @@ func (rc *RouteController) reconcile(nodes []api.Node, routes []*cloudprovider.R
if node.Spec.PodCIDR == "" { if node.Spec.PodCIDR == "" {
continue continue
} }
nodeName := types.NodeName(node.Name)
// Check if we have a route for this node w/ the correct CIDR. // Check if we have a route for this node w/ the correct CIDR.
r := routeMap[node.Name] r := routeMap[nodeName]
if r == nil || r.DestinationCIDR != node.Spec.PodCIDR { if r == nil || r.DestinationCIDR != node.Spec.PodCIDR {
// If not, create the route. // If not, create the route.
route := &cloudprovider.Route{ route := &cloudprovider.Route{
TargetInstance: node.Name, TargetNode: nodeName,
DestinationCIDR: node.Spec.PodCIDR, DestinationCIDR: node.Spec.PodCIDR,
} }
nameHint := string(node.UID) nameHint := string(node.UID)
wg.Add(1) wg.Add(1)
go func(nodeName string, nameHint string, route *cloudprovider.Route) { go func(nodeName types.NodeName, nameHint string, route *cloudprovider.Route) {
defer wg.Done() defer wg.Done()
for i := 0; i < maxRetries; i++ { for i := 0; i < maxRetries; i++ {
startTime := time.Now() startTime := time.Now()
...@@ -161,20 +163,20 @@ func (rc *RouteController) reconcile(nodes []api.Node, routes []*cloudprovider.R ...@@ -161,20 +163,20 @@ func (rc *RouteController) reconcile(nodes []api.Node, routes []*cloudprovider.R
return return
} }
} }
}(node.Name, nameHint, route) }(nodeName, nameHint, route)
} else { } else {
// Update condition only if it doesn't reflect the current state. // Update condition only if it doesn't reflect the current state.
_, condition := api.GetNodeCondition(&node.Status, api.NodeNetworkUnavailable) _, condition := api.GetNodeCondition(&node.Status, api.NodeNetworkUnavailable)
if condition == nil || condition.Status != api.ConditionFalse { if condition == nil || condition.Status != api.ConditionFalse {
rc.updateNetworkingCondition(node.Name, true) rc.updateNetworkingCondition(types.NodeName(node.Name), true)
} }
} }
nodeCIDRs[node.Name] = node.Spec.PodCIDR nodeCIDRs[nodeName] = node.Spec.PodCIDR
} }
for _, route := range routes { for _, route := range routes {
if rc.isResponsibleForRoute(route) { if rc.isResponsibleForRoute(route) {
// Check if this route applies to a node we know about & has correct CIDR. // Check if this route applies to a node we know about & has correct CIDR.
if nodeCIDRs[route.TargetInstance] != route.DestinationCIDR { if nodeCIDRs[route.TargetNode] != route.DestinationCIDR {
wg.Add(1) wg.Add(1)
// Delete the route. // Delete the route.
go func(route *cloudprovider.Route, startTime time.Time) { go func(route *cloudprovider.Route, startTime time.Time) {
...@@ -194,7 +196,7 @@ func (rc *RouteController) reconcile(nodes []api.Node, routes []*cloudprovider.R ...@@ -194,7 +196,7 @@ func (rc *RouteController) reconcile(nodes []api.Node, routes []*cloudprovider.R
return nil return nil
} }
func (rc *RouteController) updateNetworkingCondition(nodeName string, routeCreated bool) error { func (rc *RouteController) updateNetworkingCondition(nodeName types.NodeName, routeCreated bool) error {
var err error var err error
for i := 0; i < updateNodeStatusMaxRetries; i++ { for i := 0; i < updateNodeStatusMaxRetries; i++ {
// Patch could also fail, even though the chance is very slim. So we still do // Patch could also fail, even though the chance is very slim. So we still do
......
...@@ -26,6 +26,7 @@ import ( ...@@ -26,6 +26,7 @@ import (
"k8s.io/kubernetes/pkg/client/testing/core" "k8s.io/kubernetes/pkg/client/testing/core"
"k8s.io/kubernetes/pkg/cloudprovider" "k8s.io/kubernetes/pkg/cloudprovider"
fakecloud "k8s.io/kubernetes/pkg/cloudprovider/providers/fake" fakecloud "k8s.io/kubernetes/pkg/cloudprovider/providers/fake"
"k8s.io/kubernetes/pkg/types"
) )
func TestIsResponsibleForRoute(t *testing.T) { func TestIsResponsibleForRoute(t *testing.T) {
...@@ -58,7 +59,7 @@ func TestIsResponsibleForRoute(t *testing.T) { ...@@ -58,7 +59,7 @@ func TestIsResponsibleForRoute(t *testing.T) {
rc := New(nil, nil, myClusterName, cidr) rc := New(nil, nil, myClusterName, cidr)
route := &cloudprovider.Route{ route := &cloudprovider.Route{
Name: testCase.routeName, Name: testCase.routeName,
TargetInstance: "doesnt-matter-for-this-test", TargetNode: types.NodeName("doesnt-matter-for-this-test"),
DestinationCIDR: testCase.routeCIDR, DestinationCIDR: testCase.routeCIDR,
} }
if resp := rc.isResponsibleForRoute(route); resp != testCase.expectedResponsible { if resp := rc.isResponsibleForRoute(route); resp != testCase.expectedResponsible {
......
...@@ -237,7 +237,7 @@ func (adc *attachDetachController) nodeAdd(obj interface{}) { ...@@ -237,7 +237,7 @@ func (adc *attachDetachController) nodeAdd(obj interface{}) {
return return
} }
nodeName := node.Name nodeName := types.NodeName(node.Name)
if _, exists := node.Annotations[volumehelper.ControllerManagedAttachAnnotation]; exists { if _, exists := node.Annotations[volumehelper.ControllerManagedAttachAnnotation]; exists {
// Node specifies annotation indicating it should be managed by attach // Node specifies annotation indicating it should be managed by attach
// detach controller. Add it to desired state of world. // detach controller. Add it to desired state of world.
...@@ -258,7 +258,7 @@ func (adc *attachDetachController) nodeDelete(obj interface{}) { ...@@ -258,7 +258,7 @@ func (adc *attachDetachController) nodeDelete(obj interface{}) {
return return
} }
nodeName := node.Name nodeName := types.NodeName(node.Name)
if err := adc.desiredStateOfWorld.DeleteNode(nodeName); err != nil { if err := adc.desiredStateOfWorld.DeleteNode(nodeName); err != nil {
glog.V(10).Infof("%v", err) glog.V(10).Infof("%v", err)
} }
...@@ -278,7 +278,9 @@ func (adc *attachDetachController) processPodVolumes( ...@@ -278,7 +278,9 @@ func (adc *attachDetachController) processPodVolumes(
return return
} }
if !adc.desiredStateOfWorld.NodeExists(pod.Spec.NodeName) { nodeName := types.NodeName(pod.Spec.NodeName)
if !adc.desiredStateOfWorld.NodeExists(nodeName) {
// If the node the pod is scheduled to does not exist in the desired // If the node the pod is scheduled to does not exist in the desired
// state of the world data structure, that indicates the node is not // state of the world data structure, that indicates the node is not
// yet managed by the controller. Therefore, ignore the pod. // yet managed by the controller. Therefore, ignore the pod.
...@@ -288,7 +290,7 @@ func (adc *attachDetachController) processPodVolumes( ...@@ -288,7 +290,7 @@ func (adc *attachDetachController) processPodVolumes(
"Skipping processing of pod %q/%q: it is scheduled to node %q which is not managed by the controller.", "Skipping processing of pod %q/%q: it is scheduled to node %q which is not managed by the controller.",
pod.Namespace, pod.Namespace,
pod.Name, pod.Name,
pod.Spec.NodeName) nodeName)
return return
} }
...@@ -321,7 +323,7 @@ func (adc *attachDetachController) processPodVolumes( ...@@ -321,7 +323,7 @@ func (adc *attachDetachController) processPodVolumes(
if addVolumes { if addVolumes {
// Add volume to desired state of world // Add volume to desired state of world
_, err := adc.desiredStateOfWorld.AddPod( _, err := adc.desiredStateOfWorld.AddPod(
uniquePodName, pod, volumeSpec, pod.Spec.NodeName) uniquePodName, pod, volumeSpec, nodeName)
if err != nil { if err != nil {
glog.V(10).Infof( glog.V(10).Infof(
"Failed to add volume %q for pod %q/%q to desiredStateOfWorld. %v", "Failed to add volume %q for pod %q/%q to desiredStateOfWorld. %v",
...@@ -345,7 +347,7 @@ func (adc *attachDetachController) processPodVolumes( ...@@ -345,7 +347,7 @@ func (adc *attachDetachController) processPodVolumes(
continue continue
} }
adc.desiredStateOfWorld.DeletePod( adc.desiredStateOfWorld.DeletePod(
uniquePodName, uniqueVolumeName, pod.Spec.NodeName) uniquePodName, uniqueVolumeName, nodeName)
} }
} }
...@@ -516,7 +518,7 @@ func (adc *attachDetachController) getPVSpecFromCache( ...@@ -516,7 +518,7 @@ func (adc *attachDetachController) getPVSpecFromCache(
// corresponding volume in the actual state of the world to indicate that it is // corresponding volume in the actual state of the world to indicate that it is
// mounted. // mounted.
func (adc *attachDetachController) processVolumesInUse( func (adc *attachDetachController) processVolumesInUse(
nodeName string, volumesInUse []api.UniqueVolumeName) { nodeName types.NodeName, volumesInUse []api.UniqueVolumeName) {
glog.V(4).Infof("processVolumesInUse for node %q", nodeName) glog.V(4).Infof("processVolumesInUse for node %q", nodeName)
for _, attachedVolume := range adc.actualStateOfWorld.GetAttachedVolumesForNode(nodeName) { for _, attachedVolume := range adc.actualStateOfWorld.GetAttachedVolumesForNode(nodeName) {
mounted := false mounted := false
......
...@@ -26,6 +26,7 @@ import ( ...@@ -26,6 +26,7 @@ import (
"sync" "sync"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
k8stypes "k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util/operationexecutor" "k8s.io/kubernetes/pkg/volume/util/operationexecutor"
"k8s.io/kubernetes/pkg/volume/util/types" "k8s.io/kubernetes/pkg/volume/util/types"
...@@ -45,7 +46,7 @@ type DesiredStateOfWorld interface { ...@@ -45,7 +46,7 @@ type DesiredStateOfWorld interface {
// AddNode adds the given node to the list of nodes managed by the attach/ // AddNode adds the given node to the list of nodes managed by the attach/
// detach controller. // detach controller.
// If the node already exists this is a no-op. // If the node already exists this is a no-op.
AddNode(nodeName string) AddNode(nodeName k8stypes.NodeName)
// AddPod adds the given pod to the list of pods that reference the // AddPod adds the given pod to the list of pods that reference the
// specified volume and is scheduled to the specified node. // specified volume and is scheduled to the specified node.
...@@ -57,13 +58,13 @@ type DesiredStateOfWorld interface { ...@@ -57,13 +58,13 @@ type DesiredStateOfWorld interface {
// should be attached to the specified node, the volume is implicitly added. // should be attached to the specified node, the volume is implicitly added.
// If no node with the name nodeName exists in list of nodes managed by the // If no node with the name nodeName exists in list of nodes managed by the
// attach/detach attached controller, an error is returned. // attach/detach attached controller, an error is returned.
AddPod(podName types.UniquePodName, pod *api.Pod, volumeSpec *volume.Spec, nodeName string) (api.UniqueVolumeName, error) AddPod(podName types.UniquePodName, pod *api.Pod, volumeSpec *volume.Spec, nodeName k8stypes.NodeName) (api.UniqueVolumeName, error)
// DeleteNode removes the given node from the list of nodes managed by the // DeleteNode removes the given node from the list of nodes managed by the
// attach/detach controller. // attach/detach controller.
// If the node does not exist this is a no-op. // If the node does not exist this is a no-op.
// If the node exists but has 1 or more child volumes, an error is returned. // If the node exists but has 1 or more child volumes, an error is returned.
DeleteNode(nodeName string) error DeleteNode(nodeName k8stypes.NodeName) error
// DeletePod removes the given pod from the list of pods that reference the // DeletePod removes the given pod from the list of pods that reference the
// specified volume and are scheduled to the specified node. // specified volume and are scheduled to the specified node.
...@@ -75,16 +76,16 @@ type DesiredStateOfWorld interface { ...@@ -75,16 +76,16 @@ type DesiredStateOfWorld interface {
// volumes under the specified node, this is a no-op. // volumes under the specified node, this is a no-op.
// If after deleting the pod, the specified volume contains no other child // If after deleting the pod, the specified volume contains no other child
// pods, the volume is also deleted. // pods, the volume is also deleted.
DeletePod(podName types.UniquePodName, volumeName api.UniqueVolumeName, nodeName string) DeletePod(podName types.UniquePodName, volumeName api.UniqueVolumeName, nodeName k8stypes.NodeName)
// NodeExists returns true if the node with the specified name exists in // NodeExists returns true if the node with the specified name exists in
// the list of nodes managed by the attach/detach controller. // the list of nodes managed by the attach/detach controller.
NodeExists(nodeName string) bool NodeExists(nodeName k8stypes.NodeName) bool
// VolumeExists returns true if the volume with the specified name exists // VolumeExists returns true if the volume with the specified name exists
// in the list of volumes that should be attached to the specified node by // in the list of volumes that should be attached to the specified node by
// the attach detach controller. // the attach detach controller.
VolumeExists(volumeName api.UniqueVolumeName, nodeName string) bool VolumeExists(volumeName api.UniqueVolumeName, nodeName k8stypes.NodeName) bool
// GetVolumesToAttach generates and returns a list of volumes to attach // GetVolumesToAttach generates and returns a list of volumes to attach
// and the nodes they should be attached to based on the current desired // and the nodes they should be attached to based on the current desired
...@@ -111,13 +112,13 @@ type PodToAdd struct { ...@@ -111,13 +112,13 @@ type PodToAdd struct {
VolumeName api.UniqueVolumeName VolumeName api.UniqueVolumeName
// nodeName contains the name of this node. // nodeName contains the name of this node.
NodeName string NodeName k8stypes.NodeName
} }
// NewDesiredStateOfWorld returns a new instance of DesiredStateOfWorld. // NewDesiredStateOfWorld returns a new instance of DesiredStateOfWorld.
func NewDesiredStateOfWorld(volumePluginMgr *volume.VolumePluginMgr) DesiredStateOfWorld { func NewDesiredStateOfWorld(volumePluginMgr *volume.VolumePluginMgr) DesiredStateOfWorld {
return &desiredStateOfWorld{ return &desiredStateOfWorld{
nodesManaged: make(map[string]nodeManaged), nodesManaged: make(map[k8stypes.NodeName]nodeManaged),
volumePluginMgr: volumePluginMgr, volumePluginMgr: volumePluginMgr,
} }
} }
...@@ -126,7 +127,7 @@ type desiredStateOfWorld struct { ...@@ -126,7 +127,7 @@ type desiredStateOfWorld struct {
// nodesManaged is a map containing the set of nodes managed by the attach/ // nodesManaged is a map containing the set of nodes managed by the attach/
// detach controller. The key in this map is the name of the node and the // detach controller. The key in this map is the name of the node and the
// value is a node object containing more information about the node. // value is a node object containing more information about the node.
nodesManaged map[string]nodeManaged nodesManaged map[k8stypes.NodeName]nodeManaged
// volumePluginMgr is the volume plugin manager used to create volume // volumePluginMgr is the volume plugin manager used to create volume
// plugin objects. // plugin objects.
volumePluginMgr *volume.VolumePluginMgr volumePluginMgr *volume.VolumePluginMgr
...@@ -137,7 +138,7 @@ type desiredStateOfWorld struct { ...@@ -137,7 +138,7 @@ type desiredStateOfWorld struct {
// controller. // controller.
type nodeManaged struct { type nodeManaged struct {
// nodeName contains the name of this node. // nodeName contains the name of this node.
nodeName string nodeName k8stypes.NodeName
// volumesToAttach is a map containing the set of volumes that should be // volumesToAttach is a map containing the set of volumes that should be
// attached to this node. The key in the map is the name of the volume and // attached to this node. The key in the map is the name of the volume and
...@@ -172,7 +173,7 @@ type pod struct { ...@@ -172,7 +173,7 @@ type pod struct {
podObj *api.Pod podObj *api.Pod
} }
func (dsw *desiredStateOfWorld) AddNode(nodeName string) { func (dsw *desiredStateOfWorld) AddNode(nodeName k8stypes.NodeName) {
dsw.Lock() dsw.Lock()
defer dsw.Unlock() defer dsw.Unlock()
...@@ -188,7 +189,7 @@ func (dsw *desiredStateOfWorld) AddPod( ...@@ -188,7 +189,7 @@ func (dsw *desiredStateOfWorld) AddPod(
podName types.UniquePodName, podName types.UniquePodName,
podToAdd *api.Pod, podToAdd *api.Pod,
volumeSpec *volume.Spec, volumeSpec *volume.Spec,
nodeName string) (api.UniqueVolumeName, error) { nodeName k8stypes.NodeName) (api.UniqueVolumeName, error) {
dsw.Lock() dsw.Lock()
defer dsw.Unlock() defer dsw.Unlock()
...@@ -236,7 +237,7 @@ func (dsw *desiredStateOfWorld) AddPod( ...@@ -236,7 +237,7 @@ func (dsw *desiredStateOfWorld) AddPod(
return volumeName, nil return volumeName, nil
} }
func (dsw *desiredStateOfWorld) DeleteNode(nodeName string) error { func (dsw *desiredStateOfWorld) DeleteNode(nodeName k8stypes.NodeName) error {
dsw.Lock() dsw.Lock()
defer dsw.Unlock() defer dsw.Unlock()
...@@ -261,7 +262,7 @@ func (dsw *desiredStateOfWorld) DeleteNode(nodeName string) error { ...@@ -261,7 +262,7 @@ func (dsw *desiredStateOfWorld) DeleteNode(nodeName string) error {
func (dsw *desiredStateOfWorld) DeletePod( func (dsw *desiredStateOfWorld) DeletePod(
podName types.UniquePodName, podName types.UniquePodName,
volumeName api.UniqueVolumeName, volumeName api.UniqueVolumeName,
nodeName string) { nodeName k8stypes.NodeName) {
dsw.Lock() dsw.Lock()
defer dsw.Unlock() defer dsw.Unlock()
...@@ -289,7 +290,7 @@ func (dsw *desiredStateOfWorld) DeletePod( ...@@ -289,7 +290,7 @@ func (dsw *desiredStateOfWorld) DeletePod(
} }
} }
func (dsw *desiredStateOfWorld) NodeExists(nodeName string) bool { func (dsw *desiredStateOfWorld) NodeExists(nodeName k8stypes.NodeName) bool {
dsw.RLock() dsw.RLock()
defer dsw.RUnlock() defer dsw.RUnlock()
...@@ -298,7 +299,7 @@ func (dsw *desiredStateOfWorld) NodeExists(nodeName string) bool { ...@@ -298,7 +299,7 @@ func (dsw *desiredStateOfWorld) NodeExists(nodeName string) bool {
} }
func (dsw *desiredStateOfWorld) VolumeExists( func (dsw *desiredStateOfWorld) VolumeExists(
volumeName api.UniqueVolumeName, nodeName string) bool { volumeName api.UniqueVolumeName, nodeName k8stypes.NodeName) bool {
dsw.RLock() dsw.RLock()
defer dsw.RUnlock() defer dsw.RUnlock()
......
...@@ -26,6 +26,7 @@ import ( ...@@ -26,6 +26,7 @@ import (
"k8s.io/kubernetes/pkg/controller/volume/attachdetach/cache" "k8s.io/kubernetes/pkg/controller/volume/attachdetach/cache"
"k8s.io/kubernetes/pkg/controller/volume/attachdetach/statusupdater" "k8s.io/kubernetes/pkg/controller/volume/attachdetach/statusupdater"
controllervolumetesting "k8s.io/kubernetes/pkg/controller/volume/attachdetach/testing" controllervolumetesting "k8s.io/kubernetes/pkg/controller/volume/attachdetach/testing"
k8stypes "k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/util/wait" "k8s.io/kubernetes/pkg/util/wait"
volumetesting "k8s.io/kubernetes/pkg/volume/testing" volumetesting "k8s.io/kubernetes/pkg/volume/testing"
"k8s.io/kubernetes/pkg/volume/util/operationexecutor" "k8s.io/kubernetes/pkg/volume/util/operationexecutor"
...@@ -86,7 +87,7 @@ func Test_Run_Positive_OneDesiredVolumeAttach(t *testing.T) { ...@@ -86,7 +87,7 @@ func Test_Run_Positive_OneDesiredVolumeAttach(t *testing.T) {
podName := "pod-uid" podName := "pod-uid"
volumeName := api.UniqueVolumeName("volume-name") volumeName := api.UniqueVolumeName("volume-name")
volumeSpec := controllervolumetesting.GetTestVolumeSpec(string(volumeName), volumeName) volumeSpec := controllervolumetesting.GetTestVolumeSpec(string(volumeName), volumeName)
nodeName := "node-name" nodeName := k8stypes.NodeName("node-name")
dsw.AddNode(nodeName) dsw.AddNode(nodeName)
volumeExists := dsw.VolumeExists(volumeName, nodeName) volumeExists := dsw.VolumeExists(volumeName, nodeName)
if volumeExists { if volumeExists {
...@@ -132,7 +133,7 @@ func Test_Run_Positive_OneDesiredVolumeAttachThenDetachWithUnmountedVolume(t *te ...@@ -132,7 +133,7 @@ func Test_Run_Positive_OneDesiredVolumeAttachThenDetachWithUnmountedVolume(t *te
podName := "pod-uid" podName := "pod-uid"
volumeName := api.UniqueVolumeName("volume-name") volumeName := api.UniqueVolumeName("volume-name")
volumeSpec := controllervolumetesting.GetTestVolumeSpec(string(volumeName), volumeName) volumeSpec := controllervolumetesting.GetTestVolumeSpec(string(volumeName), volumeName)
nodeName := "node-name" nodeName := k8stypes.NodeName("node-name")
dsw.AddNode(nodeName) dsw.AddNode(nodeName)
volumeExists := dsw.VolumeExists(volumeName, nodeName) volumeExists := dsw.VolumeExists(volumeName, nodeName)
if volumeExists { if volumeExists {
...@@ -199,7 +200,7 @@ func Test_Run_Positive_OneDesiredVolumeAttachThenDetachWithMountedVolume(t *test ...@@ -199,7 +200,7 @@ func Test_Run_Positive_OneDesiredVolumeAttachThenDetachWithMountedVolume(t *test
podName := "pod-uid" podName := "pod-uid"
volumeName := api.UniqueVolumeName("volume-name") volumeName := api.UniqueVolumeName("volume-name")
volumeSpec := controllervolumetesting.GetTestVolumeSpec(string(volumeName), volumeName) volumeSpec := controllervolumetesting.GetTestVolumeSpec(string(volumeName), volumeName)
nodeName := "node-name" nodeName := k8stypes.NodeName("node-name")
dsw.AddNode(nodeName) dsw.AddNode(nodeName)
volumeExists := dsw.VolumeExists(volumeName, nodeName) volumeExists := dsw.VolumeExists(volumeName, nodeName)
if volumeExists { if volumeExists {
...@@ -266,7 +267,7 @@ func Test_Run_Negative_OneDesiredVolumeAttachThenDetachWithUnmountedVolumeUpdate ...@@ -266,7 +267,7 @@ func Test_Run_Negative_OneDesiredVolumeAttachThenDetachWithUnmountedVolumeUpdate
podName := "pod-uid" podName := "pod-uid"
volumeName := api.UniqueVolumeName("volume-name") volumeName := api.UniqueVolumeName("volume-name")
volumeSpec := controllervolumetesting.GetTestVolumeSpec(string(volumeName), volumeName) volumeSpec := controllervolumetesting.GetTestVolumeSpec(string(volumeName), volumeName)
nodeName := "node-name" nodeName := k8stypes.NodeName("node-name")
dsw.AddNode(nodeName) dsw.AddNode(nodeName)
volumeExists := dsw.VolumeExists(volumeName, nodeName) volumeExists := dsw.VolumeExists(volumeName, nodeName)
if volumeExists { if volumeExists {
......
...@@ -60,7 +60,7 @@ type nodeStatusUpdater struct { ...@@ -60,7 +60,7 @@ type nodeStatusUpdater struct {
func (nsu *nodeStatusUpdater) UpdateNodeStatuses() error { func (nsu *nodeStatusUpdater) UpdateNodeStatuses() error {
nodesToUpdate := nsu.actualStateOfWorld.GetVolumesToReportAttached() nodesToUpdate := nsu.actualStateOfWorld.GetVolumesToReportAttached()
for nodeName, attachedVolumes := range nodesToUpdate { for nodeName, attachedVolumes := range nodesToUpdate {
nodeObj, exists, err := nsu.nodeInformer.GetStore().GetByKey(nodeName) nodeObj, exists, err := nsu.nodeInformer.GetStore().GetByKey(string(nodeName))
if nodeObj == nil || !exists || err != nil { if nodeObj == nil || !exists || err != nil {
// If node does not exist, its status cannot be updated, log error and move on. // If node does not exist, its status cannot be updated, log error and move on.
glog.V(5).Infof( glog.V(5).Infof(
...@@ -105,7 +105,7 @@ func (nsu *nodeStatusUpdater) UpdateNodeStatuses() error { ...@@ -105,7 +105,7 @@ func (nsu *nodeStatusUpdater) UpdateNodeStatuses() error {
err) err)
} }
_, err = nsu.kubeClient.Core().Nodes().PatchStatus(nodeName, patchBytes) _, err = nsu.kubeClient.Core().Nodes().PatchStatus(string(nodeName), patchBytes)
if err != nil { if err != nil {
// If update node status fails, reset flag statusUpdateNeeded back to true // If update node status fails, reset flag statusUpdateNeeded back to true
// to indicate this node status needs to be udpated again // to indicate this node status needs to be udpated again
......
...@@ -7735,7 +7735,7 @@ var OpenAPIDefinitions *common.OpenAPIDefinitions = &common.OpenAPIDefinitions{ ...@@ -7735,7 +7735,7 @@ var OpenAPIDefinitions *common.OpenAPIDefinitions = &common.OpenAPIDefinitions{
}, },
"host": { "host": {
SchemaProps: spec.SchemaProps{ SchemaProps: spec.SchemaProps{
Description: "Host name on which the event is generated.", Description: "Node name on which the event is generated.",
Type: []string{"string"}, Type: []string{"string"},
Format: "", Format: "",
}, },
......
...@@ -426,11 +426,15 @@ func DefaultAndValidateRunOptions(options *options.ServerRunOptions) { ...@@ -426,11 +426,15 @@ func DefaultAndValidateRunOptions(options *options.ServerRunOptions) {
if !supported { if !supported {
glog.Fatalf("GCE cloud provider has no instances. this shouldn't happen. exiting.") glog.Fatalf("GCE cloud provider has no instances. this shouldn't happen. exiting.")
} }
name, err := os.Hostname() hostname, err := os.Hostname()
if err != nil { if err != nil {
glog.Fatalf("Failed to get hostname: %v", err) glog.Fatalf("Failed to get hostname: %v", err)
} }
addrs, err := instances.NodeAddresses(name) nodeName, err := instances.CurrentNodeName(hostname)
if err != nil {
glog.Fatalf("Failed to get NodeName: %v", err)
}
addrs, err := instances.NodeAddresses(nodeName)
if err != nil { if err != nil {
glog.Warningf("Unable to obtain external host address from cloud provider: %v", err) glog.Warningf("Unable to obtain external host address from cloud provider: %v", err)
} else { } else {
......
...@@ -23,11 +23,12 @@ import ( ...@@ -23,11 +23,12 @@ import (
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/fields"
kubetypes "k8s.io/kubernetes/pkg/kubelet/types" kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
"k8s.io/kubernetes/pkg/types"
) )
// NewSourceApiserver creates a config source that watches and pulls from the apiserver. // NewSourceApiserver creates a config source that watches and pulls from the apiserver.
func NewSourceApiserver(c *clientset.Clientset, nodeName string, updates chan<- interface{}) { func NewSourceApiserver(c *clientset.Clientset, nodeName types.NodeName, updates chan<- interface{}) {
lw := cache.NewListWatchFromClient(c.CoreClient, "pods", api.NamespaceAll, fields.OneTermEqualSelector(api.PodHostField, nodeName)) lw := cache.NewListWatchFromClient(c.CoreClient, "pods", api.NamespaceAll, fields.OneTermEqualSelector(api.PodHostField, string(nodeName)))
newSourceApiserverFromLW(lw, updates) newSourceApiserverFromLW(lw, updates)
} }
......
...@@ -35,11 +35,11 @@ import ( ...@@ -35,11 +35,11 @@ import (
) )
// Generate a pod name that is unique among nodes by appending the nodeName. // Generate a pod name that is unique among nodes by appending the nodeName.
func generatePodName(name, nodeName string) string { func generatePodName(name string, nodeName types.NodeName) string {
return fmt.Sprintf("%s-%s", name, nodeName) return fmt.Sprintf("%s-%s", name, nodeName)
} }
func applyDefaults(pod *api.Pod, source string, isFile bool, nodeName string) error { func applyDefaults(pod *api.Pod, source string, isFile bool, nodeName types.NodeName) error {
if len(pod.UID) == 0 { if len(pod.UID) == 0 {
hasher := md5.New() hasher := md5.New()
if isFile { if isFile {
...@@ -62,7 +62,7 @@ func applyDefaults(pod *api.Pod, source string, isFile bool, nodeName string) er ...@@ -62,7 +62,7 @@ func applyDefaults(pod *api.Pod, source string, isFile bool, nodeName string) er
glog.V(5).Infof("Using namespace %q for pod %q from %s", pod.Namespace, pod.Name, source) glog.V(5).Infof("Using namespace %q for pod %q from %s", pod.Namespace, pod.Name, source)
// Set the Host field to indicate this pod is scheduled on the current node. // Set the Host field to indicate this pod is scheduled on the current node.
pod.Spec.NodeName = nodeName pod.Spec.NodeName = string(nodeName)
pod.ObjectMeta.SelfLink = getSelfLink(pod.Name, pod.Namespace) pod.ObjectMeta.SelfLink = getSelfLink(pod.Name, pod.Namespace)
......
...@@ -30,15 +30,16 @@ import ( ...@@ -30,15 +30,16 @@ import (
"k8s.io/kubernetes/pkg/util/wait" "k8s.io/kubernetes/pkg/util/wait"
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kubernetes/pkg/types"
) )
type sourceFile struct { type sourceFile struct {
path string path string
nodeName string nodeName types.NodeName
updates chan<- interface{} updates chan<- interface{}
} }
func NewSourceFile(path string, nodeName string, period time.Duration, updates chan<- interface{}) { func NewSourceFile(path string, nodeName types.NodeName, period time.Duration, updates chan<- interface{}) {
config := &sourceFile{ config := &sourceFile{
path: path, path: path,
nodeName: nodeName, nodeName: nodeName,
......
...@@ -29,6 +29,7 @@ import ( ...@@ -29,6 +29,7 @@ import (
kubetypes "k8s.io/kubernetes/pkg/kubelet/types" kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/securitycontext" "k8s.io/kubernetes/pkg/securitycontext"
"k8s.io/kubernetes/pkg/types"
utiltesting "k8s.io/kubernetes/pkg/util/testing" utiltesting "k8s.io/kubernetes/pkg/util/testing"
"k8s.io/kubernetes/pkg/util/wait" "k8s.io/kubernetes/pkg/util/wait"
) )
...@@ -71,7 +72,7 @@ func writeTestFile(t *testing.T, dir, name string, contents string) *os.File { ...@@ -71,7 +72,7 @@ func writeTestFile(t *testing.T, dir, name string, contents string) *os.File {
} }
func TestReadPodsFromFile(t *testing.T) { func TestReadPodsFromFile(t *testing.T) {
hostname := "random-test-hostname" nodeName := "random-test-hostname"
grace := int64(30) grace := int64(30)
var testCases = []struct { var testCases = []struct {
desc string desc string
...@@ -100,14 +101,14 @@ func TestReadPodsFromFile(t *testing.T) { ...@@ -100,14 +101,14 @@ func TestReadPodsFromFile(t *testing.T) {
}, },
expected: CreatePodUpdate(kubetypes.SET, kubetypes.FileSource, &api.Pod{ expected: CreatePodUpdate(kubetypes.SET, kubetypes.FileSource, &api.Pod{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
Name: "test-" + hostname, Name: "test-" + nodeName,
UID: "12345", UID: "12345",
Namespace: "mynamespace", Namespace: "mynamespace",
Annotations: map[string]string{kubetypes.ConfigHashAnnotationKey: "12345"}, Annotations: map[string]string{kubetypes.ConfigHashAnnotationKey: "12345"},
SelfLink: getSelfLink("test-"+hostname, "mynamespace"), SelfLink: getSelfLink("test-"+nodeName, "mynamespace"),
}, },
Spec: api.PodSpec{ Spec: api.PodSpec{
NodeName: hostname, NodeName: nodeName,
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace, TerminationGracePeriodSeconds: &grace,
...@@ -142,7 +143,7 @@ func TestReadPodsFromFile(t *testing.T) { ...@@ -142,7 +143,7 @@ func TestReadPodsFromFile(t *testing.T) {
defer os.Remove(file.Name()) defer os.Remove(file.Name())
ch := make(chan interface{}) ch := make(chan interface{})
NewSourceFile(file.Name(), hostname, time.Millisecond, ch) NewSourceFile(file.Name(), types.NodeName(nodeName), time.Millisecond, ch)
select { select {
case got := <-ch: case got := <-ch:
update := got.(kubetypes.PodUpdate) update := got.(kubetypes.PodUpdate)
......
...@@ -29,19 +29,20 @@ import ( ...@@ -29,19 +29,20 @@ import (
"k8s.io/kubernetes/pkg/util/wait" "k8s.io/kubernetes/pkg/util/wait"
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kubernetes/pkg/types"
) )
type sourceURL struct { type sourceURL struct {
url string url string
header http.Header header http.Header
nodeName string nodeName types.NodeName
updates chan<- interface{} updates chan<- interface{}
data []byte data []byte
failureLogs int failureLogs int
client *http.Client client *http.Client
} }
func NewSourceURL(url string, header http.Header, nodeName string, period time.Duration, updates chan<- interface{}) { func NewSourceURL(url string, header http.Header, nodeName types.NodeName, period time.Duration, updates chan<- interface{}) {
config := &sourceURL{ config := &sourceURL{
url: url, url: url,
header: header, header: header,
......
...@@ -29,6 +29,7 @@ import ( ...@@ -29,6 +29,7 @@ import (
"k8s.io/kubernetes/pkg/api/validation" "k8s.io/kubernetes/pkg/api/validation"
kubetypes "k8s.io/kubernetes/pkg/kubelet/types" kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/types"
utiltesting "k8s.io/kubernetes/pkg/util/testing" utiltesting "k8s.io/kubernetes/pkg/util/testing"
) )
...@@ -121,7 +122,7 @@ func TestExtractInvalidPods(t *testing.T) { ...@@ -121,7 +122,7 @@ func TestExtractInvalidPods(t *testing.T) {
} }
func TestExtractPodsFromHTTP(t *testing.T) { func TestExtractPodsFromHTTP(t *testing.T) {
hostname := "different-value" nodeName := "different-value"
grace := int64(30) grace := int64(30)
var testCases = []struct { var testCases = []struct {
...@@ -142,7 +143,7 @@ func TestExtractPodsFromHTTP(t *testing.T) { ...@@ -142,7 +143,7 @@ func TestExtractPodsFromHTTP(t *testing.T) {
Namespace: "mynamespace", Namespace: "mynamespace",
}, },
Spec: api.PodSpec{ Spec: api.PodSpec{
NodeName: hostname, NodeName: string(nodeName),
Containers: []api.Container{{Name: "1", Image: "foo", ImagePullPolicy: api.PullAlways}}, Containers: []api.Container{{Name: "1", Image: "foo", ImagePullPolicy: api.PullAlways}},
SecurityContext: &api.PodSecurityContext{}, SecurityContext: &api.PodSecurityContext{},
}, },
...@@ -155,13 +156,13 @@ func TestExtractPodsFromHTTP(t *testing.T) { ...@@ -155,13 +156,13 @@ func TestExtractPodsFromHTTP(t *testing.T) {
&api.Pod{ &api.Pod{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
UID: "111", UID: "111",
Name: "foo" + "-" + hostname, Name: "foo" + "-" + nodeName,
Namespace: "mynamespace", Namespace: "mynamespace",
Annotations: map[string]string{kubetypes.ConfigHashAnnotationKey: "111"}, Annotations: map[string]string{kubetypes.ConfigHashAnnotationKey: "111"},
SelfLink: getSelfLink("foo-"+hostname, "mynamespace"), SelfLink: getSelfLink("foo-"+nodeName, "mynamespace"),
}, },
Spec: api.PodSpec{ Spec: api.PodSpec{
NodeName: hostname, NodeName: nodeName,
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
SecurityContext: &api.PodSecurityContext{}, SecurityContext: &api.PodSecurityContext{},
...@@ -193,7 +194,7 @@ func TestExtractPodsFromHTTP(t *testing.T) { ...@@ -193,7 +194,7 @@ func TestExtractPodsFromHTTP(t *testing.T) {
UID: "111", UID: "111",
}, },
Spec: api.PodSpec{ Spec: api.PodSpec{
NodeName: hostname, NodeName: nodeName,
Containers: []api.Container{{Name: "1", Image: "foo", ImagePullPolicy: api.PullAlways}}, Containers: []api.Container{{Name: "1", Image: "foo", ImagePullPolicy: api.PullAlways}},
SecurityContext: &api.PodSecurityContext{}, SecurityContext: &api.PodSecurityContext{},
}, },
...@@ -207,7 +208,7 @@ func TestExtractPodsFromHTTP(t *testing.T) { ...@@ -207,7 +208,7 @@ func TestExtractPodsFromHTTP(t *testing.T) {
UID: "222", UID: "222",
}, },
Spec: api.PodSpec{ Spec: api.PodSpec{
NodeName: hostname, NodeName: nodeName,
Containers: []api.Container{{Name: "2", Image: "bar:bartag", ImagePullPolicy: ""}}, Containers: []api.Container{{Name: "2", Image: "bar:bartag", ImagePullPolicy: ""}},
SecurityContext: &api.PodSecurityContext{}, SecurityContext: &api.PodSecurityContext{},
}, },
...@@ -222,13 +223,13 @@ func TestExtractPodsFromHTTP(t *testing.T) { ...@@ -222,13 +223,13 @@ func TestExtractPodsFromHTTP(t *testing.T) {
&api.Pod{ &api.Pod{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
UID: "111", UID: "111",
Name: "foo" + "-" + hostname, Name: "foo" + "-" + nodeName,
Namespace: "default", Namespace: "default",
Annotations: map[string]string{kubetypes.ConfigHashAnnotationKey: "111"}, Annotations: map[string]string{kubetypes.ConfigHashAnnotationKey: "111"},
SelfLink: getSelfLink("foo-"+hostname, kubetypes.NamespaceDefault), SelfLink: getSelfLink("foo-"+nodeName, kubetypes.NamespaceDefault),
}, },
Spec: api.PodSpec{ Spec: api.PodSpec{
NodeName: hostname, NodeName: nodeName,
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace, TerminationGracePeriodSeconds: &grace,
...@@ -248,13 +249,13 @@ func TestExtractPodsFromHTTP(t *testing.T) { ...@@ -248,13 +249,13 @@ func TestExtractPodsFromHTTP(t *testing.T) {
&api.Pod{ &api.Pod{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
UID: "222", UID: "222",
Name: "bar" + "-" + hostname, Name: "bar" + "-" + nodeName,
Namespace: "default", Namespace: "default",
Annotations: map[string]string{kubetypes.ConfigHashAnnotationKey: "222"}, Annotations: map[string]string{kubetypes.ConfigHashAnnotationKey: "222"},
SelfLink: getSelfLink("bar-"+hostname, kubetypes.NamespaceDefault), SelfLink: getSelfLink("bar-"+nodeName, kubetypes.NamespaceDefault),
}, },
Spec: api.PodSpec{ Spec: api.PodSpec{
NodeName: hostname, NodeName: nodeName,
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace, TerminationGracePeriodSeconds: &grace,
...@@ -291,7 +292,7 @@ func TestExtractPodsFromHTTP(t *testing.T) { ...@@ -291,7 +292,7 @@ func TestExtractPodsFromHTTP(t *testing.T) {
testServer := httptest.NewServer(&fakeHandler) testServer := httptest.NewServer(&fakeHandler)
defer testServer.Close() defer testServer.Close()
ch := make(chan interface{}, 1) ch := make(chan interface{}, 1)
c := sourceURL{testServer.URL, http.Header{}, hostname, ch, nil, 0, http.DefaultClient} c := sourceURL{testServer.URL, http.Header{}, types.NodeName(nodeName), ch, nil, 0, http.DefaultClient}
if err := c.extractFromURL(); err != nil { if err := c.extractFromURL(); err != nil {
t.Errorf("%s: Unexpected error: %v", testCase.desc, err) t.Errorf("%s: Unexpected error: %v", testCase.desc, err)
continue continue
......
...@@ -237,7 +237,7 @@ type KubeletDeps struct { ...@@ -237,7 +237,7 @@ type KubeletDeps struct {
// makePodSourceConfig creates a config.PodConfig from the given // makePodSourceConfig creates a config.PodConfig from the given
// KubeletConfiguration or returns an error. // KubeletConfiguration or returns an error.
func makePodSourceConfig(kubeCfg *componentconfig.KubeletConfiguration, kubeDeps *KubeletDeps, nodeName string) (*config.PodConfig, error) { func makePodSourceConfig(kubeCfg *componentconfig.KubeletConfiguration, kubeDeps *KubeletDeps, nodeName types.NodeName) (*config.PodConfig, error) {
manifestURLHeader := make(http.Header) manifestURLHeader := make(http.Header)
if kubeCfg.ManifestURLHeader != "" { if kubeCfg.ManifestURLHeader != "" {
pieces := strings.Split(kubeCfg.ManifestURLHeader, ":") pieces := strings.Split(kubeCfg.ManifestURLHeader, ":")
...@@ -292,7 +292,7 @@ func NewMainKubelet(kubeCfg *componentconfig.KubeletConfiguration, kubeDeps *Kub ...@@ -292,7 +292,7 @@ func NewMainKubelet(kubeCfg *componentconfig.KubeletConfiguration, kubeDeps *Kub
hostname := nodeutil.GetHostname(kubeCfg.HostnameOverride) hostname := nodeutil.GetHostname(kubeCfg.HostnameOverride)
// Query the cloud provider for our node name, default to hostname // Query the cloud provider for our node name, default to hostname
nodeName := hostname nodeName := types.NodeName(hostname)
if kubeDeps.Cloud != nil { if kubeDeps.Cloud != nil {
var err error var err error
instances, ok := kubeDeps.Cloud.Instances() instances, ok := kubeDeps.Cloud.Instances()
...@@ -392,7 +392,7 @@ func NewMainKubelet(kubeCfg *componentconfig.KubeletConfiguration, kubeDeps *Kub ...@@ -392,7 +392,7 @@ func NewMainKubelet(kubeCfg *componentconfig.KubeletConfiguration, kubeDeps *Kub
if kubeClient != nil { if kubeClient != nil {
// TODO: cache.NewListWatchFromClient is limited as it takes a client implementation rather // TODO: cache.NewListWatchFromClient is limited as it takes a client implementation rather
// than an interface. There is no way to construct a list+watcher using resource name. // than an interface. There is no way to construct a list+watcher using resource name.
fieldSelector := fields.Set{api.ObjectNameField: nodeName}.AsSelector() fieldSelector := fields.Set{api.ObjectNameField: string(nodeName)}.AsSelector()
listWatch := &cache.ListWatch{ listWatch := &cache.ListWatch{
ListFunc: func(options api.ListOptions) (runtime.Object, error) { ListFunc: func(options api.ListOptions) (runtime.Object, error) {
options.FieldSelector = fieldSelector options.FieldSelector = fieldSelector
...@@ -413,7 +413,7 @@ func NewMainKubelet(kubeCfg *componentconfig.KubeletConfiguration, kubeDeps *Kub ...@@ -413,7 +413,7 @@ func NewMainKubelet(kubeCfg *componentconfig.KubeletConfiguration, kubeDeps *Kub
// TODO: what is namespace for node? // TODO: what is namespace for node?
nodeRef := &api.ObjectReference{ nodeRef := &api.ObjectReference{
Kind: "Node", Kind: "Node",
Name: nodeName, Name: string(nodeName),
UID: types.UID(nodeName), UID: types.UID(nodeName),
Namespace: "", Namespace: "",
} }
...@@ -798,7 +798,7 @@ type Kubelet struct { ...@@ -798,7 +798,7 @@ type Kubelet struct {
kubeletConfiguration componentconfig.KubeletConfiguration kubeletConfiguration componentconfig.KubeletConfiguration
hostname string hostname string
nodeName string nodeName types.NodeName
dockerClient dockertools.DockerInterface dockerClient dockertools.DockerInterface
runtimeCache kubecontainer.RuntimeCache runtimeCache kubecontainer.RuntimeCache
kubeClient clientset.Interface kubeClient clientset.Interface
......
...@@ -191,7 +191,7 @@ func (kl *Kubelet) GetNode() (*api.Node, error) { ...@@ -191,7 +191,7 @@ func (kl *Kubelet) GetNode() (*api.Node, error) {
if kl.standaloneMode { if kl.standaloneMode {
return kl.initialNode() return kl.initialNode()
} }
return kl.nodeInfo.GetNodeInfo(kl.nodeName) return kl.nodeInfo.GetNodeInfo(string(kl.nodeName))
} }
// getNodeAnyWay() must return a *api.Node which is required by RunGeneralPredicates(). // getNodeAnyWay() must return a *api.Node which is required by RunGeneralPredicates().
...@@ -201,7 +201,7 @@ func (kl *Kubelet) GetNode() (*api.Node, error) { ...@@ -201,7 +201,7 @@ func (kl *Kubelet) GetNode() (*api.Node, error) {
// zero capacity, and the default labels. // zero capacity, and the default labels.
func (kl *Kubelet) getNodeAnyWay() (*api.Node, error) { func (kl *Kubelet) getNodeAnyWay() (*api.Node, error) {
if !kl.standaloneMode { if !kl.standaloneMode {
if n, err := kl.nodeInfo.GetNodeInfo(kl.nodeName); err == nil { if n, err := kl.nodeInfo.GetNodeInfo(string(kl.nodeName)); err == nil {
return n, nil return n, nil
} }
} }
......
...@@ -98,7 +98,7 @@ func (kl *Kubelet) tryRegisterWithApiServer(node *api.Node) bool { ...@@ -98,7 +98,7 @@ func (kl *Kubelet) tryRegisterWithApiServer(node *api.Node) bool {
return false return false
} }
existingNode, err := kl.kubeClient.Core().Nodes().Get(kl.nodeName) existingNode, err := kl.kubeClient.Core().Nodes().Get(string(kl.nodeName))
if err != nil { if err != nil {
glog.Errorf("Unable to register node %q with API server: error getting existing node: %v", kl.nodeName, err) glog.Errorf("Unable to register node %q with API server: error getting existing node: %v", kl.nodeName, err)
return false return false
...@@ -173,7 +173,7 @@ func (kl *Kubelet) reconcileCMADAnnotationWithExistingNode(node, existingNode *a ...@@ -173,7 +173,7 @@ func (kl *Kubelet) reconcileCMADAnnotationWithExistingNode(node, existingNode *a
func (kl *Kubelet) initialNode() (*api.Node, error) { func (kl *Kubelet) initialNode() (*api.Node, error) {
node := &api.Node{ node := &api.Node{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
Name: kl.nodeName, Name: string(kl.nodeName),
Labels: map[string]string{ Labels: map[string]string{
unversioned.LabelHostname: kl.hostname, unversioned.LabelHostname: kl.hostname,
unversioned.LabelOS: goRuntime.GOOS, unversioned.LabelOS: goRuntime.GOOS,
...@@ -309,7 +309,7 @@ func (kl *Kubelet) updateNodeStatus() error { ...@@ -309,7 +309,7 @@ func (kl *Kubelet) updateNodeStatus() error {
// tryUpdateNodeStatus tries to update node status to master. If ReconcileCBR0 // tryUpdateNodeStatus tries to update node status to master. If ReconcileCBR0
// is set, this function will also confirm that cbr0 is configured correctly. // is set, this function will also confirm that cbr0 is configured correctly.
func (kl *Kubelet) tryUpdateNodeStatus() error { func (kl *Kubelet) tryUpdateNodeStatus() error {
node, err := kl.kubeClient.Core().Nodes().Get(kl.nodeName) node, err := kl.kubeClient.Core().Nodes().Get(string(kl.nodeName))
if err != nil { if err != nil {
return fmt.Errorf("error getting node %q: %v", kl.nodeName, err) return fmt.Errorf("error getting node %q: %v", kl.nodeName, err)
} }
......
...@@ -137,7 +137,7 @@ func newTestKubeletWithImageList( ...@@ -137,7 +137,7 @@ func newTestKubeletWithImageList(
kubelet.os = &containertest.FakeOS{} kubelet.os = &containertest.FakeOS{}
kubelet.hostname = testKubeletHostname kubelet.hostname = testKubeletHostname
kubelet.nodeName = testKubeletHostname kubelet.nodeName = types.NodeName(testKubeletHostname)
kubelet.runtimeState = newRuntimeState(maxWaitForContainerRuntime) kubelet.runtimeState = newRuntimeState(maxWaitForContainerRuntime)
kubelet.runtimeState.setNetworkState(nil) kubelet.runtimeState.setNetworkState(nil)
kubelet.networkPlugin, _ = network.InitNetworkPlugin([]network.NetworkPlugin{}, "", nettest.NewFakeHost(nil), componentconfig.HairpinNone, kubelet.nonMasqueradeCIDR, 1440) kubelet.networkPlugin, _ = network.InitNetworkPlugin([]network.NetworkPlugin{}, "", nettest.NewFakeHost(nil), componentconfig.HairpinNone, kubelet.nonMasqueradeCIDR, 1440)
...@@ -220,7 +220,7 @@ func newTestKubeletWithImageList( ...@@ -220,7 +220,7 @@ func newTestKubeletWithImageList(
kubelet.resourceAnalyzer = stats.NewResourceAnalyzer(kubelet, volumeStatsAggPeriod, kubelet.containerRuntime) kubelet.resourceAnalyzer = stats.NewResourceAnalyzer(kubelet, volumeStatsAggPeriod, kubelet.containerRuntime)
nodeRef := &api.ObjectReference{ nodeRef := &api.ObjectReference{
Kind: "Node", Kind: "Node",
Name: kubelet.nodeName, Name: string(kubelet.nodeName),
UID: types.UID(kubelet.nodeName), UID: types.UID(kubelet.nodeName),
Namespace: "", Namespace: "",
} }
...@@ -241,7 +241,7 @@ func newTestKubeletWithImageList( ...@@ -241,7 +241,7 @@ func newTestKubeletWithImageList(
kubelet.mounter = &mount.FakeMounter{} kubelet.mounter = &mount.FakeMounter{}
kubelet.volumeManager, err = kubeletvolume.NewVolumeManager( kubelet.volumeManager, err = kubeletvolume.NewVolumeManager(
controllerAttachDetachEnabled, controllerAttachDetachEnabled,
kubelet.hostname, kubelet.nodeName,
kubelet.podManager, kubelet.podManager,
fakeKubeClient, fakeKubeClient,
kubelet.volumePluginMgr, kubelet.volumePluginMgr,
...@@ -1933,7 +1933,7 @@ func TestHandlePortConflicts(t *testing.T) { ...@@ -1933,7 +1933,7 @@ func TestHandlePortConflicts(t *testing.T) {
kl.nodeLister = testNodeLister{nodes: []api.Node{ kl.nodeLister = testNodeLister{nodes: []api.Node{
{ {
ObjectMeta: api.ObjectMeta{Name: kl.nodeName}, ObjectMeta: api.ObjectMeta{Name: string(kl.nodeName)},
Status: api.NodeStatus{ Status: api.NodeStatus{
Allocatable: api.ResourceList{ Allocatable: api.ResourceList{
api.ResourcePods: *resource.NewQuantity(110, resource.DecimalSI), api.ResourcePods: *resource.NewQuantity(110, resource.DecimalSI),
...@@ -1943,7 +1943,7 @@ func TestHandlePortConflicts(t *testing.T) { ...@@ -1943,7 +1943,7 @@ func TestHandlePortConflicts(t *testing.T) {
}} }}
kl.nodeInfo = testNodeInfo{nodes: []api.Node{ kl.nodeInfo = testNodeInfo{nodes: []api.Node{
{ {
ObjectMeta: api.ObjectMeta{Name: kl.nodeName}, ObjectMeta: api.ObjectMeta{Name: string(kl.nodeName)},
Status: api.NodeStatus{ Status: api.NodeStatus{
Allocatable: api.ResourceList{ Allocatable: api.ResourceList{
api.ResourcePods: *resource.NewQuantity(110, resource.DecimalSI), api.ResourcePods: *resource.NewQuantity(110, resource.DecimalSI),
...@@ -1952,7 +1952,7 @@ func TestHandlePortConflicts(t *testing.T) { ...@@ -1952,7 +1952,7 @@ func TestHandlePortConflicts(t *testing.T) {
}, },
}} }}
spec := api.PodSpec{NodeName: kl.nodeName, Containers: []api.Container{{Ports: []api.ContainerPort{{HostPort: 80}}}}} spec := api.PodSpec{NodeName: string(kl.nodeName), Containers: []api.Container{{Ports: []api.ContainerPort{{HostPort: 80}}}}}
pods := []*api.Pod{ pods := []*api.Pod{
podWithUidNameNsSpec("123456789", "newpod", "foo", spec), podWithUidNameNsSpec("123456789", "newpod", "foo", spec),
podWithUidNameNsSpec("987654321", "oldpod", "foo", spec), podWithUidNameNsSpec("987654321", "oldpod", "foo", spec),
...@@ -2086,7 +2086,7 @@ func TestHandleMemExceeded(t *testing.T) { ...@@ -2086,7 +2086,7 @@ func TestHandleMemExceeded(t *testing.T) {
testKubelet.fakeCadvisor.On("ImagesFsInfo").Return(cadvisorapiv2.FsInfo{}, nil) testKubelet.fakeCadvisor.On("ImagesFsInfo").Return(cadvisorapiv2.FsInfo{}, nil)
testKubelet.fakeCadvisor.On("RootFsInfo").Return(cadvisorapiv2.FsInfo{}, nil) testKubelet.fakeCadvisor.On("RootFsInfo").Return(cadvisorapiv2.FsInfo{}, nil)
spec := api.PodSpec{NodeName: kl.nodeName, spec := api.PodSpec{NodeName: string(kl.nodeName),
Containers: []api.Container{{Resources: api.ResourceRequirements{ Containers: []api.Container{{Resources: api.ResourceRequirements{
Requests: api.ResourceList{ Requests: api.ResourceList{
"memory": resource.MustParse("90"), "memory": resource.MustParse("90"),
...@@ -3312,7 +3312,7 @@ func TestHandlePodAdditionsInvokesPodAdmitHandlers(t *testing.T) { ...@@ -3312,7 +3312,7 @@ func TestHandlePodAdditionsInvokesPodAdmitHandlers(t *testing.T) {
kl := testKubelet.kubelet kl := testKubelet.kubelet
kl.nodeLister = testNodeLister{nodes: []api.Node{ kl.nodeLister = testNodeLister{nodes: []api.Node{
{ {
ObjectMeta: api.ObjectMeta{Name: kl.nodeName}, ObjectMeta: api.ObjectMeta{Name: string(kl.nodeName)},
Status: api.NodeStatus{ Status: api.NodeStatus{
Allocatable: api.ResourceList{ Allocatable: api.ResourceList{
api.ResourcePods: *resource.NewQuantity(110, resource.DecimalSI), api.ResourcePods: *resource.NewQuantity(110, resource.DecimalSI),
...@@ -3322,7 +3322,7 @@ func TestHandlePodAdditionsInvokesPodAdmitHandlers(t *testing.T) { ...@@ -3322,7 +3322,7 @@ func TestHandlePodAdditionsInvokesPodAdmitHandlers(t *testing.T) {
}} }}
kl.nodeInfo = testNodeInfo{nodes: []api.Node{ kl.nodeInfo = testNodeInfo{nodes: []api.Node{
{ {
ObjectMeta: api.ObjectMeta{Name: kl.nodeName}, ObjectMeta: api.ObjectMeta{Name: string(kl.nodeName)},
Status: api.NodeStatus{ Status: api.NodeStatus{
Allocatable: api.ResourceList{ Allocatable: api.ResourceList{
api.ResourcePods: *resource.NewQuantity(110, resource.DecimalSI), api.ResourcePods: *resource.NewQuantity(110, resource.DecimalSI),
......
...@@ -94,7 +94,7 @@ func TestRunOnce(t *testing.T) { ...@@ -94,7 +94,7 @@ func TestRunOnce(t *testing.T) {
} }
kb.volumeManager, err = volumemanager.NewVolumeManager( kb.volumeManager, err = volumemanager.NewVolumeManager(
true, true,
kb.hostname, kb.nodeName,
kb.podManager, kb.podManager,
kb.kubeClient, kb.kubeClient,
kb.volumePluginMgr, kb.volumePluginMgr,
...@@ -109,7 +109,7 @@ func TestRunOnce(t *testing.T) { ...@@ -109,7 +109,7 @@ func TestRunOnce(t *testing.T) {
kb.resourceAnalyzer = stats.NewResourceAnalyzer(kb, volumeStatsAggPeriod, kb.containerRuntime) kb.resourceAnalyzer = stats.NewResourceAnalyzer(kb, volumeStatsAggPeriod, kb.containerRuntime)
nodeRef := &api.ObjectReference{ nodeRef := &api.ObjectReference{
Kind: "Node", Kind: "Node",
Name: kb.nodeName, Name: string(kb.nodeName),
UID: types.UID(kb.nodeName), UID: types.UID(kb.nodeName),
Namespace: "", Namespace: "",
} }
......
...@@ -25,6 +25,7 @@ import ( ...@@ -25,6 +25,7 @@ import (
"k8s.io/kubernetes/pkg/apis/certificates" "k8s.io/kubernetes/pkg/apis/certificates"
unversionedcertificates "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/certificates/unversioned" unversionedcertificates "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/certificates/unversioned"
"k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/types"
certutil "k8s.io/kubernetes/pkg/util/cert" certutil "k8s.io/kubernetes/pkg/util/cert"
"k8s.io/kubernetes/pkg/watch" "k8s.io/kubernetes/pkg/watch"
) )
...@@ -33,7 +34,7 @@ import ( ...@@ -33,7 +34,7 @@ import (
// then it will watch the object's status, once approved by API server, it will return the API // then it will watch the object's status, once approved by API server, it will return the API
// server's issued certificate (pem-encoded). If there is any errors, or the watch timeouts, // server's issued certificate (pem-encoded). If there is any errors, or the watch timeouts,
// it will return an error. This is intended for use on nodes (kubelet and kubeadm). // it will return an error. This is intended for use on nodes (kubelet and kubeadm).
func RequestNodeCertificate(client unversionedcertificates.CertificateSigningRequestInterface, privateKeyData []byte, nodeName string) (certData []byte, err error) { func RequestNodeCertificate(client unversionedcertificates.CertificateSigningRequestInterface, privateKeyData []byte, nodeName types.NodeName) (certData []byte, err error) {
subject := &pkix.Name{ subject := &pkix.Name{
Organization: []string{"system:nodes"}, Organization: []string{"system:nodes"},
CommonName: fmt.Sprintf("system:node:%s", nodeName), CommonName: fmt.Sprintf("system:node:%s", nodeName),
......
...@@ -160,7 +160,7 @@ type AttachedVolume struct { ...@@ -160,7 +160,7 @@ type AttachedVolume struct {
// NewActualStateOfWorld returns a new instance of ActualStateOfWorld. // NewActualStateOfWorld returns a new instance of ActualStateOfWorld.
func NewActualStateOfWorld( func NewActualStateOfWorld(
nodeName string, nodeName types.NodeName,
volumePluginMgr *volume.VolumePluginMgr) ActualStateOfWorld { volumePluginMgr *volume.VolumePluginMgr) ActualStateOfWorld {
return &actualStateOfWorld{ return &actualStateOfWorld{
nodeName: nodeName, nodeName: nodeName,
...@@ -185,7 +185,7 @@ func IsRemountRequiredError(err error) bool { ...@@ -185,7 +185,7 @@ func IsRemountRequiredError(err error) bool {
type actualStateOfWorld struct { type actualStateOfWorld struct {
// nodeName is the name of this node. This value is passed to Attach/Detach // nodeName is the name of this node. This value is passed to Attach/Detach
nodeName string nodeName types.NodeName
// attachedVolumes is a map containing the set of volumes the kubelet volume // attachedVolumes is a map containing the set of volumes the kubelet volume
// manager believes to be successfully attached to this node. Volume types // manager believes to be successfully attached to this node. Volume types
// that do not implement an attacher interface are assumed to be in this // that do not implement an attacher interface are assumed to be in this
...@@ -271,12 +271,12 @@ type mountedPod struct { ...@@ -271,12 +271,12 @@ type mountedPod struct {
} }
func (asw *actualStateOfWorld) MarkVolumeAsAttached( func (asw *actualStateOfWorld) MarkVolumeAsAttached(
volumeName api.UniqueVolumeName, volumeSpec *volume.Spec, _, devicePath string) error { volumeName api.UniqueVolumeName, volumeSpec *volume.Spec, _ types.NodeName, devicePath string) error {
return asw.addVolume(volumeName, volumeSpec, devicePath) return asw.addVolume(volumeName, volumeSpec, devicePath)
} }
func (asw *actualStateOfWorld) MarkVolumeAsDetached( func (asw *actualStateOfWorld) MarkVolumeAsDetached(
volumeName api.UniqueVolumeName, nodeName string) { volumeName api.UniqueVolumeName, nodeName types.NodeName) {
asw.DeleteVolume(volumeName) asw.DeleteVolume(volumeName)
} }
...@@ -296,11 +296,11 @@ func (asw *actualStateOfWorld) MarkVolumeAsMounted( ...@@ -296,11 +296,11 @@ func (asw *actualStateOfWorld) MarkVolumeAsMounted(
volumeGidValue) volumeGidValue)
} }
func (asw *actualStateOfWorld) AddVolumeToReportAsAttached(volumeName api.UniqueVolumeName, nodeName string) { func (asw *actualStateOfWorld) AddVolumeToReportAsAttached(volumeName api.UniqueVolumeName, nodeName types.NodeName) {
// no operation for kubelet side // no operation for kubelet side
} }
func (asw *actualStateOfWorld) RemoveVolumeFromReportAsAttached(volumeName api.UniqueVolumeName, nodeName string) error { func (asw *actualStateOfWorld) RemoveVolumeFromReportAsAttached(volumeName api.UniqueVolumeName, nodeName types.NodeName) error {
// no operation for kubelet side // no operation for kubelet side
return nil return nil
} }
......
...@@ -71,7 +71,7 @@ type Reconciler interface { ...@@ -71,7 +71,7 @@ type Reconciler interface {
// successive executions // successive executions
// waitForAttachTimeout - the amount of time the Mount function will wait for // waitForAttachTimeout - the amount of time the Mount function will wait for
// the volume to be attached // the volume to be attached
// hostName - the hostname for this node, used by Attach and Detach methods // nodeName - the Name for this node, used by Attach and Detach methods
// desiredStateOfWorld - cache containing the desired state of the world // desiredStateOfWorld - cache containing the desired state of the world
// actualStateOfWorld - cache containing the actual state of the world // actualStateOfWorld - cache containing the actual state of the world
// operationExecutor - used to trigger attach/detach/mount/unmount operations // operationExecutor - used to trigger attach/detach/mount/unmount operations
...@@ -85,7 +85,7 @@ func NewReconciler( ...@@ -85,7 +85,7 @@ func NewReconciler(
loopSleepDuration time.Duration, loopSleepDuration time.Duration,
reconstructDuration time.Duration, reconstructDuration time.Duration,
waitForAttachTimeout time.Duration, waitForAttachTimeout time.Duration,
hostName string, nodeName types.NodeName,
desiredStateOfWorld cache.DesiredStateOfWorld, desiredStateOfWorld cache.DesiredStateOfWorld,
actualStateOfWorld cache.ActualStateOfWorld, actualStateOfWorld cache.ActualStateOfWorld,
operationExecutor operationexecutor.OperationExecutor, operationExecutor operationexecutor.OperationExecutor,
...@@ -98,7 +98,7 @@ func NewReconciler( ...@@ -98,7 +98,7 @@ func NewReconciler(
loopSleepDuration: loopSleepDuration, loopSleepDuration: loopSleepDuration,
reconstructDuration: reconstructDuration, reconstructDuration: reconstructDuration,
waitForAttachTimeout: waitForAttachTimeout, waitForAttachTimeout: waitForAttachTimeout,
hostName: hostName, nodeName: nodeName,
desiredStateOfWorld: desiredStateOfWorld, desiredStateOfWorld: desiredStateOfWorld,
actualStateOfWorld: actualStateOfWorld, actualStateOfWorld: actualStateOfWorld,
operationExecutor: operationExecutor, operationExecutor: operationExecutor,
...@@ -115,7 +115,7 @@ type reconciler struct { ...@@ -115,7 +115,7 @@ type reconciler struct {
loopSleepDuration time.Duration loopSleepDuration time.Duration
reconstructDuration time.Duration reconstructDuration time.Duration
waitForAttachTimeout time.Duration waitForAttachTimeout time.Duration
hostName string nodeName types.NodeName
desiredStateOfWorld cache.DesiredStateOfWorld desiredStateOfWorld cache.DesiredStateOfWorld
actualStateOfWorld cache.ActualStateOfWorld actualStateOfWorld cache.ActualStateOfWorld
operationExecutor operationexecutor.OperationExecutor operationExecutor operationexecutor.OperationExecutor
...@@ -201,7 +201,7 @@ func (rc *reconciler) reconcile() { ...@@ -201,7 +201,7 @@ func (rc *reconciler) reconcile() {
volumeToMount.Pod.UID) volumeToMount.Pod.UID)
err := rc.operationExecutor.VerifyControllerAttachedVolume( err := rc.operationExecutor.VerifyControllerAttachedVolume(
volumeToMount.VolumeToMount, volumeToMount.VolumeToMount,
rc.hostName, rc.nodeName,
rc.actualStateOfWorld) rc.actualStateOfWorld)
if err != nil && if err != nil &&
!nestedpendingoperations.IsAlreadyExists(err) && !nestedpendingoperations.IsAlreadyExists(err) &&
...@@ -230,7 +230,7 @@ func (rc *reconciler) reconcile() { ...@@ -230,7 +230,7 @@ func (rc *reconciler) reconcile() {
volumeToAttach := operationexecutor.VolumeToAttach{ volumeToAttach := operationexecutor.VolumeToAttach{
VolumeName: volumeToMount.VolumeName, VolumeName: volumeToMount.VolumeName,
VolumeSpec: volumeToMount.VolumeSpec, VolumeSpec: volumeToMount.VolumeSpec,
NodeName: rc.hostName, NodeName: rc.nodeName,
} }
glog.V(12).Infof("Attempting to start AttachVolume for volume %q (spec.Name: %q) pod %q (UID: %q)", glog.V(12).Infof("Attempting to start AttachVolume for volume %q (spec.Name: %q) pod %q (UID: %q)",
volumeToMount.VolumeName, volumeToMount.VolumeName,
...@@ -334,7 +334,7 @@ func (rc *reconciler) reconcile() { ...@@ -334,7 +334,7 @@ func (rc *reconciler) reconcile() {
// Kubelet not responsible for detaching or this volume has a non-attachable volume plugin, // Kubelet not responsible for detaching or this volume has a non-attachable volume plugin,
// so just remove it to actualStateOfWorld without attach. // so just remove it to actualStateOfWorld without attach.
rc.actualStateOfWorld.MarkVolumeAsDetached( rc.actualStateOfWorld.MarkVolumeAsDetached(
attachedVolume.VolumeName, rc.hostName) attachedVolume.VolumeName, rc.nodeName)
} else { } else {
// Only detach if kubelet detach is enabled // Only detach if kubelet detach is enabled
glog.V(12).Infof("Attempting to start DetachVolume for volume %q (spec.Name: %q)", glog.V(12).Infof("Attempting to start DetachVolume for volume %q (spec.Name: %q)",
......
...@@ -29,6 +29,7 @@ import ( ...@@ -29,6 +29,7 @@ import (
"k8s.io/kubernetes/pkg/kubelet/config" "k8s.io/kubernetes/pkg/kubelet/config"
"k8s.io/kubernetes/pkg/kubelet/volumemanager/cache" "k8s.io/kubernetes/pkg/kubelet/volumemanager/cache"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
k8stypes "k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/util/sets" "k8s.io/kubernetes/pkg/util/sets"
"k8s.io/kubernetes/pkg/util/wait" "k8s.io/kubernetes/pkg/util/wait"
...@@ -45,9 +46,9 @@ const ( ...@@ -45,9 +46,9 @@ const (
reconcilerReconstructSleepPeriod time.Duration = 10 * time.Minute reconcilerReconstructSleepPeriod time.Duration = 10 * time.Minute
// waitForAttachTimeout is the maximum amount of time a // waitForAttachTimeout is the maximum amount of time a
// operationexecutor.Mount call will wait for a volume to be attached. // operationexecutor.Mount call will wait for a volume to be attached.
waitForAttachTimeout time.Duration = 1 * time.Second waitForAttachTimeout time.Duration = 1 * time.Second
nodeName string = "myhostname" nodeName k8stypes.NodeName = k8stypes.NodeName("mynodename")
kubeletPodsDir string = "fake-dir" kubeletPodsDir string = "fake-dir"
) )
// Calls Run() // Calls Run()
...@@ -452,7 +453,7 @@ func createTestClient() *fake.Clientset { ...@@ -452,7 +453,7 @@ func createTestClient() *fake.Clientset {
fakeClient.AddReactor("get", "nodes", fakeClient.AddReactor("get", "nodes",
func(action core.Action) (bool, runtime.Object, error) { func(action core.Action) (bool, runtime.Object, error) {
return true, &api.Node{ return true, &api.Node{
ObjectMeta: api.ObjectMeta{Name: nodeName}, ObjectMeta: api.ObjectMeta{Name: string(nodeName)},
Status: api.NodeStatus{ Status: api.NodeStatus{
VolumesAttached: []api.AttachedVolume{ VolumesAttached: []api.AttachedVolume{
{ {
...@@ -460,7 +461,7 @@ func createTestClient() *fake.Clientset { ...@@ -460,7 +461,7 @@ func createTestClient() *fake.Clientset {
DevicePath: "fake/path", DevicePath: "fake/path",
}, },
}}, }},
Spec: api.NodeSpec{ExternalID: nodeName}, Spec: api.NodeSpec{ExternalID: string(nodeName)},
}, nil }, nil
}) })
fakeClient.AddReactor("*", "*", func(action core.Action) (bool, runtime.Object, error) { fakeClient.AddReactor("*", "*", func(action core.Action) (bool, runtime.Object, error) {
......
...@@ -33,6 +33,7 @@ import ( ...@@ -33,6 +33,7 @@ import (
"k8s.io/kubernetes/pkg/kubelet/volumemanager/cache" "k8s.io/kubernetes/pkg/kubelet/volumemanager/cache"
"k8s.io/kubernetes/pkg/kubelet/volumemanager/populator" "k8s.io/kubernetes/pkg/kubelet/volumemanager/populator"
"k8s.io/kubernetes/pkg/kubelet/volumemanager/reconciler" "k8s.io/kubernetes/pkg/kubelet/volumemanager/reconciler"
k8stypes "k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/util/runtime" "k8s.io/kubernetes/pkg/util/runtime"
"k8s.io/kubernetes/pkg/util/sets" "k8s.io/kubernetes/pkg/util/sets"
...@@ -143,7 +144,7 @@ type VolumeManager interface { ...@@ -143,7 +144,7 @@ type VolumeManager interface {
// Must be pre-initialized. // Must be pre-initialized.
func NewVolumeManager( func NewVolumeManager(
controllerAttachDetachEnabled bool, controllerAttachDetachEnabled bool,
hostName string, nodeName k8stypes.NodeName,
podManager pod.Manager, podManager pod.Manager,
kubeClient internalclientset.Interface, kubeClient internalclientset.Interface,
volumePluginMgr *volume.VolumePluginMgr, volumePluginMgr *volume.VolumePluginMgr,
...@@ -156,7 +157,7 @@ func NewVolumeManager( ...@@ -156,7 +157,7 @@ func NewVolumeManager(
kubeClient: kubeClient, kubeClient: kubeClient,
volumePluginMgr: volumePluginMgr, volumePluginMgr: volumePluginMgr,
desiredStateOfWorld: cache.NewDesiredStateOfWorld(volumePluginMgr), desiredStateOfWorld: cache.NewDesiredStateOfWorld(volumePluginMgr),
actualStateOfWorld: cache.NewActualStateOfWorld(hostName, volumePluginMgr), actualStateOfWorld: cache.NewActualStateOfWorld(nodeName, volumePluginMgr),
operationExecutor: operationexecutor.NewOperationExecutor( operationExecutor: operationexecutor.NewOperationExecutor(
kubeClient, kubeClient,
volumePluginMgr, volumePluginMgr,
...@@ -169,7 +170,7 @@ func NewVolumeManager( ...@@ -169,7 +170,7 @@ func NewVolumeManager(
reconcilerLoopSleepPeriod, reconcilerLoopSleepPeriod,
reconcilerReconstructSleepPeriod, reconcilerReconstructSleepPeriod,
waitForAttachTimeout, waitForAttachTimeout,
hostName, nodeName,
vm.desiredStateOfWorld, vm.desiredStateOfWorld,
vm.actualStateOfWorld, vm.actualStateOfWorld,
vm.operationExecutor, vm.operationExecutor,
......
/*
Copyright 2015 The Kubernetes Authors.
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 types
// NodeName is a type that holds a api.Node's Name identifier.
// Being a type captures intent and helps make sure that the node name
// is not confused with similar concepts (the hostname, the cloud provider id,
// the cloud provider name etc)
//
// To clarify the various types:
//
// * Node.Name is the Name field of the Node in the API. This should be stored in a NodeName.
// Unfortunately, because Name is part of ObjectMeta, we can't store it as a NodeName at the API level.
//
// * Hostname is the hostname of the local machine (from uname -n).
// However, some components allow the user to pass in a --hostname-override flag,
// which will override this in most places. In the absence of anything more meaningful,
// kubelet will use Hostname as the Node.Name when it creates the Node.
//
// * The cloudproviders have the own names: GCE has InstanceName, AWS has InstanceId.
//
// For GCE, InstanceName is the Name of an Instance object in the GCE API. On GCE, Instance.Name becomes the
// Hostname, and thus it makes sense also to use it as the Node.Name. But that is GCE specific, and it is up
// to the cloudprovider how to do this mapping.
//
// For AWS, the InstanceID is not yet suitable for use as a Node.Name, so we actually use the
// PrivateDnsName for the Node.Name. And this is _not_ always the same as the hostname: if
// we are using a custom DHCP domain it won't be.
type NodeName string
...@@ -28,6 +28,7 @@ import ( ...@@ -28,6 +28,7 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/unversioned"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/types"
) )
func GetHostname(hostnameOverride string) string { func GetHostname(hostnameOverride string) string {
...@@ -86,7 +87,7 @@ func GetZoneKey(node *api.Node) string { ...@@ -86,7 +87,7 @@ func GetZoneKey(node *api.Node) string {
} }
// SetNodeCondition updates specific node condition with patch operation. // SetNodeCondition updates specific node condition with patch operation.
func SetNodeCondition(c clientset.Interface, node string, condition api.NodeCondition) error { func SetNodeCondition(c clientset.Interface, node types.NodeName, condition api.NodeCondition) error {
generatePatch := func(condition api.NodeCondition) ([]byte, error) { generatePatch := func(condition api.NodeCondition) ([]byte, error) {
raw, err := json.Marshal(&[]api.NodeCondition{condition}) raw, err := json.Marshal(&[]api.NodeCondition{condition})
if err != nil { if err != nil {
...@@ -99,6 +100,6 @@ func SetNodeCondition(c clientset.Interface, node string, condition api.NodeCond ...@@ -99,6 +100,6 @@ func SetNodeCondition(c clientset.Interface, node string, condition api.NodeCond
if err != nil { if err != nil {
return nil return nil
} }
_, err = c.Core().Nodes().PatchStatus(node, patch) _, err = c.Core().Nodes().PatchStatus(string(node), patch)
return err return err
} }
...@@ -25,6 +25,7 @@ import ( ...@@ -25,6 +25,7 @@ import (
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kubernetes/pkg/cloudprovider/providers/aws" "k8s.io/kubernetes/pkg/cloudprovider/providers/aws"
"k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/util/exec" "k8s.io/kubernetes/pkg/util/exec"
"k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
...@@ -57,7 +58,7 @@ func (plugin *awsElasticBlockStorePlugin) GetDeviceMountRefs(deviceMountPath str ...@@ -57,7 +58,7 @@ func (plugin *awsElasticBlockStorePlugin) GetDeviceMountRefs(deviceMountPath str
return mount.GetMountRefs(mounter, deviceMountPath) return mount.GetMountRefs(mounter, deviceMountPath)
} }
func (attacher *awsElasticBlockStoreAttacher) Attach(spec *volume.Spec, hostName string) (string, error) { func (attacher *awsElasticBlockStoreAttacher) Attach(spec *volume.Spec, nodeName types.NodeName) (string, error) {
volumeSource, readOnly, err := getVolumeSource(spec) volumeSource, readOnly, err := getVolumeSource(spec)
if err != nil { if err != nil {
return "", err return "", err
...@@ -67,7 +68,7 @@ func (attacher *awsElasticBlockStoreAttacher) Attach(spec *volume.Spec, hostName ...@@ -67,7 +68,7 @@ func (attacher *awsElasticBlockStoreAttacher) Attach(spec *volume.Spec, hostName
// awsCloud.AttachDisk checks if disk is already attached to node and // awsCloud.AttachDisk checks if disk is already attached to node and
// succeeds in that case, so no need to do that separately. // succeeds in that case, so no need to do that separately.
devicePath, err := attacher.awsVolumes.AttachDisk(volumeID, hostName, readOnly) devicePath, err := attacher.awsVolumes.AttachDisk(volumeID, nodeName, readOnly)
if err != nil { if err != nil {
glog.Errorf("Error attaching volume %q: %+v", volumeID, err) glog.Errorf("Error attaching volume %q: %+v", volumeID, err)
return "", err return "", err
...@@ -185,24 +186,24 @@ func (plugin *awsElasticBlockStorePlugin) NewDetacher() (volume.Detacher, error) ...@@ -185,24 +186,24 @@ func (plugin *awsElasticBlockStorePlugin) NewDetacher() (volume.Detacher, error)
}, nil }, nil
} }
func (detacher *awsElasticBlockStoreDetacher) Detach(deviceMountPath string, hostName string) error { func (detacher *awsElasticBlockStoreDetacher) Detach(deviceMountPath string, nodeName types.NodeName) error {
volumeID := path.Base(deviceMountPath) volumeID := path.Base(deviceMountPath)
attached, err := detacher.awsVolumes.DiskIsAttached(volumeID, hostName) attached, err := detacher.awsVolumes.DiskIsAttached(volumeID, nodeName)
if err != nil { if err != nil {
// Log error and continue with detach // Log error and continue with detach
glog.Errorf( glog.Errorf(
"Error checking if volume (%q) is already attached to current node (%q). Will continue and try detach anyway. err=%v", "Error checking if volume (%q) is already attached to current node (%q). Will continue and try detach anyway. err=%v",
volumeID, hostName, err) volumeID, nodeName, err)
} }
if err == nil && !attached { if err == nil && !attached {
// Volume is already detached from node. // Volume is already detached from node.
glog.Infof("detach operation was successful. volume %q is already detached from node %q.", volumeID, hostName) glog.Infof("detach operation was successful. volume %q is already detached from node %q.", volumeID, nodeName)
return nil return nil
} }
if _, err = detacher.awsVolumes.DetachDisk(volumeID, hostName); err != nil { if _, err = detacher.awsVolumes.DetachDisk(volumeID, nodeName); err != nil {
glog.Errorf("Error detaching volumeID %q: %v", volumeID, err) glog.Errorf("Error detaching volumeID %q: %v", volumeID, err)
return err return err
} }
......
...@@ -26,6 +26,7 @@ import ( ...@@ -26,6 +26,7 @@ import (
volumetest "k8s.io/kubernetes/pkg/volume/testing" volumetest "k8s.io/kubernetes/pkg/volume/testing"
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kubernetes/pkg/types"
) )
func TestGetDeviceName_Volume(t *testing.T) { func TestGetDeviceName_Volume(t *testing.T) {
...@@ -74,7 +75,7 @@ type testcase struct { ...@@ -74,7 +75,7 @@ type testcase struct {
func TestAttachDetach(t *testing.T) { func TestAttachDetach(t *testing.T) {
diskName := "disk" diskName := "disk"
instanceID := "instance" nodeName := types.NodeName("instance")
readOnly := false readOnly := false
spec := createVolSpec(diskName, readOnly) spec := createVolSpec(diskName, readOnly)
attachError := errors.New("Fake attach error") attachError := errors.New("Fake attach error")
...@@ -84,10 +85,10 @@ func TestAttachDetach(t *testing.T) { ...@@ -84,10 +85,10 @@ func TestAttachDetach(t *testing.T) {
// Successful Attach call // Successful Attach call
{ {
name: "Attach_Positive", name: "Attach_Positive",
attach: attachCall{diskName, instanceID, readOnly, "/dev/sda", nil}, attach: attachCall{diskName, nodeName, readOnly, "/dev/sda", nil},
test: func(testcase *testcase) (string, error) { test: func(testcase *testcase) (string, error) {
attacher := newAttacher(testcase) attacher := newAttacher(testcase)
return attacher.Attach(spec, instanceID) return attacher.Attach(spec, nodeName)
}, },
expectedDevice: "/dev/sda", expectedDevice: "/dev/sda",
}, },
...@@ -95,10 +96,10 @@ func TestAttachDetach(t *testing.T) { ...@@ -95,10 +96,10 @@ func TestAttachDetach(t *testing.T) {
// Attach call fails // Attach call fails
{ {
name: "Attach_Negative", name: "Attach_Negative",
attach: attachCall{diskName, instanceID, readOnly, "", attachError}, attach: attachCall{diskName, nodeName, readOnly, "", attachError},
test: func(testcase *testcase) (string, error) { test: func(testcase *testcase) (string, error) {
attacher := newAttacher(testcase) attacher := newAttacher(testcase)
return attacher.Attach(spec, instanceID) return attacher.Attach(spec, nodeName)
}, },
expectedError: attachError, expectedError: attachError,
}, },
...@@ -106,43 +107,43 @@ func TestAttachDetach(t *testing.T) { ...@@ -106,43 +107,43 @@ func TestAttachDetach(t *testing.T) {
// Detach succeeds // Detach succeeds
{ {
name: "Detach_Positive", name: "Detach_Positive",
diskIsAttached: diskIsAttachedCall{diskName, instanceID, true, nil}, diskIsAttached: diskIsAttachedCall{diskName, nodeName, true, nil},
detach: detachCall{diskName, instanceID, "/dev/sda", nil}, detach: detachCall{diskName, nodeName, "/dev/sda", nil},
test: func(testcase *testcase) (string, error) { test: func(testcase *testcase) (string, error) {
detacher := newDetacher(testcase) detacher := newDetacher(testcase)
return "", detacher.Detach(diskName, instanceID) return "", detacher.Detach(diskName, nodeName)
}, },
}, },
// Disk is already detached // Disk is already detached
{ {
name: "Detach_Positive_AlreadyDetached", name: "Detach_Positive_AlreadyDetached",
diskIsAttached: diskIsAttachedCall{diskName, instanceID, false, nil}, diskIsAttached: diskIsAttachedCall{diskName, nodeName, false, nil},
test: func(testcase *testcase) (string, error) { test: func(testcase *testcase) (string, error) {
detacher := newDetacher(testcase) detacher := newDetacher(testcase)
return "", detacher.Detach(diskName, instanceID) return "", detacher.Detach(diskName, nodeName)
}, },
}, },
// Detach succeeds when DiskIsAttached fails // Detach succeeds when DiskIsAttached fails
{ {
name: "Detach_Positive_CheckFails", name: "Detach_Positive_CheckFails",
diskIsAttached: diskIsAttachedCall{diskName, instanceID, false, diskCheckError}, diskIsAttached: diskIsAttachedCall{diskName, nodeName, false, diskCheckError},
detach: detachCall{diskName, instanceID, "/dev/sda", nil}, detach: detachCall{diskName, nodeName, "/dev/sda", nil},
test: func(testcase *testcase) (string, error) { test: func(testcase *testcase) (string, error) {
detacher := newDetacher(testcase) detacher := newDetacher(testcase)
return "", detacher.Detach(diskName, instanceID) return "", detacher.Detach(diskName, nodeName)
}, },
}, },
// Detach fails // Detach fails
{ {
name: "Detach_Negative", name: "Detach_Negative",
diskIsAttached: diskIsAttachedCall{diskName, instanceID, false, diskCheckError}, diskIsAttached: diskIsAttachedCall{diskName, nodeName, false, diskCheckError},
detach: detachCall{diskName, instanceID, "", detachError}, detach: detachCall{diskName, nodeName, "", detachError},
test: func(testcase *testcase) (string, error) { test: func(testcase *testcase) (string, error) {
detacher := newDetacher(testcase) detacher := newDetacher(testcase)
return "", detacher.Detach(diskName, instanceID) return "", detacher.Detach(diskName, nodeName)
}, },
expectedError: detachError, expectedError: detachError,
}, },
...@@ -216,7 +217,7 @@ func createPVSpec(name string, readOnly bool) *volume.Spec { ...@@ -216,7 +217,7 @@ func createPVSpec(name string, readOnly bool) *volume.Spec {
type attachCall struct { type attachCall struct {
diskName string diskName string
instanceID string nodeName types.NodeName
readOnly bool readOnly bool
retDeviceName string retDeviceName string
ret error ret error
...@@ -224,21 +225,22 @@ type attachCall struct { ...@@ -224,21 +225,22 @@ type attachCall struct {
type detachCall struct { type detachCall struct {
diskName string diskName string
instanceID string nodeName types.NodeName
retDeviceName string retDeviceName string
ret error ret error
} }
type diskIsAttachedCall struct { type diskIsAttachedCall struct {
diskName, instanceID string diskName string
isAttached bool nodeName types.NodeName
ret error isAttached bool
ret error
} }
func (testcase *testcase) AttachDisk(diskName string, instanceID string, readOnly bool) (string, error) { func (testcase *testcase) AttachDisk(diskName string, nodeName types.NodeName, readOnly bool) (string, error) {
expected := &testcase.attach expected := &testcase.attach
if expected.diskName == "" && expected.instanceID == "" { if expected.diskName == "" && expected.nodeName == "" {
// testcase.attach looks uninitialized, test did not expect to call // testcase.attach looks uninitialized, test did not expect to call
// AttachDisk // AttachDisk
testcase.t.Errorf("Unexpected AttachDisk call!") testcase.t.Errorf("Unexpected AttachDisk call!")
...@@ -250,9 +252,9 @@ func (testcase *testcase) AttachDisk(diskName string, instanceID string, readOnl ...@@ -250,9 +252,9 @@ func (testcase *testcase) AttachDisk(diskName string, instanceID string, readOnl
return "", errors.New("Unexpected AttachDisk call: wrong diskName") return "", errors.New("Unexpected AttachDisk call: wrong diskName")
} }
if expected.instanceID != instanceID { if expected.nodeName != nodeName {
testcase.t.Errorf("Unexpected AttachDisk call: expected instanceID %s, got %s", expected.instanceID, instanceID) testcase.t.Errorf("Unexpected AttachDisk call: expected nodeName %s, got %s", expected.nodeName, nodeName)
return "", errors.New("Unexpected AttachDisk call: wrong instanceID") return "", errors.New("Unexpected AttachDisk call: wrong nodeName")
} }
if expected.readOnly != readOnly { if expected.readOnly != readOnly {
...@@ -260,15 +262,15 @@ func (testcase *testcase) AttachDisk(diskName string, instanceID string, readOnl ...@@ -260,15 +262,15 @@ func (testcase *testcase) AttachDisk(diskName string, instanceID string, readOnl
return "", errors.New("Unexpected AttachDisk call: wrong readOnly") return "", errors.New("Unexpected AttachDisk call: wrong readOnly")
} }
glog.V(4).Infof("AttachDisk call: %s, %s, %v, returning %q, %v", diskName, instanceID, readOnly, expected.retDeviceName, expected.ret) glog.V(4).Infof("AttachDisk call: %s, %s, %v, returning %q, %v", diskName, nodeName, readOnly, expected.retDeviceName, expected.ret)
return expected.retDeviceName, expected.ret return expected.retDeviceName, expected.ret
} }
func (testcase *testcase) DetachDisk(diskName string, instanceID string) (string, error) { func (testcase *testcase) DetachDisk(diskName string, nodeName types.NodeName) (string, error) {
expected := &testcase.detach expected := &testcase.detach
if expected.diskName == "" && expected.instanceID == "" { if expected.diskName == "" && expected.nodeName == "" {
// testcase.detach looks uninitialized, test did not expect to call // testcase.detach looks uninitialized, test did not expect to call
// DetachDisk // DetachDisk
testcase.t.Errorf("Unexpected DetachDisk call!") testcase.t.Errorf("Unexpected DetachDisk call!")
...@@ -280,20 +282,20 @@ func (testcase *testcase) DetachDisk(diskName string, instanceID string) (string ...@@ -280,20 +282,20 @@ func (testcase *testcase) DetachDisk(diskName string, instanceID string) (string
return "", errors.New("Unexpected DetachDisk call: wrong diskName") return "", errors.New("Unexpected DetachDisk call: wrong diskName")
} }
if expected.instanceID != instanceID { if expected.nodeName != nodeName {
testcase.t.Errorf("Unexpected DetachDisk call: expected instanceID %s, got %s", expected.instanceID, instanceID) testcase.t.Errorf("Unexpected DetachDisk call: expected nodeName %s, got %s", expected.nodeName, nodeName)
return "", errors.New("Unexpected DetachDisk call: wrong instanceID") return "", errors.New("Unexpected DetachDisk call: wrong nodeName")
} }
glog.V(4).Infof("DetachDisk call: %s, %s, returning %q, %v", diskName, instanceID, expected.retDeviceName, expected.ret) glog.V(4).Infof("DetachDisk call: %s, %s, returning %q, %v", diskName, nodeName, expected.retDeviceName, expected.ret)
return expected.retDeviceName, expected.ret return expected.retDeviceName, expected.ret
} }
func (testcase *testcase) DiskIsAttached(diskName, instanceID string) (bool, error) { func (testcase *testcase) DiskIsAttached(diskName string, nodeName types.NodeName) (bool, error) {
expected := &testcase.diskIsAttached expected := &testcase.diskIsAttached
if expected.diskName == "" && expected.instanceID == "" { if expected.diskName == "" && expected.nodeName == "" {
// testcase.diskIsAttached looks uninitialized, test did not expect to // testcase.diskIsAttached looks uninitialized, test did not expect to
// call DiskIsAttached // call DiskIsAttached
testcase.t.Errorf("Unexpected DiskIsAttached call!") testcase.t.Errorf("Unexpected DiskIsAttached call!")
...@@ -305,12 +307,12 @@ func (testcase *testcase) DiskIsAttached(diskName, instanceID string) (bool, err ...@@ -305,12 +307,12 @@ func (testcase *testcase) DiskIsAttached(diskName, instanceID string) (bool, err
return false, errors.New("Unexpected DiskIsAttached call: wrong diskName") return false, errors.New("Unexpected DiskIsAttached call: wrong diskName")
} }
if expected.instanceID != instanceID { if expected.nodeName != nodeName {
testcase.t.Errorf("Unexpected DiskIsAttached call: expected instanceID %s, got %s", expected.instanceID, instanceID) testcase.t.Errorf("Unexpected DiskIsAttached call: expected nodeName %s, got %s", expected.nodeName, nodeName)
return false, errors.New("Unexpected DiskIsAttached call: wrong instanceID") return false, errors.New("Unexpected DiskIsAttached call: wrong nodeName")
} }
glog.V(4).Infof("DiskIsAttached call: %s, %s, returning %v, %v", diskName, instanceID, expected.isAttached, expected.ret) glog.V(4).Infof("DiskIsAttached call: %s, %s, returning %v, %v", diskName, nodeName, expected.isAttached, expected.ret)
return expected.isAttached, expected.ret return expected.isAttached, expected.ret
} }
......
...@@ -27,6 +27,7 @@ import ( ...@@ -27,6 +27,7 @@ import (
"github.com/Azure/azure-sdk-for-go/arm/compute" "github.com/Azure/azure-sdk-for-go/arm/compute"
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kubernetes/pkg/cloudprovider" "k8s.io/kubernetes/pkg/cloudprovider"
"k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/util/exec" "k8s.io/kubernetes/pkg/util/exec"
"k8s.io/kubernetes/pkg/util/keymutex" "k8s.io/kubernetes/pkg/util/keymutex"
"k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/mount"
...@@ -65,23 +66,23 @@ func (plugin *azureDataDiskPlugin) NewAttacher() (volume.Attacher, error) { ...@@ -65,23 +66,23 @@ func (plugin *azureDataDiskPlugin) NewAttacher() (volume.Attacher, error) {
}, nil }, nil
} }
// Attach attaches a volume.Spec to a Azure VM referenced by hostname, returning the disk's LUN // Attach attaches a volume.Spec to a Azure VM referenced by NodeName, returning the disk's LUN
func (attacher *azureDiskAttacher) Attach(spec *volume.Spec, hostName string) (string, error) { func (attacher *azureDiskAttacher) Attach(spec *volume.Spec, nodeName types.NodeName) (string, error) {
volumeSource, err := getVolumeSource(spec) volumeSource, err := getVolumeSource(spec)
if err != nil { if err != nil {
glog.Warningf("failed to get azure disk spec") glog.Warningf("failed to get azure disk spec")
return "", err return "", err
} }
instanceid, err := attacher.azureProvider.InstanceID(hostName) instanceid, err := attacher.azureProvider.InstanceID(nodeName)
if err != nil { if err != nil {
glog.Warningf("failed to get azure instance id") glog.Warningf("failed to get azure instance id")
return "", fmt.Errorf("failed to get azure instance id for host %q", hostName) return "", fmt.Errorf("failed to get azure instance id for node %q", nodeName)
} }
if ind := strings.LastIndex(instanceid, "/"); ind >= 0 { if ind := strings.LastIndex(instanceid, "/"); ind >= 0 {
instanceid = instanceid[(ind + 1):] instanceid = instanceid[(ind + 1):]
} }
lun, err := attacher.azureProvider.GetDiskLun(volumeSource.DiskName, volumeSource.DataDiskURI, instanceid) lun, err := attacher.azureProvider.GetDiskLun(volumeSource.DiskName, volumeSource.DataDiskURI, nodeName)
if err == cloudprovider.InstanceNotFound { if err == cloudprovider.InstanceNotFound {
// Log error and continue with attach // Log error and continue with attach
glog.Warningf( glog.Warningf(
...@@ -96,15 +97,15 @@ func (attacher *azureDiskAttacher) Attach(spec *volume.Spec, hostName string) (s ...@@ -96,15 +97,15 @@ func (attacher *azureDiskAttacher) Attach(spec *volume.Spec, hostName string) (s
getLunMutex.LockKey(instanceid) getLunMutex.LockKey(instanceid)
defer getLunMutex.UnlockKey(instanceid) defer getLunMutex.UnlockKey(instanceid)
lun, err = attacher.azureProvider.GetNextDiskLun(instanceid) lun, err = attacher.azureProvider.GetNextDiskLun(nodeName)
if err != nil { if err != nil {
glog.Warningf("no LUN available for instance %q", instanceid) glog.Warningf("no LUN available for instance %q", nodeName)
return "", fmt.Errorf("all LUNs are used, cannot attach volume %q to instance %q", volumeSource.DiskName, instanceid) return "", fmt.Errorf("all LUNs are used, cannot attach volume %q to instance %q", volumeSource.DiskName, instanceid)
} }
err = attacher.azureProvider.AttachDisk(volumeSource.DiskName, volumeSource.DataDiskURI, instanceid, lun, compute.CachingTypes(*volumeSource.CachingMode)) err = attacher.azureProvider.AttachDisk(volumeSource.DiskName, volumeSource.DataDiskURI, nodeName, lun, compute.CachingTypes(*volumeSource.CachingMode))
if err == nil { if err == nil {
glog.V(4).Infof("Attach operation successful: volume %q attached to node %q.", volumeSource.DataDiskURI, instanceid) glog.V(4).Infof("Attach operation successful: volume %q attached to node %q.", volumeSource.DataDiskURI, nodeName)
} else { } else {
glog.V(2).Infof("Attach volume %q to instance %q failed with %v", volumeSource.DataDiskURI, instanceid, err) glog.V(2).Infof("Attach volume %q to instance %q failed with %v", volumeSource.DataDiskURI, instanceid, err)
return "", fmt.Errorf("Attach volume %q to instance %q failed with %v", volumeSource.DiskName, instanceid, err) return "", fmt.Errorf("Attach volume %q to instance %q failed with %v", volumeSource.DiskName, instanceid, err)
...@@ -213,21 +214,21 @@ func (plugin *azureDataDiskPlugin) NewDetacher() (volume.Detacher, error) { ...@@ -213,21 +214,21 @@ func (plugin *azureDataDiskPlugin) NewDetacher() (volume.Detacher, error) {
} }
// Detach detaches disk from Azure VM. // Detach detaches disk from Azure VM.
func (detacher *azureDiskDetacher) Detach(diskName string, hostName string) error { func (detacher *azureDiskDetacher) Detach(diskName string, nodeName types.NodeName) error {
if diskName == "" { if diskName == "" {
return fmt.Errorf("invalid disk to detach: %q", diskName) return fmt.Errorf("invalid disk to detach: %q", diskName)
} }
instanceid, err := detacher.azureProvider.InstanceID(hostName) instanceid, err := detacher.azureProvider.InstanceID(nodeName)
if err != nil { if err != nil {
glog.Warningf("no instance id for host %q, skip detaching", hostName) glog.Warningf("no instance id for node %q, skip detaching", nodeName)
return nil return nil
} }
if ind := strings.LastIndex(instanceid, "/"); ind >= 0 { if ind := strings.LastIndex(instanceid, "/"); ind >= 0 {
instanceid = instanceid[(ind + 1):] instanceid = instanceid[(ind + 1):]
} }
glog.V(4).Infof("detach %v from host %q", diskName, instanceid) glog.V(4).Infof("detach %v from node %q", diskName, nodeName)
err = detacher.azureProvider.DetachDiskByName(diskName, "" /* diskURI */, instanceid) err = detacher.azureProvider.DetachDiskByName(diskName, "" /* diskURI */, nodeName)
if err != nil { if err != nil {
glog.Errorf("failed to detach azure disk %q, err %v", diskName, err) glog.Errorf("failed to detach azure disk %q, err %v", diskName, err)
} }
......
...@@ -50,15 +50,15 @@ type azureDataDiskPlugin struct { ...@@ -50,15 +50,15 @@ type azureDataDiskPlugin struct {
// azure cloud provider should implement it // azure cloud provider should implement it
type azureCloudProvider interface { type azureCloudProvider interface {
// Attaches the disk to the host machine. // Attaches the disk to the host machine.
AttachDisk(diskName, diskUri, vmName string, lun int32, cachingMode compute.CachingTypes) error AttachDisk(diskName, diskUri string, nodeName types.NodeName, lun int32, cachingMode compute.CachingTypes) error
// Detaches the disk, identified by disk name or uri, from the host machine. // Detaches the disk, identified by disk name or uri, from the host machine.
DetachDiskByName(diskName, diskUri, vmName string) error DetachDiskByName(diskName, diskUri string, nodeName types.NodeName) error
// Get the LUN number of the disk that is attached to the host // Get the LUN number of the disk that is attached to the host
GetDiskLun(diskName, diskUri, vmName string) (int32, error) GetDiskLun(diskName, diskUri string, nodeName types.NodeName) (int32, error)
// Get the next available LUN number to attach a new VHD // Get the next available LUN number to attach a new VHD
GetNextDiskLun(vmName string) (int32, error) GetNextDiskLun(nodeName types.NodeName) (int32, error)
// InstanceID returns the cloud provider ID of the specified instance. // InstanceID returns the cloud provider ID of the specified instance.
InstanceID(name string) (string, error) InstanceID(nodeName types.NodeName) (string, error)
} }
var _ volume.VolumePlugin = &azureDataDiskPlugin{} var _ volume.VolumePlugin = &azureDataDiskPlugin{}
......
...@@ -24,6 +24,7 @@ import ( ...@@ -24,6 +24,7 @@ import (
"time" "time"
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/util/exec" "k8s.io/kubernetes/pkg/util/exec"
"k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
...@@ -59,7 +60,7 @@ func (plugin *cinderPlugin) GetDeviceMountRefs(deviceMountPath string) ([]string ...@@ -59,7 +60,7 @@ func (plugin *cinderPlugin) GetDeviceMountRefs(deviceMountPath string) ([]string
return mount.GetMountRefs(mounter, deviceMountPath) return mount.GetMountRefs(mounter, deviceMountPath)
} }
func (attacher *cinderDiskAttacher) Attach(spec *volume.Spec, hostName string) (string, error) { func (attacher *cinderDiskAttacher) Attach(spec *volume.Spec, nodeName types.NodeName) (string, error) {
volumeSource, _, err := getVolumeSource(spec) volumeSource, _, err := getVolumeSource(spec)
if err != nil { if err != nil {
return "", err return "", err
...@@ -71,7 +72,7 @@ func (attacher *cinderDiskAttacher) Attach(spec *volume.Spec, hostName string) ( ...@@ -71,7 +72,7 @@ func (attacher *cinderDiskAttacher) Attach(spec *volume.Spec, hostName string) (
if !res { if !res {
return "", fmt.Errorf("failed to list openstack instances") return "", fmt.Errorf("failed to list openstack instances")
} }
instanceid, err := instances.InstanceID(hostName) instanceid, err := instances.InstanceID(nodeName)
if err != nil { if err != nil {
return "", err return "", err
} }
...@@ -208,13 +209,13 @@ func (plugin *cinderPlugin) NewDetacher() (volume.Detacher, error) { ...@@ -208,13 +209,13 @@ func (plugin *cinderPlugin) NewDetacher() (volume.Detacher, error) {
}, nil }, nil
} }
func (detacher *cinderDiskDetacher) Detach(deviceMountPath string, hostName string) error { func (detacher *cinderDiskDetacher) Detach(deviceMountPath string, nodeName types.NodeName) error {
volumeID := path.Base(deviceMountPath) volumeID := path.Base(deviceMountPath)
instances, res := detacher.cinderProvider.Instances() instances, res := detacher.cinderProvider.Instances()
if !res { if !res {
return fmt.Errorf("failed to list openstack instances") return fmt.Errorf("failed to list openstack instances")
} }
instanceid, err := instances.InstanceID(hostName) instanceid, err := instances.InstanceID(nodeName)
if ind := strings.LastIndex(instanceid, "/"); ind >= 0 { if ind := strings.LastIndex(instanceid, "/"); ind >= 0 {
instanceid = instanceid[(ind + 1):] instanceid = instanceid[(ind + 1):]
} }
...@@ -224,12 +225,12 @@ func (detacher *cinderDiskDetacher) Detach(deviceMountPath string, hostName stri ...@@ -224,12 +225,12 @@ func (detacher *cinderDiskDetacher) Detach(deviceMountPath string, hostName stri
// Log error and continue with detach // Log error and continue with detach
glog.Errorf( glog.Errorf(
"Error checking if volume (%q) is already attached to current node (%q). Will continue and try detach anyway. err=%v", "Error checking if volume (%q) is already attached to current node (%q). Will continue and try detach anyway. err=%v",
volumeID, hostName, err) volumeID, nodeName, err)
} }
if err == nil && !attached { if err == nil && !attached {
// Volume is already detached from node. // Volume is already detached from node.
glog.Infof("detach operation was successful. volume %q is already detached from node %q.", volumeID, hostName) glog.Infof("detach operation was successful. volume %q is already detached from node %q.", volumeID, nodeName)
return nil return nil
} }
......
...@@ -26,6 +26,7 @@ import ( ...@@ -26,6 +26,7 @@ import (
volumetest "k8s.io/kubernetes/pkg/volume/testing" volumetest "k8s.io/kubernetes/pkg/volume/testing"
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kubernetes/pkg/types"
) )
func TestGetDeviceName_Volume(t *testing.T) { func TestGetDeviceName_Volume(t *testing.T) {
...@@ -77,6 +78,7 @@ type testcase struct { ...@@ -77,6 +78,7 @@ type testcase struct {
func TestAttachDetach(t *testing.T) { func TestAttachDetach(t *testing.T) {
diskName := "disk" diskName := "disk"
instanceID := "instance" instanceID := "instance"
nodeName := types.NodeName(instanceID)
readOnly := false readOnly := false
spec := createVolSpec(diskName, readOnly) spec := createVolSpec(diskName, readOnly)
attachError := errors.New("Fake attach error") attachError := errors.New("Fake attach error")
...@@ -93,7 +95,7 @@ func TestAttachDetach(t *testing.T) { ...@@ -93,7 +95,7 @@ func TestAttachDetach(t *testing.T) {
diskPath: diskPathCall{diskName, instanceID, "/dev/sda", nil}, diskPath: diskPathCall{diskName, instanceID, "/dev/sda", nil},
test: func(testcase *testcase) (string, error) { test: func(testcase *testcase) (string, error) {
attacher := newAttacher(testcase) attacher := newAttacher(testcase)
return attacher.Attach(spec, instanceID) return attacher.Attach(spec, nodeName)
}, },
expectedDevice: "/dev/sda", expectedDevice: "/dev/sda",
}, },
...@@ -106,7 +108,7 @@ func TestAttachDetach(t *testing.T) { ...@@ -106,7 +108,7 @@ func TestAttachDetach(t *testing.T) {
diskPath: diskPathCall{diskName, instanceID, "/dev/sda", nil}, diskPath: diskPathCall{diskName, instanceID, "/dev/sda", nil},
test: func(testcase *testcase) (string, error) { test: func(testcase *testcase) (string, error) {
attacher := newAttacher(testcase) attacher := newAttacher(testcase)
return attacher.Attach(spec, instanceID) return attacher.Attach(spec, nodeName)
}, },
expectedDevice: "/dev/sda", expectedDevice: "/dev/sda",
}, },
...@@ -120,7 +122,7 @@ func TestAttachDetach(t *testing.T) { ...@@ -120,7 +122,7 @@ func TestAttachDetach(t *testing.T) {
diskPath: diskPathCall{diskName, instanceID, "/dev/sda", nil}, diskPath: diskPathCall{diskName, instanceID, "/dev/sda", nil},
test: func(testcase *testcase) (string, error) { test: func(testcase *testcase) (string, error) {
attacher := newAttacher(testcase) attacher := newAttacher(testcase)
return attacher.Attach(spec, instanceID) return attacher.Attach(spec, nodeName)
}, },
expectedDevice: "/dev/sda", expectedDevice: "/dev/sda",
}, },
...@@ -133,7 +135,7 @@ func TestAttachDetach(t *testing.T) { ...@@ -133,7 +135,7 @@ func TestAttachDetach(t *testing.T) {
attach: attachCall{diskName, instanceID, "/dev/sda", attachError}, attach: attachCall{diskName, instanceID, "/dev/sda", attachError},
test: func(testcase *testcase) (string, error) { test: func(testcase *testcase) (string, error) {
attacher := newAttacher(testcase) attacher := newAttacher(testcase)
return attacher.Attach(spec, instanceID) return attacher.Attach(spec, nodeName)
}, },
expectedError: attachError, expectedError: attachError,
}, },
...@@ -147,7 +149,7 @@ func TestAttachDetach(t *testing.T) { ...@@ -147,7 +149,7 @@ func TestAttachDetach(t *testing.T) {
diskPath: diskPathCall{diskName, instanceID, "", diskPathError}, diskPath: diskPathCall{diskName, instanceID, "", diskPathError},
test: func(testcase *testcase) (string, error) { test: func(testcase *testcase) (string, error) {
attacher := newAttacher(testcase) attacher := newAttacher(testcase)
return attacher.Attach(spec, instanceID) return attacher.Attach(spec, nodeName)
}, },
expectedError: diskPathError, expectedError: diskPathError,
}, },
...@@ -160,7 +162,7 @@ func TestAttachDetach(t *testing.T) { ...@@ -160,7 +162,7 @@ func TestAttachDetach(t *testing.T) {
detach: detachCall{diskName, instanceID, nil}, detach: detachCall{diskName, instanceID, nil},
test: func(testcase *testcase) (string, error) { test: func(testcase *testcase) (string, error) {
detacher := newDetacher(testcase) detacher := newDetacher(testcase)
return "", detacher.Detach(diskName, instanceID) return "", detacher.Detach(diskName, nodeName)
}, },
}, },
...@@ -171,7 +173,7 @@ func TestAttachDetach(t *testing.T) { ...@@ -171,7 +173,7 @@ func TestAttachDetach(t *testing.T) {
diskIsAttached: diskIsAttachedCall{diskName, instanceID, false, nil}, diskIsAttached: diskIsAttachedCall{diskName, instanceID, false, nil},
test: func(testcase *testcase) (string, error) { test: func(testcase *testcase) (string, error) {
detacher := newDetacher(testcase) detacher := newDetacher(testcase)
return "", detacher.Detach(diskName, instanceID) return "", detacher.Detach(diskName, nodeName)
}, },
}, },
...@@ -183,7 +185,7 @@ func TestAttachDetach(t *testing.T) { ...@@ -183,7 +185,7 @@ func TestAttachDetach(t *testing.T) {
detach: detachCall{diskName, instanceID, nil}, detach: detachCall{diskName, instanceID, nil},
test: func(testcase *testcase) (string, error) { test: func(testcase *testcase) (string, error) {
detacher := newDetacher(testcase) detacher := newDetacher(testcase)
return "", detacher.Detach(diskName, instanceID) return "", detacher.Detach(diskName, nodeName)
}, },
}, },
...@@ -195,7 +197,7 @@ func TestAttachDetach(t *testing.T) { ...@@ -195,7 +197,7 @@ func TestAttachDetach(t *testing.T) {
detach: detachCall{diskName, instanceID, detachError}, detach: detachCall{diskName, instanceID, detachError},
test: func(testcase *testcase) (string, error) { test: func(testcase *testcase) (string, error) {
detacher := newDetacher(testcase) detacher := newDetacher(testcase)
return "", detacher.Detach(diskName, instanceID) return "", detacher.Detach(diskName, nodeName)
}, },
expectedError: detachError, expectedError: detachError,
}, },
...@@ -420,30 +422,30 @@ type instances struct { ...@@ -420,30 +422,30 @@ type instances struct {
instanceID string instanceID string
} }
func (instances *instances) NodeAddresses(name string) ([]api.NodeAddress, error) { func (instances *instances) NodeAddresses(name types.NodeName) ([]api.NodeAddress, error) {
return []api.NodeAddress{}, errors.New("Not implemented") return []api.NodeAddress{}, errors.New("Not implemented")
} }
func (instances *instances) ExternalID(name string) (string, error) { func (instances *instances) ExternalID(name types.NodeName) (string, error) {
return "", errors.New("Not implemented") return "", errors.New("Not implemented")
} }
func (instances *instances) InstanceID(name string) (string, error) { func (instances *instances) InstanceID(name types.NodeName) (string, error) {
return instances.instanceID, nil return instances.instanceID, nil
} }
func (instances *instances) InstanceType(name string) (string, error) { func (instances *instances) InstanceType(name types.NodeName) (string, error) {
return "", errors.New("Not implemented") return "", errors.New("Not implemented")
} }
func (instances *instances) List(filter string) ([]string, error) { func (instances *instances) List(filter string) ([]types.NodeName, error) {
return []string{}, errors.New("Not implemented") return []types.NodeName{}, errors.New("Not implemented")
} }
func (instances *instances) AddSSHKeyToAllInstances(user string, keyData []byte) error { func (instances *instances) AddSSHKeyToAllInstances(user string, keyData []byte) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
func (instances *instances) CurrentNodeName(hostname string) (string, error) { func (instances *instances) CurrentNodeName(hostname string) (types.NodeName, error) {
return "", errors.New("Not implemented") return "", errors.New("Not implemented")
} }
...@@ -26,6 +26,7 @@ import ( ...@@ -26,6 +26,7 @@ import (
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kubernetes/pkg/cloudprovider/providers/gce" "k8s.io/kubernetes/pkg/cloudprovider/providers/gce"
"k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/util/exec" "k8s.io/kubernetes/pkg/util/exec"
"k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/util/sets" "k8s.io/kubernetes/pkg/util/sets"
...@@ -60,13 +61,13 @@ func (plugin *gcePersistentDiskPlugin) GetDeviceMountRefs(deviceMountPath string ...@@ -60,13 +61,13 @@ func (plugin *gcePersistentDiskPlugin) GetDeviceMountRefs(deviceMountPath string
} }
// Attach checks with the GCE cloud provider if the specified volume is already // Attach checks with the GCE cloud provider if the specified volume is already
// attached to the specified node. If the volume is attached, it succeeds // attached to the node with the specified Name.
// (returns nil). If it is not, Attach issues a call to the GCE cloud provider // If the volume is attached, it succeeds (returns nil).
// to attach it. // If it is not, Attach issues a call to the GCE cloud provider to attach it.
// Callers are responsible for retryinging on failure. // Callers are responsible for retrying on failure.
// Callers are responsible for thread safety between concurrent attach and // Callers are responsible for thread safety between concurrent attach and
// detach operations. // detach operations.
func (attacher *gcePersistentDiskAttacher) Attach(spec *volume.Spec, hostName string) (string, error) { func (attacher *gcePersistentDiskAttacher) Attach(spec *volume.Spec, nodeName types.NodeName) (string, error) {
volumeSource, readOnly, err := getVolumeSource(spec) volumeSource, readOnly, err := getVolumeSource(spec)
if err != nil { if err != nil {
return "", err return "", err
...@@ -74,20 +75,20 @@ func (attacher *gcePersistentDiskAttacher) Attach(spec *volume.Spec, hostName st ...@@ -74,20 +75,20 @@ func (attacher *gcePersistentDiskAttacher) Attach(spec *volume.Spec, hostName st
pdName := volumeSource.PDName pdName := volumeSource.PDName
attached, err := attacher.gceDisks.DiskIsAttached(pdName, hostName) attached, err := attacher.gceDisks.DiskIsAttached(pdName, nodeName)
if err != nil { if err != nil {
// Log error and continue with attach // Log error and continue with attach
glog.Errorf( glog.Errorf(
"Error checking if PD (%q) is already attached to current node (%q). Will continue and try attach anyway. err=%v", "Error checking if PD (%q) is already attached to current node (%q). Will continue and try attach anyway. err=%v",
pdName, hostName, err) pdName, nodeName, err)
} }
if err == nil && attached { if err == nil && attached {
// Volume is already attached to node. // Volume is already attached to node.
glog.Infof("Attach operation is successful. PD %q is already attached to node %q.", pdName, hostName) glog.Infof("Attach operation is successful. PD %q is already attached to node %q.", pdName, nodeName)
} else { } else {
if err := attacher.gceDisks.AttachDisk(pdName, hostName, readOnly); err != nil { if err := attacher.gceDisks.AttachDisk(pdName, nodeName, readOnly); err != nil {
glog.Errorf("Error attaching PD %q to node %q: %+v", pdName, hostName, err) glog.Errorf("Error attaching PD %q to node %q: %+v", pdName, nodeName, err)
return "", err return "", err
} }
} }
...@@ -210,25 +211,25 @@ func (plugin *gcePersistentDiskPlugin) NewDetacher() (volume.Detacher, error) { ...@@ -210,25 +211,25 @@ func (plugin *gcePersistentDiskPlugin) NewDetacher() (volume.Detacher, error) {
// Callers are responsible for retryinging on failure. // Callers are responsible for retryinging on failure.
// Callers are responsible for thread safety between concurrent attach and detach // Callers are responsible for thread safety between concurrent attach and detach
// operations. // operations.
func (detacher *gcePersistentDiskDetacher) Detach(deviceMountPath string, hostName string) error { func (detacher *gcePersistentDiskDetacher) Detach(deviceMountPath string, nodeName types.NodeName) error {
pdName := path.Base(deviceMountPath) pdName := path.Base(deviceMountPath)
attached, err := detacher.gceDisks.DiskIsAttached(pdName, hostName) attached, err := detacher.gceDisks.DiskIsAttached(pdName, nodeName)
if err != nil { if err != nil {
// Log error and continue with detach // Log error and continue with detach
glog.Errorf( glog.Errorf(
"Error checking if PD (%q) is already attached to current node (%q). Will continue and try detach anyway. err=%v", "Error checking if PD (%q) is already attached to current node (%q). Will continue and try detach anyway. err=%v",
pdName, hostName, err) pdName, nodeName, err)
} }
if err == nil && !attached { if err == nil && !attached {
// Volume is not attached to node. Success! // Volume is not attached to node. Success!
glog.Infof("Detach operation is successful. PD %q was not attached to node %q.", pdName, hostName) glog.Infof("Detach operation is successful. PD %q was not attached to node %q.", pdName, nodeName)
return nil return nil
} }
if err = detacher.gceDisks.DetachDisk(pdName, hostName); err != nil { if err = detacher.gceDisks.DetachDisk(pdName, nodeName); err != nil {
glog.Errorf("Error detaching PD %q from node %q: %v", pdName, hostName, err) glog.Errorf("Error detaching PD %q from node %q: %v", pdName, nodeName, err)
return err return err
} }
......
...@@ -370,7 +370,7 @@ func (fv *FakeVolume) TearDownAt(dir string) error { ...@@ -370,7 +370,7 @@ func (fv *FakeVolume) TearDownAt(dir string) error {
return os.RemoveAll(dir) return os.RemoveAll(dir)
} }
func (fv *FakeVolume) Attach(spec *Spec, hostName string) (string, error) { func (fv *FakeVolume) Attach(spec *Spec, nodeName types.NodeName) (string, error) {
fv.Lock() fv.Lock()
defer fv.Unlock() defer fv.Unlock()
fv.AttachCallCount++ fv.AttachCallCount++
...@@ -416,7 +416,7 @@ func (fv *FakeVolume) GetMountDeviceCallCount() int { ...@@ -416,7 +416,7 @@ func (fv *FakeVolume) GetMountDeviceCallCount() int {
return fv.MountDeviceCallCount return fv.MountDeviceCallCount
} }
func (fv *FakeVolume) Detach(deviceMountPath string, hostName string) error { func (fv *FakeVolume) Detach(deviceMountPath string, nodeName types.NodeName) error {
fv.Lock() fv.Lock()
defer fv.Unlock() defer fv.Unlock()
fv.DetachCallCount++ fv.DetachCallCount++
......
...@@ -101,7 +101,7 @@ type OperationExecutor interface { ...@@ -101,7 +101,7 @@ type OperationExecutor interface {
// If the volume is not found or there is an error (fetching the node // If the volume is not found or there is an error (fetching the node
// object, for example) then an error is returned which triggers exponential // object, for example) then an error is returned which triggers exponential
// back off on retries. // back off on retries.
VerifyControllerAttachedVolume(volumeToMount VolumeToMount, nodeName string, actualStateOfWorld ActualStateOfWorldAttacherUpdater) error VerifyControllerAttachedVolume(volumeToMount VolumeToMount, nodeName types.NodeName, actualStateOfWorld ActualStateOfWorldAttacherUpdater) error
// IsOperationPending returns true if an operation for the given volumeName and podName is pending, // IsOperationPending returns true if an operation for the given volumeName and podName is pending,
// otherwise it returns false // otherwise it returns false
...@@ -149,18 +149,18 @@ type ActualStateOfWorldAttacherUpdater interface { ...@@ -149,18 +149,18 @@ type ActualStateOfWorldAttacherUpdater interface {
// TODO: in the future, we should be able to remove the volumeName // TODO: in the future, we should be able to remove the volumeName
// argument to this method -- since it is used only for attachable // argument to this method -- since it is used only for attachable
// volumes. See issue 29695. // volumes. See issue 29695.
MarkVolumeAsAttached(volumeName api.UniqueVolumeName, volumeSpec *volume.Spec, nodeName, devicePath string) error MarkVolumeAsAttached(volumeName api.UniqueVolumeName, volumeSpec *volume.Spec, nodeName types.NodeName, devicePath string) error
// Marks the specified volume as detached from the specified node // Marks the specified volume as detached from the specified node
MarkVolumeAsDetached(volumeName api.UniqueVolumeName, nodeName string) MarkVolumeAsDetached(volumeName api.UniqueVolumeName, nodeName types.NodeName)
// Marks desire to detach the specified volume (remove the volume from the node's // Marks desire to detach the specified volume (remove the volume from the node's
// volumesToReportedAsAttached list) // volumesToReportedAsAttached list)
RemoveVolumeFromReportAsAttached(volumeName api.UniqueVolumeName, nodeName string) error RemoveVolumeFromReportAsAttached(volumeName api.UniqueVolumeName, nodeName types.NodeName) error
// Unmarks the desire to detach for the specified volume (add the volume back to // Unmarks the desire to detach for the specified volume (add the volume back to
// the node's volumesToReportedAsAttached list) // the node's volumesToReportedAsAttached list)
AddVolumeToReportAsAttached(volumeName api.UniqueVolumeName, nodeName string) AddVolumeToReportAsAttached(volumeName api.UniqueVolumeName, nodeName types.NodeName)
} }
// VolumeToAttach represents a volume that should be attached to a node. // VolumeToAttach represents a volume that should be attached to a node.
...@@ -175,7 +175,7 @@ type VolumeToAttach struct { ...@@ -175,7 +175,7 @@ type VolumeToAttach struct {
// NodeName is the identifier for the node that the volume should be // NodeName is the identifier for the node that the volume should be
// attached to. // attached to.
NodeName string NodeName types.NodeName
// scheduledPods is a map containing the set of pods that reference this // scheduledPods is a map containing the set of pods that reference this
// volume and are scheduled to the underlying node. The key in the map is // volume and are scheduled to the underlying node. The key in the map is
...@@ -234,7 +234,7 @@ type AttachedVolume struct { ...@@ -234,7 +234,7 @@ type AttachedVolume struct {
VolumeSpec *volume.Spec VolumeSpec *volume.Spec
// NodeName is the identifier for the node that the volume is attached to. // NodeName is the identifier for the node that the volume is attached to.
NodeName string NodeName types.NodeName
// PluginIsAttachable indicates that the plugin for this volume implements // PluginIsAttachable indicates that the plugin for this volume implements
// the volume.Attacher interface // the volume.Attacher interface
...@@ -453,7 +453,7 @@ func (oe *operationExecutor) UnmountDevice( ...@@ -453,7 +453,7 @@ func (oe *operationExecutor) UnmountDevice(
func (oe *operationExecutor) VerifyControllerAttachedVolume( func (oe *operationExecutor) VerifyControllerAttachedVolume(
volumeToMount VolumeToMount, volumeToMount VolumeToMount,
nodeName string, nodeName types.NodeName,
actualStateOfWorld ActualStateOfWorldAttacherUpdater) error { actualStateOfWorld ActualStateOfWorldAttacherUpdater) error {
verifyControllerAttachedVolumeFunc, err := verifyControllerAttachedVolumeFunc, err :=
oe.generateVerifyControllerAttachedVolumeFunc(volumeToMount, nodeName, actualStateOfWorld) oe.generateVerifyControllerAttachedVolumeFunc(volumeToMount, nodeName, actualStateOfWorld)
...@@ -605,7 +605,7 @@ func (oe *operationExecutor) generateDetachVolumeFunc( ...@@ -605,7 +605,7 @@ func (oe *operationExecutor) generateDetachVolumeFunc(
func (oe *operationExecutor) verifyVolumeIsSafeToDetach( func (oe *operationExecutor) verifyVolumeIsSafeToDetach(
volumeToDetach AttachedVolume) error { volumeToDetach AttachedVolume) error {
// Fetch current node object // Fetch current node object
node, fetchErr := oe.kubeClient.Core().Nodes().Get(volumeToDetach.NodeName) node, fetchErr := oe.kubeClient.Core().Nodes().Get(string(volumeToDetach.NodeName))
if fetchErr != nil { if fetchErr != nil {
if errors.IsNotFound(fetchErr) { if errors.IsNotFound(fetchErr) {
glog.Warningf("Node %q not found on API server. DetachVolume will skip safe to detach check.", glog.Warningf("Node %q not found on API server. DetachVolume will skip safe to detach check.",
...@@ -1001,7 +1001,7 @@ func (oe *operationExecutor) generateUnmountDeviceFunc( ...@@ -1001,7 +1001,7 @@ func (oe *operationExecutor) generateUnmountDeviceFunc(
func (oe *operationExecutor) generateVerifyControllerAttachedVolumeFunc( func (oe *operationExecutor) generateVerifyControllerAttachedVolumeFunc(
volumeToMount VolumeToMount, volumeToMount VolumeToMount,
nodeName string, nodeName types.NodeName,
actualStateOfWorld ActualStateOfWorldAttacherUpdater) (func() error, error) { actualStateOfWorld ActualStateOfWorldAttacherUpdater) (func() error, error) {
return func() error { return func() error {
if !volumeToMount.PluginIsAttachable { if !volumeToMount.PluginIsAttachable {
...@@ -1040,7 +1040,7 @@ func (oe *operationExecutor) generateVerifyControllerAttachedVolumeFunc( ...@@ -1040,7 +1040,7 @@ func (oe *operationExecutor) generateVerifyControllerAttachedVolumeFunc(
} }
// Fetch current node object // Fetch current node object
node, fetchErr := oe.kubeClient.Core().Nodes().Get(nodeName) node, fetchErr := oe.kubeClient.Core().Nodes().Get(string(nodeName))
if fetchErr != nil { if fetchErr != nil {
// On failure, return error. Caller will log and retry. // On failure, return error. Caller will log and retry.
return fmt.Errorf( return fmt.Errorf(
......
...@@ -24,6 +24,7 @@ import ( ...@@ -24,6 +24,7 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/api/resource"
"k8s.io/kubernetes/pkg/types"
) )
// Volume represents a directory used by pods or hosts on a node. All method // Volume represents a directory used by pods or hosts on a node. All method
...@@ -140,10 +141,10 @@ type Deleter interface { ...@@ -140,10 +141,10 @@ type Deleter interface {
// Attacher can attach a volume to a node. // Attacher can attach a volume to a node.
type Attacher interface { type Attacher interface {
// Attaches the volume specified by the given spec to the given host. // Attaches the volume specified by the given spec to the node with the given Name.
// On success, returns the device path where the device was attached on the // On success, returns the device path where the device was attached on the
// node. // node.
Attach(spec *Spec, hostName string) (string, error) Attach(spec *Spec, nodeName types.NodeName) (string, error)
// WaitForAttach blocks until the device is attached to this // WaitForAttach blocks until the device is attached to this
// node. If it successfully attaches, the path to the device // node. If it successfully attaches, the path to the device
...@@ -163,8 +164,8 @@ type Attacher interface { ...@@ -163,8 +164,8 @@ type Attacher interface {
// Detacher can detach a volume from a node. // Detacher can detach a volume from a node.
type Detacher interface { type Detacher interface {
// Detach the given device from the given host. // Detach the given device from the node with the given Name.
Detach(deviceName, hostName string) error Detach(deviceName string, nodeName types.NodeName) error
// WaitForDetach blocks until the device is detached from this // WaitForDetach blocks until the device is detached from this
// node. If the device does not detach within the given timeout // node. If the device does not detach within the given timeout
......
...@@ -24,6 +24,7 @@ import ( ...@@ -24,6 +24,7 @@ import (
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere" "k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere"
"k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/util/exec" "k8s.io/kubernetes/pkg/util/exec"
"k8s.io/kubernetes/pkg/util/keymutex" "k8s.io/kubernetes/pkg/util/keymutex"
"k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/mount"
...@@ -60,21 +61,21 @@ func (plugin *vsphereVolumePlugin) NewAttacher() (volume.Attacher, error) { ...@@ -60,21 +61,21 @@ func (plugin *vsphereVolumePlugin) NewAttacher() (volume.Attacher, error) {
// Callers are responsible for retryinging on failure. // Callers are responsible for retryinging on failure.
// Callers are responsible for thread safety between concurrent attach and // Callers are responsible for thread safety between concurrent attach and
// detach operations. // detach operations.
func (attacher *vsphereVMDKAttacher) Attach(spec *volume.Spec, hostName string) (string, error) { func (attacher *vsphereVMDKAttacher) Attach(spec *volume.Spec, nodeName types.NodeName) (string, error) {
volumeSource, _, err := getVolumeSource(spec) volumeSource, _, err := getVolumeSource(spec)
if err != nil { if err != nil {
return "", err return "", err
} }
glog.V(4).Infof("vSphere: Attach disk called for host %s", hostName) glog.V(4).Infof("vSphere: Attach disk called for node %s", nodeName)
// Keeps concurrent attach operations to same host atomic // Keeps concurrent attach operations to same host atomic
attachdetachMutex.LockKey(hostName) attachdetachMutex.LockKey(string(nodeName))
defer attachdetachMutex.UnlockKey(hostName) defer attachdetachMutex.UnlockKey(string(nodeName))
// vsphereCloud.AttachDisk checks if disk is already attached to host and // vsphereCloud.AttachDisk checks if disk is already attached to host and
// succeeds in that case, so no need to do that separately. // succeeds in that case, so no need to do that separately.
_, diskUUID, err := attacher.vsphereVolumes.AttachDisk(volumeSource.VolumePath, hostName) _, diskUUID, err := attacher.vsphereVolumes.AttachDisk(volumeSource.VolumePath, nodeName)
if err != nil { if err != nil {
glog.Errorf("Error attaching volume %q: %+v", volumeSource.VolumePath, err) glog.Errorf("Error attaching volume %q: %+v", volumeSource.VolumePath, err)
return "", err return "", err
...@@ -190,27 +191,27 @@ func (plugin *vsphereVolumePlugin) NewDetacher() (volume.Detacher, error) { ...@@ -190,27 +191,27 @@ func (plugin *vsphereVolumePlugin) NewDetacher() (volume.Detacher, error) {
}, nil }, nil
} }
// Detach the given device from the given host. // Detach the given device from the given node.
func (detacher *vsphereVMDKDetacher) Detach(deviceMountPath string, hostName string) error { func (detacher *vsphereVMDKDetacher) Detach(deviceMountPath string, nodeName types.NodeName) error {
volPath := getVolPathfromDeviceMountPath(deviceMountPath) volPath := getVolPathfromDeviceMountPath(deviceMountPath)
attached, err := detacher.vsphereVolumes.DiskIsAttached(volPath, hostName) attached, err := detacher.vsphereVolumes.DiskIsAttached(volPath, nodeName)
if err != nil { if err != nil {
// Log error and continue with detach // Log error and continue with detach
glog.Errorf( glog.Errorf(
"Error checking if volume (%q) is already attached to current node (%q). Will continue and try detach anyway. err=%v", "Error checking if volume (%q) is already attached to current node (%q). Will continue and try detach anyway. err=%v",
volPath, hostName, err) volPath, nodeName, err)
} }
if err == nil && !attached { if err == nil && !attached {
// Volume is already detached from node. // Volume is already detached from node.
glog.Infof("detach operation was successful. volume %q is already detached from node %q.", volPath, hostName) glog.Infof("detach operation was successful. volume %q is already detached from node %q.", volPath, nodeName)
return nil return nil
} }
attachdetachMutex.LockKey(hostName) attachdetachMutex.LockKey(string(nodeName))
defer attachdetachMutex.UnlockKey(hostName) defer attachdetachMutex.UnlockKey(string(nodeName))
if err := detacher.vsphereVolumes.DetachDisk(volPath, hostName); err != nil { if err := detacher.vsphereVolumes.DetachDisk(volPath, nodeName); err != nil {
glog.Errorf("Error detaching volume %q: %v", volPath, err) glog.Errorf("Error detaching volume %q: %v", volPath, err)
return err return err
} }
......
...@@ -26,6 +26,7 @@ import ( ...@@ -26,6 +26,7 @@ import (
volumetest "k8s.io/kubernetes/pkg/volume/testing" volumetest "k8s.io/kubernetes/pkg/volume/testing"
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kubernetes/pkg/types"
) )
func TestGetDeviceName_Volume(t *testing.T) { func TestGetDeviceName_Volume(t *testing.T) {
...@@ -75,7 +76,7 @@ type testcase struct { ...@@ -75,7 +76,7 @@ type testcase struct {
func TestAttachDetach(t *testing.T) { func TestAttachDetach(t *testing.T) {
uuid := "00000000000000" uuid := "00000000000000"
diskName := "[local] volumes/test" diskName := "[local] volumes/test"
hostName := "host" nodeName := types.NodeName("host")
spec := createVolSpec(diskName) spec := createVolSpec(diskName)
attachError := errors.New("Fake attach error") attachError := errors.New("Fake attach error")
detachError := errors.New("Fake detach error") detachError := errors.New("Fake detach error")
...@@ -84,10 +85,10 @@ func TestAttachDetach(t *testing.T) { ...@@ -84,10 +85,10 @@ func TestAttachDetach(t *testing.T) {
// Successful Attach call // Successful Attach call
{ {
name: "Attach_Positive", name: "Attach_Positive",
attach: attachCall{diskName, hostName, uuid, nil}, attach: attachCall{diskName, nodeName, uuid, nil},
test: func(testcase *testcase) (string, error) { test: func(testcase *testcase) (string, error) {
attacher := newAttacher(testcase) attacher := newAttacher(testcase)
return attacher.Attach(spec, hostName) return attacher.Attach(spec, nodeName)
}, },
expectedDevice: "/dev/disk/by-id/wwn-0x" + uuid, expectedDevice: "/dev/disk/by-id/wwn-0x" + uuid,
}, },
...@@ -95,10 +96,10 @@ func TestAttachDetach(t *testing.T) { ...@@ -95,10 +96,10 @@ func TestAttachDetach(t *testing.T) {
// Attach call fails // Attach call fails
{ {
name: "Attach_Negative", name: "Attach_Negative",
attach: attachCall{diskName, hostName, "", attachError}, attach: attachCall{diskName, nodeName, "", attachError},
test: func(testcase *testcase) (string, error) { test: func(testcase *testcase) (string, error) {
attacher := newAttacher(testcase) attacher := newAttacher(testcase)
return attacher.Attach(spec, hostName) return attacher.Attach(spec, nodeName)
}, },
expectedError: attachError, expectedError: attachError,
}, },
...@@ -106,43 +107,43 @@ func TestAttachDetach(t *testing.T) { ...@@ -106,43 +107,43 @@ func TestAttachDetach(t *testing.T) {
// Detach succeeds // Detach succeeds
{ {
name: "Detach_Positive", name: "Detach_Positive",
diskIsAttached: diskIsAttachedCall{diskName, hostName, true, nil}, diskIsAttached: diskIsAttachedCall{diskName, nodeName, true, nil},
detach: detachCall{diskName, hostName, nil}, detach: detachCall{diskName, nodeName, nil},
test: func(testcase *testcase) (string, error) { test: func(testcase *testcase) (string, error) {
detacher := newDetacher(testcase) detacher := newDetacher(testcase)
return "", detacher.Detach(diskName, hostName) return "", detacher.Detach(diskName, nodeName)
}, },
}, },
// Disk is already detached // Disk is already detached
{ {
name: "Detach_Positive_AlreadyDetached", name: "Detach_Positive_AlreadyDetached",
diskIsAttached: diskIsAttachedCall{diskName, hostName, false, nil}, diskIsAttached: diskIsAttachedCall{diskName, nodeName, false, nil},
test: func(testcase *testcase) (string, error) { test: func(testcase *testcase) (string, error) {
detacher := newDetacher(testcase) detacher := newDetacher(testcase)
return "", detacher.Detach(diskName, hostName) return "", detacher.Detach(diskName, nodeName)
}, },
}, },
// Detach succeeds when DiskIsAttached fails // Detach succeeds when DiskIsAttached fails
{ {
name: "Detach_Positive_CheckFails", name: "Detach_Positive_CheckFails",
diskIsAttached: diskIsAttachedCall{diskName, hostName, false, diskCheckError}, diskIsAttached: diskIsAttachedCall{diskName, nodeName, false, diskCheckError},
detach: detachCall{diskName, hostName, nil}, detach: detachCall{diskName, nodeName, nil},
test: func(testcase *testcase) (string, error) { test: func(testcase *testcase) (string, error) {
detacher := newDetacher(testcase) detacher := newDetacher(testcase)
return "", detacher.Detach(diskName, hostName) return "", detacher.Detach(diskName, nodeName)
}, },
}, },
// Detach fails // Detach fails
{ {
name: "Detach_Negative", name: "Detach_Negative",
diskIsAttached: diskIsAttachedCall{diskName, hostName, false, diskCheckError}, diskIsAttached: diskIsAttachedCall{diskName, nodeName, false, diskCheckError},
detach: detachCall{diskName, hostName, detachError}, detach: detachCall{diskName, nodeName, detachError},
test: func(testcase *testcase) (string, error) { test: func(testcase *testcase) (string, error) {
detacher := newDetacher(testcase) detacher := newDetacher(testcase)
return "", detacher.Detach(diskName, hostName) return "", detacher.Detach(diskName, nodeName)
}, },
expectedError: detachError, expectedError: detachError,
}, },
...@@ -214,27 +215,28 @@ func createPVSpec(name string) *volume.Spec { ...@@ -214,27 +215,28 @@ func createPVSpec(name string) *volume.Spec {
type attachCall struct { type attachCall struct {
diskName string diskName string
hostName string nodeName types.NodeName
retDeviceUUID string retDeviceUUID string
ret error ret error
} }
type detachCall struct { type detachCall struct {
diskName string diskName string
hostName string nodeName types.NodeName
ret error ret error
} }
type diskIsAttachedCall struct { type diskIsAttachedCall struct {
diskName, hostName string diskName string
isAttached bool nodeName types.NodeName
ret error isAttached bool
ret error
} }
func (testcase *testcase) AttachDisk(diskName string, hostName string) (string, string, error) { func (testcase *testcase) AttachDisk(diskName string, nodeName types.NodeName) (string, string, error) {
expected := &testcase.attach expected := &testcase.attach
if expected.diskName == "" && expected.hostName == "" { if expected.diskName == "" && expected.nodeName == "" {
// testcase.attach looks uninitialized, test did not expect to call // testcase.attach looks uninitialized, test did not expect to call
// AttachDisk // AttachDisk
testcase.t.Errorf("Unexpected AttachDisk call!") testcase.t.Errorf("Unexpected AttachDisk call!")
...@@ -246,20 +248,20 @@ func (testcase *testcase) AttachDisk(diskName string, hostName string) (string, ...@@ -246,20 +248,20 @@ func (testcase *testcase) AttachDisk(diskName string, hostName string) (string,
return "", "", errors.New("Unexpected AttachDisk call: wrong diskName") return "", "", errors.New("Unexpected AttachDisk call: wrong diskName")
} }
if expected.hostName != hostName { if expected.nodeName != nodeName {
testcase.t.Errorf("Unexpected AttachDisk call: expected hostName %s, got %s", expected.hostName, hostName) testcase.t.Errorf("Unexpected AttachDisk call: expected nodeName %s, got %s", expected.nodeName, nodeName)
return "", "", errors.New("Unexpected AttachDisk call: wrong hostName") return "", "", errors.New("Unexpected AttachDisk call: wrong nodeName")
} }
glog.V(4).Infof("AttachDisk call: %s, %s, returning %q, %v", diskName, hostName, expected.retDeviceUUID, expected.ret) glog.V(4).Infof("AttachDisk call: %s, %s, returning %q, %v", diskName, nodeName, expected.retDeviceUUID, expected.ret)
return "", expected.retDeviceUUID, expected.ret return "", expected.retDeviceUUID, expected.ret
} }
func (testcase *testcase) DetachDisk(diskName string, hostName string) error { func (testcase *testcase) DetachDisk(diskName string, nodeName types.NodeName) error {
expected := &testcase.detach expected := &testcase.detach
if expected.diskName == "" && expected.hostName == "" { if expected.diskName == "" && expected.nodeName == "" {
// testcase.detach looks uninitialized, test did not expect to call // testcase.detach looks uninitialized, test did not expect to call
// DetachDisk // DetachDisk
testcase.t.Errorf("Unexpected DetachDisk call!") testcase.t.Errorf("Unexpected DetachDisk call!")
...@@ -271,20 +273,20 @@ func (testcase *testcase) DetachDisk(diskName string, hostName string) error { ...@@ -271,20 +273,20 @@ func (testcase *testcase) DetachDisk(diskName string, hostName string) error {
return errors.New("Unexpected DetachDisk call: wrong diskName") return errors.New("Unexpected DetachDisk call: wrong diskName")
} }
if expected.hostName != hostName { if expected.nodeName != nodeName {
testcase.t.Errorf("Unexpected DetachDisk call: expected hostname %s, got %s", expected.hostName, hostName) testcase.t.Errorf("Unexpected DetachDisk call: expected nodeName %s, got %s", expected.nodeName, nodeName)
return errors.New("Unexpected DetachDisk call: wrong hostname") return errors.New("Unexpected DetachDisk call: wrong nodeName")
} }
glog.V(4).Infof("DetachDisk call: %s, %s, returning %v", diskName, hostName, expected.ret) glog.V(4).Infof("DetachDisk call: %s, %s, returning %v", diskName, nodeName, expected.ret)
return expected.ret return expected.ret
} }
func (testcase *testcase) DiskIsAttached(diskName, hostName string) (bool, error) { func (testcase *testcase) DiskIsAttached(diskName string, nodeName types.NodeName) (bool, error) {
expected := &testcase.diskIsAttached expected := &testcase.diskIsAttached
if expected.diskName == "" && expected.hostName == "" { if expected.diskName == "" && expected.nodeName == "" {
// testcase.diskIsAttached looks uninitialized, test did not expect to // testcase.diskIsAttached looks uninitialized, test did not expect to
// call DiskIsAttached // call DiskIsAttached
testcase.t.Errorf("Unexpected DiskIsAttached call!") testcase.t.Errorf("Unexpected DiskIsAttached call!")
...@@ -296,12 +298,12 @@ func (testcase *testcase) DiskIsAttached(diskName, hostName string) (bool, error ...@@ -296,12 +298,12 @@ func (testcase *testcase) DiskIsAttached(diskName, hostName string) (bool, error
return false, errors.New("Unexpected DiskIsAttached call: wrong diskName") return false, errors.New("Unexpected DiskIsAttached call: wrong diskName")
} }
if expected.hostName != hostName { if expected.nodeName != nodeName {
testcase.t.Errorf("Unexpected DiskIsAttached call: expected hostName %s, got %s", expected.hostName, hostName) testcase.t.Errorf("Unexpected DiskIsAttached call: expected nodeName %s, got %s", expected.nodeName, nodeName)
return false, errors.New("Unexpected DiskIsAttached call: wrong hostName") return false, errors.New("Unexpected DiskIsAttached call: wrong nodeName")
} }
glog.V(4).Infof("DiskIsAttached call: %s, %s, returning %v, %v", diskName, hostName, expected.isAttached, expected.ret) glog.V(4).Infof("DiskIsAttached call: %s, %s, returning %v, %v", diskName, nodeName, expected.isAttached, expected.ret)
return expected.isAttached, expected.ret return expected.isAttached, expected.ret
} }
......
...@@ -24,6 +24,7 @@ import ( ...@@ -24,6 +24,7 @@ import (
"k8s.io/kubernetes/pkg/admission" "k8s.io/kubernetes/pkg/admission"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/cloudprovider/providers/aws" "k8s.io/kubernetes/pkg/cloudprovider/providers/aws"
"k8s.io/kubernetes/pkg/types"
) )
type mockVolumes struct { type mockVolumes struct {
...@@ -33,11 +34,11 @@ type mockVolumes struct { ...@@ -33,11 +34,11 @@ type mockVolumes struct {
var _ aws.Volumes = &mockVolumes{} var _ aws.Volumes = &mockVolumes{}
func (v *mockVolumes) AttachDisk(diskName string, instanceName string, readOnly bool) (string, error) { func (v *mockVolumes) AttachDisk(diskName string, nodeName types.NodeName, readOnly bool) (string, error) {
return "", fmt.Errorf("not implemented") return "", fmt.Errorf("not implemented")
} }
func (v *mockVolumes) DetachDisk(diskName string, instanceName string) (string, error) { func (v *mockVolumes) DetachDisk(diskName string, nodeName types.NodeName) (string, error) {
return "", fmt.Errorf("not implemented") return "", fmt.Errorf("not implemented")
} }
...@@ -57,7 +58,7 @@ func (c *mockVolumes) GetDiskPath(volumeName string) (string, error) { ...@@ -57,7 +58,7 @@ func (c *mockVolumes) GetDiskPath(volumeName string) (string, error) {
return "", fmt.Errorf("not implemented") return "", fmt.Errorf("not implemented")
} }
func (c *mockVolumes) DiskIsAttached(volumeName, instanceID string) (bool, error) { func (c *mockVolumes) DiskIsAttached(volumeName string, nodeName types.NodeName) (bool, error) {
return false, fmt.Errorf("not implemented") return false, fmt.Errorf("not implemented")
} }
......
...@@ -37,6 +37,7 @@ import ( ...@@ -37,6 +37,7 @@ import (
client "k8s.io/kubernetes/pkg/client/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned"
awscloud "k8s.io/kubernetes/pkg/cloudprovider/providers/aws" awscloud "k8s.io/kubernetes/pkg/cloudprovider/providers/aws"
gcecloud "k8s.io/kubernetes/pkg/cloudprovider/providers/gce" gcecloud "k8s.io/kubernetes/pkg/cloudprovider/providers/gce"
"k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/util/uuid" "k8s.io/kubernetes/pkg/util/uuid"
"k8s.io/kubernetes/test/e2e/framework" "k8s.io/kubernetes/test/e2e/framework"
) )
...@@ -54,8 +55,8 @@ var _ = framework.KubeDescribe("Pod Disks", func() { ...@@ -54,8 +55,8 @@ var _ = framework.KubeDescribe("Pod Disks", func() {
var ( var (
podClient client.PodInterface podClient client.PodInterface
nodeClient client.NodeInterface nodeClient client.NodeInterface
host0Name string host0Name types.NodeName
host1Name string host1Name types.NodeName
) )
f := framework.NewDefaultFramework("pod-disks") f := framework.NewDefaultFramework("pod-disks")
...@@ -68,8 +69,8 @@ var _ = framework.KubeDescribe("Pod Disks", func() { ...@@ -68,8 +69,8 @@ var _ = framework.KubeDescribe("Pod Disks", func() {
Expect(len(nodes.Items)).To(BeNumerically(">=", 2), "Requires at least 2 nodes") Expect(len(nodes.Items)).To(BeNumerically(">=", 2), "Requires at least 2 nodes")
host0Name = nodes.Items[0].ObjectMeta.Name host0Name = types.NodeName(nodes.Items[0].ObjectMeta.Name)
host1Name = nodes.Items[1].ObjectMeta.Name host1Name = types.NodeName(nodes.Items[1].ObjectMeta.Name)
mathrand.Seed(time.Now().UTC().UnixNano()) mathrand.Seed(time.Now().UTC().UnixNano())
}) })
...@@ -91,7 +92,7 @@ var _ = framework.KubeDescribe("Pod Disks", func() { ...@@ -91,7 +92,7 @@ var _ = framework.KubeDescribe("Pod Disks", func() {
By("cleaning up PD-RW test environment") By("cleaning up PD-RW test environment")
podClient.Delete(host0Pod.Name, api.NewDeleteOptions(0)) podClient.Delete(host0Pod.Name, api.NewDeleteOptions(0))
podClient.Delete(host1Pod.Name, api.NewDeleteOptions(0)) podClient.Delete(host1Pod.Name, api.NewDeleteOptions(0))
detachAndDeletePDs(diskName, []string{host0Name, host1Name}) detachAndDeletePDs(diskName, []types.NodeName{host0Name, host1Name})
}() }()
By("submitting host0Pod to kubernetes") By("submitting host0Pod to kubernetes")
...@@ -155,7 +156,7 @@ var _ = framework.KubeDescribe("Pod Disks", func() { ...@@ -155,7 +156,7 @@ var _ = framework.KubeDescribe("Pod Disks", func() {
By("cleaning up PD-RW test environment") By("cleaning up PD-RW test environment")
podClient.Delete(host0Pod.Name, &api.DeleteOptions{}) podClient.Delete(host0Pod.Name, &api.DeleteOptions{})
podClient.Delete(host1Pod.Name, &api.DeleteOptions{}) podClient.Delete(host1Pod.Name, &api.DeleteOptions{})
detachAndDeletePDs(diskName, []string{host0Name, host1Name}) detachAndDeletePDs(diskName, []types.NodeName{host0Name, host1Name})
}() }()
By("submitting host0Pod to kubernetes") By("submitting host0Pod to kubernetes")
...@@ -220,7 +221,7 @@ var _ = framework.KubeDescribe("Pod Disks", func() { ...@@ -220,7 +221,7 @@ var _ = framework.KubeDescribe("Pod Disks", func() {
podClient.Delete(rwPod.Name, api.NewDeleteOptions(0)) podClient.Delete(rwPod.Name, api.NewDeleteOptions(0))
podClient.Delete(host0ROPod.Name, api.NewDeleteOptions(0)) podClient.Delete(host0ROPod.Name, api.NewDeleteOptions(0))
podClient.Delete(host1ROPod.Name, api.NewDeleteOptions(0)) podClient.Delete(host1ROPod.Name, api.NewDeleteOptions(0))
detachAndDeletePDs(diskName, []string{host0Name, host1Name}) detachAndDeletePDs(diskName, []types.NodeName{host0Name, host1Name})
}() }()
By("submitting rwPod to ensure PD is formatted") By("submitting rwPod to ensure PD is formatted")
...@@ -272,7 +273,7 @@ var _ = framework.KubeDescribe("Pod Disks", func() { ...@@ -272,7 +273,7 @@ var _ = framework.KubeDescribe("Pod Disks", func() {
podClient.Delete(rwPod.Name, &api.DeleteOptions{}) podClient.Delete(rwPod.Name, &api.DeleteOptions{})
podClient.Delete(host0ROPod.Name, &api.DeleteOptions{}) podClient.Delete(host0ROPod.Name, &api.DeleteOptions{})
podClient.Delete(host1ROPod.Name, &api.DeleteOptions{}) podClient.Delete(host1ROPod.Name, &api.DeleteOptions{})
detachAndDeletePDs(diskName, []string{host0Name, host1Name}) detachAndDeletePDs(diskName, []types.NodeName{host0Name, host1Name})
}() }()
By("submitting rwPod to ensure PD is formatted") By("submitting rwPod to ensure PD is formatted")
...@@ -322,7 +323,7 @@ var _ = framework.KubeDescribe("Pod Disks", func() { ...@@ -322,7 +323,7 @@ var _ = framework.KubeDescribe("Pod Disks", func() {
if host0Pod != nil { if host0Pod != nil {
podClient.Delete(host0Pod.Name, api.NewDeleteOptions(0)) podClient.Delete(host0Pod.Name, api.NewDeleteOptions(0))
} }
detachAndDeletePDs(diskName, []string{host0Name}) detachAndDeletePDs(diskName, []types.NodeName{host0Name})
}() }()
fileAndContentToVerify := make(map[string]string) fileAndContentToVerify := make(map[string]string)
...@@ -377,8 +378,8 @@ var _ = framework.KubeDescribe("Pod Disks", func() { ...@@ -377,8 +378,8 @@ var _ = framework.KubeDescribe("Pod Disks", func() {
if host0Pod != nil { if host0Pod != nil {
podClient.Delete(host0Pod.Name, api.NewDeleteOptions(0)) podClient.Delete(host0Pod.Name, api.NewDeleteOptions(0))
} }
detachAndDeletePDs(disk1Name, []string{host0Name}) detachAndDeletePDs(disk1Name, []types.NodeName{host0Name})
detachAndDeletePDs(disk2Name, []string{host0Name}) detachAndDeletePDs(disk2Name, []types.NodeName{host0Name})
}() }()
containerName := "mycontainer" containerName := "mycontainer"
...@@ -535,16 +536,14 @@ func deletePD(pdName string) error { ...@@ -535,16 +536,14 @@ func deletePD(pdName string) error {
} }
} }
func detachPD(hostName, pdName string) error { func detachPD(nodeName types.NodeName, pdName string) error {
if framework.TestContext.Provider == "gce" || framework.TestContext.Provider == "gke" { if framework.TestContext.Provider == "gce" || framework.TestContext.Provider == "gke" {
instanceName := strings.Split(hostName, ".")[0]
gceCloud, err := getGCECloud() gceCloud, err := getGCECloud()
if err != nil { if err != nil {
return err return err
} }
err = gceCloud.DetachDisk(pdName, instanceName) err = gceCloud.DetachDisk(pdName, nodeName)
if err != nil { if err != nil {
if gerr, ok := err.(*googleapi.Error); ok && strings.Contains(gerr.Message, "Invalid value for field 'disk'") { if gerr, ok := err.(*googleapi.Error); ok && strings.Contains(gerr.Message, "Invalid value for field 'disk'") {
// PD already detached, ignore error. // PD already detached, ignore error.
...@@ -575,7 +574,7 @@ func detachPD(hostName, pdName string) error { ...@@ -575,7 +574,7 @@ func detachPD(hostName, pdName string) error {
} }
} }
func testPDPod(diskNames []string, targetHost string, readOnly bool, numContainers int) *api.Pod { func testPDPod(diskNames []string, targetNode types.NodeName, readOnly bool, numContainers int) *api.Pod {
containers := make([]api.Container, numContainers) containers := make([]api.Container, numContainers)
for i := range containers { for i := range containers {
containers[i].Name = "mycontainer" containers[i].Name = "mycontainer"
...@@ -608,7 +607,7 @@ func testPDPod(diskNames []string, targetHost string, readOnly bool, numContaine ...@@ -608,7 +607,7 @@ func testPDPod(diskNames []string, targetHost string, readOnly bool, numContaine
}, },
Spec: api.PodSpec{ Spec: api.PodSpec{
Containers: containers, Containers: containers,
NodeName: targetHost, NodeName: string(targetNode),
}, },
} }
...@@ -644,31 +643,31 @@ func testPDPod(diskNames []string, targetHost string, readOnly bool, numContaine ...@@ -644,31 +643,31 @@ func testPDPod(diskNames []string, targetHost string, readOnly bool, numContaine
} }
// Waits for specified PD to to detach from specified hostName // Waits for specified PD to to detach from specified hostName
func waitForPDDetach(diskName, hostName string) error { func waitForPDDetach(diskName string, nodeName types.NodeName) error {
if framework.TestContext.Provider == "gce" || framework.TestContext.Provider == "gke" { if framework.TestContext.Provider == "gce" || framework.TestContext.Provider == "gke" {
framework.Logf("Waiting for GCE PD %q to detach from node %q.", diskName, hostName) framework.Logf("Waiting for GCE PD %q to detach from node %q.", diskName, nodeName)
gceCloud, err := getGCECloud() gceCloud, err := getGCECloud()
if err != nil { if err != nil {
return err return err
} }
for start := time.Now(); time.Since(start) < gcePDDetachTimeout; time.Sleep(gcePDDetachPollTime) { for start := time.Now(); time.Since(start) < gcePDDetachTimeout; time.Sleep(gcePDDetachPollTime) {
diskAttached, err := gceCloud.DiskIsAttached(diskName, hostName) diskAttached, err := gceCloud.DiskIsAttached(diskName, nodeName)
if err != nil { if err != nil {
framework.Logf("Error waiting for PD %q to detach from node %q. 'DiskIsAttached(...)' failed with %v", diskName, hostName, err) framework.Logf("Error waiting for PD %q to detach from node %q. 'DiskIsAttached(...)' failed with %v", diskName, nodeName, err)
return err return err
} }
if !diskAttached { if !diskAttached {
// Specified disk does not appear to be attached to specified node // Specified disk does not appear to be attached to specified node
framework.Logf("GCE PD %q appears to have successfully detached from %q.", diskName, hostName) framework.Logf("GCE PD %q appears to have successfully detached from %q.", diskName, nodeName)
return nil return nil
} }
framework.Logf("Waiting for GCE PD %q to detach from %q.", diskName, hostName) framework.Logf("Waiting for GCE PD %q to detach from %q.", diskName, nodeName)
} }
return fmt.Errorf("Gave up waiting for GCE PD %q to detach from %q after %v", diskName, hostName, gcePDDetachTimeout) return fmt.Errorf("Gave up waiting for GCE PD %q to detach from %q after %v", diskName, nodeName, gcePDDetachTimeout)
} }
return nil return nil
...@@ -684,7 +683,7 @@ func getGCECloud() (*gcecloud.GCECloud, error) { ...@@ -684,7 +683,7 @@ func getGCECloud() (*gcecloud.GCECloud, error) {
return gceCloud, nil return gceCloud, nil
} }
func detachAndDeletePDs(diskName string, hosts []string) { func detachAndDeletePDs(diskName string, hosts []types.NodeName) {
for _, host := range hosts { for _, host := range hosts {
framework.Logf("Detaching GCE PD %q from node %q.", diskName, host) framework.Logf("Detaching GCE PD %q from node %q.", diskName, host)
detachPD(host, diskName) detachPD(host, diskName)
...@@ -697,7 +696,8 @@ func detachAndDeletePDs(diskName string, hosts []string) { ...@@ -697,7 +696,8 @@ func detachAndDeletePDs(diskName string, hosts []string) {
func waitForPDInVolumesInUse( func waitForPDInVolumesInUse(
nodeClient client.NodeInterface, nodeClient client.NodeInterface,
diskName, nodeName string, diskName string,
nodeName types.NodeName,
timeout time.Duration, timeout time.Duration,
shouldExist bool) error { shouldExist bool) error {
logStr := "to contain" logStr := "to contain"
...@@ -708,7 +708,7 @@ func waitForPDInVolumesInUse( ...@@ -708,7 +708,7 @@ func waitForPDInVolumesInUse(
"Waiting for node %s's VolumesInUse Status %s PD %q", "Waiting for node %s's VolumesInUse Status %s PD %q",
nodeName, logStr, diskName) nodeName, logStr, diskName)
for start := time.Now(); time.Since(start) < timeout; time.Sleep(nodeStatusPollTime) { for start := time.Now(); time.Since(start) < timeout; time.Sleep(nodeStatusPollTime) {
nodeObj, err := nodeClient.Get(nodeName) nodeObj, err := nodeClient.Get(string(nodeName))
if err != nil || nodeObj == nil { if err != nil || nodeObj == nil {
framework.Logf( framework.Logf(
"Failed to fetch node object %q from API server. err=%v", "Failed to fetch node object %q from API server. err=%v",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment