Skip to content

Commit

Permalink
extract namespace from network annotation when cheking for kubevirt r…
Browse files Browse the repository at this point in the history
…elated pod instance

when running a vm, a virt-launcher pod is spawned. This pod should be ignored by kubemacpool,
since the mac was already allocated during the creation of the vm. This is implemented in isRelatedToKubevirt().

Specifically, it does this by checking if the vm self link is valid. The link required the vm's namespace.
Currently, kubemacpool uses the pod's own namespace in order to construct this link.
This doesn't work - because from some reason the pod isn't received with any namespace assigned to it.
Hence, the pod to be treated as a standalone pod, and thus rejected.

In this commit, we switch to taking the namespace from the pod's annotation, that consist the network's namespace.
This is introduced with selectNamespaceFromNetworks(), which goes over the pod's multus.NetworkSelectionElement annotation (if exists),
and extracts the namespace form there. We assume that in this case there could only be one namespace for all the multus networks.

Signed-off-by: Ram Lavi <[email protected]>
  • Loading branch information
RamLavi committed May 11, 2020
1 parent 97e9201 commit 7cfd27a
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 4 deletions.
4 changes: 2 additions & 2 deletions pkg/pool-manager/pod_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func (p *PoolManager) AllocatePodMac(pod *corev1.Pod) error {
}

// validate if the pod is related to kubevirt
if p.isRelatedToKubevirt(pod) {
if p.isRelatedToKubevirt(pod, networks) {
// nothing to do here. the mac is already by allocated by the virtual machine webhook
log.V(1).Info("This pod have ownerReferences from kubevirt skipping")
return nil
Expand Down Expand Up @@ -220,7 +220,7 @@ func (p *PoolManager) initPodMap() error {
}

// validate if the pod is related to kubevirt
if p.isRelatedToKubevirt(&pod) {
if p.isRelatedToKubevirt(&pod, networks) {
// nothing to do here. the mac is already by allocated by the virtual machine webhook
log.V(1).Info("This pod have ownerReferences from kubevirt skipping")
continue
Expand Down
26 changes: 24 additions & 2 deletions pkg/pool-manager/virtualmachine_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"strings"
"time"

multus "github.com/intel/multus-cni/types"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -323,14 +324,23 @@ func (p *PoolManager) IsKubevirtEnabled() bool {
return p.isKubevirt
}

func (p *PoolManager) isRelatedToKubevirt(pod *corev1.Pod) bool {
func (p *PoolManager) isRelatedToKubevirt(pod *corev1.Pod, networks []*multus.NetworkSelectionElement) bool {
if pod.ObjectMeta.OwnerReferences == nil {
log.V(1).Info("this pod has no OwnerReferences, so will be considered as a regular pod")
return false
}

// since the pod request may not have owned the vm namespace in this early state of vm making,
// we need to receive the namespace from the network annotation
namespace, ok := selectNamespaceFromNetworks(networks)
if !ok {
log.V(1).Info("this pod has more than 1 namespace in its secondary networks, so will be considered as a regular pod")
return false
}

for _, ref := range pod.OwnerReferences {
if ref.Kind == kubevirt.VirtualMachineInstanceGroupVersionKind.Kind {
requestUrl := fmt.Sprintf("apis/kubevirt.io/v1alpha3/namespaces/%s/virtualmachines/%s", pod.Namespace, ref.Name)
requestUrl := fmt.Sprintf("apis/kubevirt.io/v1alpha3/namespaces/%s/virtualmachines/%s", namespace, ref.Name)
log.V(1).Info("test", "requestURI", requestUrl)
result := p.kubeClient.ExtensionsV1beta1().RESTClient().Get().RequestURI(requestUrl).Do()

Expand Down Expand Up @@ -482,6 +492,18 @@ func (p *PoolManager) IsVmInstanceOptedIn(namespaceName string) (bool, error) {
return p.isInstanceOptedIn(namespaceName, "kubemacpool-mutator", "mutatevirtualmachines.kubemacpool.io")
}

//making sure that all networks have the same namespace, otherwise returning error.
func selectNamespaceFromNetworks(networks []*multus.NetworkSelectionElement) (string, bool) {
firstNamespace := networks[0].Namespace
for _, network := range networks {
if network.Namespace != firstNamespace {
return "", false
}
}

return firstNamespace, true
}

func vmNamespaced(machine *kubevirt.VirtualMachine) string {
return fmt.Sprintf("%s/%s", machine.Namespace, machine.Name)
}

0 comments on commit 7cfd27a

Please sign in to comment.