Skip to content

Commit

Permalink
api: remove hotplug/unplug from VMI
Browse files Browse the repository at this point in the history
hotplug/unplug will be allowed from VM only.

Signed-off-by: Alona Paz <[email protected]>
  • Loading branch information
AlonaKaplan committed Jun 21, 2023
1 parent b132172 commit 184b587
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 63 deletions.
64 changes: 45 additions & 19 deletions pkg/virt-controller/watch/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ import (

"kubevirt.io/kubevirt/pkg/controller"
"kubevirt.io/kubevirt/pkg/instancetype"
netvmispec "kubevirt.io/kubevirt/pkg/network/vmispec"
storagetypes "kubevirt.io/kubevirt/pkg/storage/types"
"kubevirt.io/kubevirt/pkg/util"
"kubevirt.io/kubevirt/pkg/util/migrations"
Expand Down Expand Up @@ -2714,40 +2713,67 @@ func (c *VMController) handleDynamicInterfaceRequests(vm *virtv1.VirtualMachine,
return nil
}

interfaceMap := map[string]virtv1.Interface{}
if vmi != nil {
interfaceMap = netvmispec.IndexInterfaceSpecByName(vmi.Spec.Domain.Devices.Interfaces)
}
vmTemplateCopy := vm.Spec.Template.Spec.DeepCopy()
for i, ifaceRequest := range vm.Status.InterfaceRequests {
for i := range vm.Status.InterfaceRequests {
vmTemplateCopy = controller.ApplyNetworkInterfaceRequestOnVMISpec(
vmTemplateCopy, &vm.Status.InterfaceRequests[i])

if vmi == nil || vmi.DeletionTimestamp != nil {
continue
}

if ifaceRequest.AddInterfaceOptions != nil {
if _, exists := interfaceMap[ifaceRequest.AddInterfaceOptions.Name]; !exists {
if err := c.clientset.VirtualMachineInstance(vmi.Namespace).AddInterface(context.Background(), vmi.Name, ifaceRequest.AddInterfaceOptions); err != nil {
return err
}
}
}
vmiSpecCopy := vmi.Spec.DeepCopy()
vmiSpecCopy = controller.ApplyNetworkInterfaceRequestOnVMISpec(
vmiSpecCopy, &vm.Status.InterfaceRequests[i])

if ifaceRequest.RemoveInterfaceOptions != nil {
if _, exists := interfaceMap[ifaceRequest.RemoveInterfaceOptions.Name]; exists {
if err := c.clientset.VirtualMachineInstance(vmi.Namespace).RemoveInterface(context.Background(), vmi.Name, ifaceRequest.RemoveInterfaceOptions); err != nil {
return err
}
}
if err := c.vmiInterfacesPatch(vmiSpecCopy, vmi); err != nil {
return err
}
}

vm.Spec.Template.Spec = *vmTemplateCopy
return nil
}

func (c *VMController) vmiInterfacesPatch(newVmiSpec *virtv1.VirtualMachineInstanceSpec, vmi *virtv1.VirtualMachineInstance) error {
if equality.Semantic.DeepEqual(vmi.Spec.Domain.Devices.Interfaces, newVmiSpec.Domain.Devices.Interfaces) {
return nil
}

oldIfacesJSON, err := json.Marshal(vmi.Spec.Domain.Devices.Interfaces)
if err != nil {
return err
}

newIfacesJSON, err := json.Marshal(newVmiSpec.Domain.Devices.Interfaces)
if err != nil {
return err
}

oldNetworksJSON, err := json.Marshal(vmi.Spec.Networks)
if err != nil {
return err
}

newNetworksJSON, err := json.Marshal(newVmiSpec.Networks)
if err != nil {
return err
}

const verb = "add"
testNetworks := fmt.Sprintf(`{ "op": "test", "path": "/spec/networks", "value": %s}`, string(oldNetworksJSON))
updateNetworks := fmt.Sprintf(`{ "op": %q, "path": "/spec/networks", "value": %s}`, verb, string(newNetworksJSON))

testInterfaces := fmt.Sprintf(`{ "op": "test", "path": "/spec/domain/devices/interfaces", "value": %s}`, string(oldIfacesJSON))
updateInterfaces := fmt.Sprintf(`{ "op": %q, "path": "/spec/domain/devices/interfaces", "value": %s}`, verb, string(newIfacesJSON))

patch := fmt.Sprintf("[%s, %s, %s, %s]", testNetworks, testInterfaces, updateNetworks, updateInterfaces)

_, err = c.clientset.VirtualMachineInstance(vmi.Namespace).Patch(context.Background(), vmi.Name, types.JSONPatchType, []byte(patch), &v1.PatchOptions{})

return err
}

func (c *VMController) setupLiveFeatures(
vm *virtv1.VirtualMachine,
vmi, VMIDefaults *virtv1.VirtualMachineInstance) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1267,26 +1267,6 @@ func (_mr *_MockVirtualMachineInstanceInterfaceRecorder) VSOCK(arg0, arg1 interf
return _mr.mock.ctrl.RecordCall(_mr.mock, "VSOCK", arg0, arg1)
}

func (_m *MockVirtualMachineInstanceInterface) AddInterface(ctx context.Context, name string, addInterfaceOptions *v120.AddInterfaceOptions) error {
ret := _m.ctrl.Call(_m, "AddInterface", ctx, name, addInterfaceOptions)
ret0, _ := ret[0].(error)
return ret0
}

func (_mr *_MockVirtualMachineInstanceInterfaceRecorder) AddInterface(arg0, arg1, arg2 interface{}) *gomock.Call {
return _mr.mock.ctrl.RecordCall(_mr.mock, "AddInterface", arg0, arg1, arg2)
}

func (_m *MockVirtualMachineInstanceInterface) RemoveInterface(ctx context.Context, name string, removeInterfaceOptions *v120.RemoveInterfaceOptions) error {
ret := _m.ctrl.Call(_m, "RemoveInterface", ctx, name, removeInterfaceOptions)
ret0, _ := ret[0].(error)
return ret0
}

func (_mr *_MockVirtualMachineInstanceInterfaceRecorder) RemoveInterface(arg0, arg1, arg2 interface{}) *gomock.Call {
return _mr.mock.ctrl.RecordCall(_mr.mock, "RemoveInterface", arg0, arg1, arg2)
}

// Mock of ReplicaSetInterface interface
type MockReplicaSetInterface struct {
ctrl *gomock.Controller
Expand Down
2 changes: 0 additions & 2 deletions staging/src/kubevirt.io/client-go/kubecli/kubevirt.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,6 @@ type VirtualMachineInstanceInterface interface {
AddVolume(ctx context.Context, name string, addVolumeOptions *v1.AddVolumeOptions) error
RemoveVolume(ctx context.Context, name string, removeVolumeOptions *v1.RemoveVolumeOptions) error
VSOCK(name string, options *v1.VSOCKOptions) (StreamInterface, error)
AddInterface(ctx context.Context, name string, addInterfaceOptions *v1.AddInterfaceOptions) error
RemoveInterface(ctx context.Context, name string, removeInterfaceOptions *v1.RemoveInterfaceOptions) error
}

type ReplicaSetInterface interface {
Expand Down
22 changes: 0 additions & 22 deletions staging/src/kubevirt.io/client-go/kubecli/vmi.go
Original file line number Diff line number Diff line change
Expand Up @@ -506,25 +506,3 @@ func (v *vmis) VSOCK(name string, options *v1.VSOCKOptions) (StreamInterface, er
queryParams.Add("tls", strconv.FormatBool(useTLS))
return asyncSubresourceHelper(v.config, v.resource, v.namespace, name, "vsock", queryParams)
}

func (v *vmis) AddInterface(ctx context.Context, name string, addInterfaceOptions *v1.AddInterfaceOptions) error {
uri := fmt.Sprintf(vmiSubresourceURL, v1.ApiStorageVersion, v.namespace, name, "addinterface")

JSON, err := json.Marshal(addInterfaceOptions)
if err != nil {
return err
}

return v.restClient.Put().RequestURI(uri).Body(JSON).Do(ctx).Error()
}

func (v *vmis) RemoveInterface(ctx context.Context, name string, removeInterfaceOptions *v1.RemoveInterfaceOptions) error {
uri := fmt.Sprintf(vmiSubresourceURL, v1.ApiStorageVersion, v.namespace, name, "removeinterface")

JSON, err := json.Marshal(removeInterfaceOptions)
if err != nil {
return err
}

return v.restClient.Put().RequestURI(uri).Body(JSON).Do(ctx).Error()
}

0 comments on commit 184b587

Please sign in to comment.