diff --git a/base-images/alt_image_versions.yml b/base-images/alt_image_versions.yml new file mode 100644 index 000000000..c639371ab --- /dev/null +++ b/base-images/alt_image_versions.yml @@ -0,0 +1,5 @@ +# REGISTRY_PATH is a special key which is concatenated with other base images +REGISTRY_PATH: "registry.altlinux.org/" + +# Virtualization images +DISTROLESS_ALT_P11: "alt/distroless-base:p11@sha256:256886b532513294e84688f63ba06b380b5160aac30f45cb7c7542ae4365bf29" diff --git a/images/virt-artifact/werf.inc.yaml b/images/virt-artifact/werf.inc.yaml index 6071e2796..18970cc14 100644 --- a/images/virt-artifact/werf.inc.yaml +++ b/images/virt-artifact/werf.inc.yaml @@ -122,18 +122,35 @@ shell: - export CGO_ENABLED=0 - export GOARCH=amd64 - - echo ============== Build container-disk ==================== + - echo ============== Build container-disk =================== - gcc -static cmd/container-disk-v2alpha/main.c -o /kubevirt-binaries/container-disk - echo ============== Build virt-launcher ==================== - CGO_ENABLED=1 go build -o /kubevirt-binaries/virt-launcher ./cmd/virt-launcher/ + - echo "Create group file" + - | + GROUP_FILE=./cmd/virt-launcher/group + echo "qemu:x:107:" > $GROUP_FILE + echo "root:x:0:" >> $GROUP_FILE + chmod 0644 $GROUP_FILE + + - echo "Create passwd file" + - | + PASSWD_FILE=./cmd/virt-launcher/passwd + echo "qemu:x:107:107:user:/home/qemu:/bin/bash" > $PASSWD_FILE + echo "root:x:0:0:root:/root:/bin/bash" >> $PASSWD_FILE + chmod 0644 $PASSWD_FILE + - echo ============== Build virt-handler ===================== - CGO_ENABLED=1 go build -o /kubevirt-binaries/virt-handler ./cmd/virt-handler/ - echo ============== Build virt-launcher-monitor ============ - go build -o /kubevirt-binaries/virt-launcher-monitor ./cmd/virt-launcher-monitor/ + - echo ============== Build virt-tail ======================== + - go build -o /kubevirt-binaries/virt-tail ./cmd/virt-tail/ + - echo ============== Build virt-freezer ===================== - go build -o /kubevirt-binaries/virt-freezer ./cmd/virt-freezer/ @@ -152,7 +169,7 @@ shell: - echo ============== Build virt-operator ==================== - go build -o /kubevirt-binaries/virt-operator ./cmd/virt-operator/ - - echo ============== Build sidecars ==================== + - echo ============== Build sidecars ========================= - go build -o /kubevirt-binaries/sidecars ./cmd/sidecars/ - echo ============== Build virtctl ========================== diff --git a/images/virt-launcher/werf.inc.yaml b/images/virt-launcher/werf.inc.yaml index 2b01d4dfb..8d86999a6 100644 --- a/images/virt-launcher/werf.inc.yaml +++ b/images/virt-launcher/werf.inc.yaml @@ -52,35 +52,48 @@ import: after: install includePaths: - .version -- image: virt-artifact - add: /images/kubevirt/{{ $.ImageName }}:latest/etc/libvirt +- image: virt-artifact-classic-go + add: /kubevirt/cmd/{{ $.ImageName }} to: /etc/libvirt after: install includePaths: - qemu.conf - virtqemud.conf +# - image: virt-artifact +# add: /images/kubevirt/{{ $.ImageName }}:latest/etc/libvirt +# to: /etc/libvirt +# after: install +# includePaths: +# - qemu.conf +# - virtqemud.conf - image: virt-artifact add: /images/kubevirt/{{ $.ImageName }}:latest/etc to: /etc after: install includePaths: - nsswitch.conf -- image: virt-artifact - add: /images/kubevirt/{{ $.ImageName }}:latest/usr/bin +# - image: virt-artifact + # add: /images/kubevirt/{{ $.ImageName }}:latest/usr/bin +- image: virt-artifact-classic-go + add: /kubevirt-binaries/ to: /usr/bin before: setup includePaths: - container-disk - - node-labeller.sh - virt-freezer - virt-launcher - virt-launcher-monitor - virt-probe - virt-tail + # - kubevirt/cmd/virt-launcher/node-labeller - image: virt-artifact-classic-go - add: /kubevirt-binaries/ - to: /kubevirt-binaries - after: install + add: /kubevirt/cmd/virt-launcher/node-labeller/ + to: /usr/bin + before: setup +# - image: virt-artifact-classic-go +# add: /kubevirt-binaries/ +# to: /kubevirt-binaries +# after: install git: - add: /images/{{ $.ImageName }} to: / @@ -312,3 +325,7 @@ shell: echo "Build RPMs from:" /home/builder/*.rpm echo "Note: time consuming operation, be patient ..." su - builder -c 'trap "echo Build log tail: ; tail -n 1024 /tmp/build.log" EXIT ; rpm -ba /home/builder/RPM/SPECS/edk2.spec > /tmp/build.log 2>&1' +# --- +# image: {{ $.ImageName }}-dir-sctruct +# final: false +# from: {{ .Images.DISTROLESS_ALT_P11 }} \ No newline at end of file diff --git a/images/virtualization-artifact/pkg/controller/service/size_policy_service.go b/images/virtualization-artifact/pkg/controller/service/size_policy_service.go index 6842b56c9..6cbd895df 100644 --- a/images/virtualization-artifact/pkg/controller/service/size_policy_service.go +++ b/images/virtualization-artifact/pkg/controller/service/size_policy_service.go @@ -17,15 +17,12 @@ limitations under the License. package service import ( - "context" "errors" "fmt" "strconv" "strings" "k8s.io/apimachinery/pkg/api/resource" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" "github.com/deckhouse/virtualization/api/core/v1alpha2" ) @@ -36,23 +33,13 @@ const ( greater = 1 ) -type SizePolicyService struct { - client client.Client -} +type SizePolicyService struct{} -func NewSizePolicyService(client client.Client) *SizePolicyService { - return &SizePolicyService{client: client} +func NewSizePolicyService() *SizePolicyService { + return &SizePolicyService{} } -func (s *SizePolicyService) CheckVMMatchedSizePolicy(ctx context.Context, vm *v1alpha2.VirtualMachine) error { - vmClass := &v1alpha2.VirtualMachineClass{} - err := s.client.Get(ctx, types.NamespacedName{ - Name: vm.Spec.VirtualMachineClassName, - }, vmClass) - if err != nil { - return err - } - +func (s *SizePolicyService) CheckVMMatchedSizePolicy(vm *v1alpha2.VirtualMachine, vmClass *v1alpha2.VirtualMachineClass) error { sizePolicy := getVMSizePolicy(vm, vmClass) if sizePolicy == nil { return fmt.Errorf( @@ -148,9 +135,9 @@ func validatePerCoreMemory(vm *v1alpha2.VirtualMachine, sp *v1alpha2.SizingPolic return } - // not have a default dividing :( - // dirty, I know - // wash your hands after read this + // Calculate memory portion per CPU core + // to compare it later with min and max + // limits in the sizing policy. vmPerCore := vm.Spec.Memory.Size.Value() / int64(vm.Spec.CPU.Cores) perCoreMemory := resource.NewQuantity(vmPerCore, resource.BinarySI) diff --git a/images/virtualization-artifact/pkg/controller/service/size_policy_service_test.go b/images/virtualization-artifact/pkg/controller/service/size_policy_service_test.go index 1f74f5bf1..bdce6ee6b 100644 --- a/images/virtualization-artifact/pkg/controller/service/size_policy_service_test.go +++ b/images/virtualization-artifact/pkg/controller/service/size_policy_service_test.go @@ -17,119 +17,61 @@ limitations under the License. package service_test import ( - "context" - "fmt" - . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "k8s.io/apimachinery/pkg/api/resource" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" "github.com/deckhouse/virtualization-controller/pkg/controller/service" v1alpha2 "github.com/deckhouse/virtualization/api/core/v1alpha2" ) -// vmClassValues stores mock values for VirtualMachineClass objects. -var vmClassValues map[string]client.Object - var _ = Describe("SizePolicyService", func() { - var mock *service.ClientMock - var ctx context.Context - - BeforeEach(func() { - mock = &service.ClientMock{} - mock.GetFunc = func(_ context.Context, key client.ObjectKey, obj client.Object, _ ...client.GetOption) error { - val, ok := vmClassValues[key.Name] - if !ok { - return fmt.Errorf("object not found") - } - - // Populate the incoming object's SizingPolicies from the mock data. - obj.(*v1alpha2.VirtualMachineClass).Spec.SizingPolicies = val.(*v1alpha2.VirtualMachineClass).Spec.SizingPolicies - - return nil - } - - // Initialize the mock data map. - vmClassValues = make(map[string]client.Object) - }) - - Context("when no value is provided", func() { - It("should return an error on Get()", func() { - val := v1alpha2.VirtualMachineClass{} - err := mock.Get(ctx, types.NamespacedName{Name: "vmclasstest"}, &val) - Expect(err).ShouldNot(BeNil()) - }) - }) - - Context("when value is provided", func() { - BeforeEach(func() { - // Set mock VM class data. - vmClassValues["vmclasstest"] = &v1alpha2.VirtualMachineClass{ - Spec: v1alpha2.VirtualMachineClassSpec{ - SizingPolicies: []v1alpha2.SizingPolicy{ - { - Cores: &v1alpha2.SizingPolicyCores{Min: 1, Max: 4}, - Memory: &v1alpha2.SizingPolicyMemory{ - MemoryMinMax: v1alpha2.MemoryMinMax{ - Min: resource.MustParse("1Gi"), - Max: resource.MustParse("4Gi"), - }, - }, - }, - }, - }, - } - }) - - It("should successfully find the value", func() { - val := v1alpha2.VirtualMachineClass{} - err := mock.Get(ctx, types.NamespacedName{Name: "vmclasstest"}, &val) - Expect(err).Should(BeNil()) - Expect(len(val.Spec.SizingPolicies)).Should(Equal(1)) - }) - }) + var vmClass *v1alpha2.VirtualMachineClass Context("when VM has no class", func() { + // Define a virtual machine with no class vm := &v1alpha2.VirtualMachine{ Spec: v1alpha2.VirtualMachineSpec{VirtualMachineClassName: ""}, } BeforeEach(func() { - // Set a default mock VM class. - vmClassValues["vmclasstest"] = &v1alpha2.VirtualMachineClass{ + // Initialize an empty virtual machine class + vmClass = &v1alpha2.VirtualMachineClass{ Spec: v1alpha2.VirtualMachineClassSpec{SizingPolicies: []v1alpha2.SizingPolicy{}}, } }) It("should fail validation due to empty class name", func() { - service := service.NewSizePolicyService(mock) - err := service.CheckVMMatchedSizePolicy(ctx, vm) + service := service.NewSizePolicyService() + err := service.CheckVMMatchedSizePolicy(vm, vmClass) + // Expect an error due to the empty class name Expect(err).ShouldNot(BeNil()) }) }) Context("when VM has a non-existent class", func() { + // Virtual machine with a non-existent class vm := &v1alpha2.VirtualMachine{ Spec: v1alpha2.VirtualMachineSpec{VirtualMachineClassName: "notexists"}, } BeforeEach(func() { - // Set a default mock VM class. - vmClassValues["vmclasstest"] = &v1alpha2.VirtualMachineClass{ + // Initialize a virtual machine class with empty policies + vmClass = &v1alpha2.VirtualMachineClass{ Spec: v1alpha2.VirtualMachineClassSpec{SizingPolicies: []v1alpha2.SizingPolicy{}}, } }) It("should fail validation due to non-existent class", func() { - service := service.NewSizePolicyService(mock) - err := service.CheckVMMatchedSizePolicy(ctx, vm) + service := service.NewSizePolicyService() + err := service.CheckVMMatchedSizePolicy(vm, vmClass) + // Expect an error due to the class not existing Expect(err).ShouldNot(BeNil()) }) }) Context("when VM's class has no valid size policy", func() { + // Virtual machine with non-matching CPU parameters vm := &v1alpha2.VirtualMachine{ Spec: v1alpha2.VirtualMachineSpec{ VirtualMachineClassName: "vmclasstest", @@ -138,8 +80,8 @@ var _ = Describe("SizePolicyService", func() { } BeforeEach(func() { - // Set mock VM class data with invalid policies for the VM. - vmClassValues["vmclasstest"] = &v1alpha2.VirtualMachineClass{ + // Initialize a virtual machine class with policies that do not match the VM's parameters + vmClass = &v1alpha2.VirtualMachineClass{ Spec: v1alpha2.VirtualMachineClassSpec{ SizingPolicies: []v1alpha2.SizingPolicy{ { @@ -151,13 +93,15 @@ var _ = Describe("SizePolicyService", func() { }) It("should fail validation due to invalid size policy", func() { - service := service.NewSizePolicyService(mock) - err := service.CheckVMMatchedSizePolicy(ctx, vm) + service := service.NewSizePolicyService() + err := service.CheckVMMatchedSizePolicy(vm, vmClass) + // Expect an error because the policies do not meet the VM's requirements Expect(err).ShouldNot(BeNil()) }) }) Context("when VM's class has correct policy without memory requirements", func() { + // Virtual machine with appropriate CPU parameters and no memory requirements vm := &v1alpha2.VirtualMachine{ Spec: v1alpha2.VirtualMachineSpec{ VirtualMachineClassName: "vmclasstest", @@ -166,8 +110,8 @@ var _ = Describe("SizePolicyService", func() { } BeforeEach(func() { - // Set mock VM class data with valid policies for the VM without memory requirements. - vmClassValues["vmclasstest"] = &v1alpha2.VirtualMachineClass{ + // Set mock VM class data with valid policies for the VM without memory requirements + vmClass = &v1alpha2.VirtualMachineClass{ Spec: v1alpha2.VirtualMachineClassSpec{ SizingPolicies: []v1alpha2.SizingPolicy{ { @@ -179,13 +123,15 @@ var _ = Describe("SizePolicyService", func() { }) It("should pass validation due to lack of memory requirements", func() { - service := service.NewSizePolicyService(mock) - err := service.CheckVMMatchedSizePolicy(ctx, vm) + service := service.NewSizePolicyService() + err := service.CheckVMMatchedSizePolicy(vm, vmClass) + // Expect no errors since there are no memory requirements Expect(err).Should(BeNil()) }) }) - Context("when VM's memory does not matched with policy", func() { + Context("when VM's memory does not match with policy", func() { + // Virtual machine with non-matching memory parameters vm := &v1alpha2.VirtualMachine{ Spec: v1alpha2.VirtualMachineSpec{ VirtualMachineClassName: "vmclasstest", @@ -195,8 +141,8 @@ var _ = Describe("SizePolicyService", func() { } BeforeEach(func() { - // Set mock VM class data with valid memory policies for the VM. - vmClassValues["vmclasstest"] = &v1alpha2.VirtualMachineClass{ + // Set mock VM class data with policies that match memory requirements for the VM + vmClass = &v1alpha2.VirtualMachineClass{ Spec: v1alpha2.VirtualMachineClassSpec{ SizingPolicies: []v1alpha2.SizingPolicy{ { @@ -213,14 +159,16 @@ var _ = Describe("SizePolicyService", func() { } }) - It("should pass validation due to match memory size", func() { - service := service.NewSizePolicyService(mock) - err := service.CheckVMMatchedSizePolicy(ctx, vm) + It("should pass validation due to matching memory size", func() { + service := service.NewSizePolicyService() + err := service.CheckVMMatchedSizePolicy(vm, vmClass) + // Expect no errors because the memory size does not match the policy Expect(err).Should(BeNil()) }) }) Context("when VM's memory matches the policy", func() { + // Virtual machine with matching memory parameters vm := &v1alpha2.VirtualMachine{ Spec: v1alpha2.VirtualMachineSpec{ VirtualMachineClassName: "vmclasstest", @@ -230,8 +178,8 @@ var _ = Describe("SizePolicyService", func() { } BeforeEach(func() { - // Set mock VM class data with valid memory policies for the VM. - vmClassValues["vmclasstest"] = &v1alpha2.VirtualMachineClass{ + // Set mock VM class data with valid memory policies for the VM + vmClass = &v1alpha2.VirtualMachineClass{ Spec: v1alpha2.VirtualMachineClassSpec{ SizingPolicies: []v1alpha2.SizingPolicy{ { @@ -249,13 +197,15 @@ var _ = Describe("SizePolicyService", func() { }) It("should pass validation due to matched memory size", func() { - service := service.NewSizePolicyService(mock) - err := service.CheckVMMatchedSizePolicy(ctx, vm) + service := service.NewSizePolicyService() + err := service.CheckVMMatchedSizePolicy(vm, vmClass) + // Expect no errors because the memory size matches the policy Expect(err).Should(BeNil()) }) }) Context("when class policy has empty memory requirements", func() { + // Virtual machine with memory size that matches an empty memory requirement policy vm := &v1alpha2.VirtualMachine{ Spec: v1alpha2.VirtualMachineSpec{ VirtualMachineClassName: "vmclasstest", @@ -265,9 +215,9 @@ var _ = Describe("SizePolicyService", func() { } BeforeEach(func() { - // Set mock VM class data with empty memory requirements. - vmClassValues["vmclasstest"] = &v1alpha2.VirtualMachineClass{ + vmClass = &v1alpha2.VirtualMachineClass{ Spec: v1alpha2.VirtualMachineClassSpec{ + // No specific memory policies defined SizingPolicies: []v1alpha2.SizingPolicy{ { Cores: &v1alpha2.SizingPolicyCores{Min: 1, Max: 4}, @@ -279,13 +229,15 @@ var _ = Describe("SizePolicyService", func() { }) It("should pass validation due to lack of memory requirements", func() { - service := service.NewSizePolicyService(mock) - err := service.CheckVMMatchedSizePolicy(ctx, vm) + service := service.NewSizePolicyService() + err := service.CheckVMMatchedSizePolicy(vm, vmClass) + // Expect no errors because there are no memory requirements Expect(err).Should(BeNil()) }) }) Context("when VM's memory is correct per core", func() { + // Virtual machine with memory size that adheres to per-core memory policies vm := &v1alpha2.VirtualMachine{ Spec: v1alpha2.VirtualMachineSpec{ VirtualMachineClassName: "vmclasstest", @@ -295,9 +247,9 @@ var _ = Describe("SizePolicyService", func() { } BeforeEach(func() { - // Set mock VM class data with valid per core memory policies for the VM. - vmClassValues["vmclasstest"] = &v1alpha2.VirtualMachineClass{ + vmClass = &v1alpha2.VirtualMachineClass{ Spec: v1alpha2.VirtualMachineClassSpec{ + // Setting policies with per-core memory requirements SizingPolicies: []v1alpha2.SizingPolicy{ { Cores: &v1alpha2.SizingPolicyCores{Min: 1, Max: 4}, @@ -315,14 +267,16 @@ var _ = Describe("SizePolicyService", func() { } }) - It("should pass validation due to matched per core memory size", func() { - service := service.NewSizePolicyService(mock) - err := service.CheckVMMatchedSizePolicy(ctx, vm) + It("should pass validation due to matched per-core memory size", func() { + service := service.NewSizePolicyService() + err := service.CheckVMMatchedSizePolicy(vm, vmClass) + // Expect no errors because the per-core memory size matches the policy Expect(err).Should(BeNil()) }) }) Context("when VM's memory is incorrect per core", func() { + // Virtual machine with incorrect per-core memory size vm := &v1alpha2.VirtualMachine{ Spec: v1alpha2.VirtualMachineSpec{ VirtualMachineClassName: "vmclasstest", @@ -332,8 +286,8 @@ var _ = Describe("SizePolicyService", func() { } BeforeEach(func() { - // Set mock VM class data with invalid per core memory policies for the VM. - vmClassValues["vmclasstest"] = &v1alpha2.VirtualMachineClass{ + // Set mock VM class data with invalid per-core memory policies for the VM + vmClass = &v1alpha2.VirtualMachineClass{ Spec: v1alpha2.VirtualMachineClassSpec{ SizingPolicies: []v1alpha2.SizingPolicy{ { @@ -352,14 +306,16 @@ var _ = Describe("SizePolicyService", func() { } }) - It("should fail validation due to non-matching per core memory size", func() { - service := service.NewSizePolicyService(mock) - err := service.CheckVMMatchedSizePolicy(ctx, vm) + It("should fail validation due to non-matching per-core memory size", func() { + service := service.NewSizePolicyService() + err := service.CheckVMMatchedSizePolicy(vm, vmClass) + // Expect an error because the per-core memory size does not match the policy Expect(err).ShouldNot(BeNil()) }) }) Context("when VM's core fraction is correct", func() { + // Virtual machine with a correct core fraction vm := &v1alpha2.VirtualMachine{ Spec: v1alpha2.VirtualMachineSpec{ VirtualMachineClassName: "vmclasstest", @@ -369,8 +325,8 @@ var _ = Describe("SizePolicyService", func() { } BeforeEach(func() { - // Set mock VM class data with valid core fraction policies for the VM. - vmClassValues["vmclasstest"] = &v1alpha2.VirtualMachineClass{ + // Set mock VM class data with valid core fraction policies for the VM + vmClass = &v1alpha2.VirtualMachineClass{ Spec: v1alpha2.VirtualMachineClassSpec{ SizingPolicies: []v1alpha2.SizingPolicy{ { @@ -383,13 +339,15 @@ var _ = Describe("SizePolicyService", func() { }) It("should pass validation due to matching core fraction", func() { - service := service.NewSizePolicyService(mock) - err := service.CheckVMMatchedSizePolicy(ctx, vm) + service := service.NewSizePolicyService() + err := service.CheckVMMatchedSizePolicy(vm, vmClass) + // Expect no errors because the core fraction matches the policy Expect(err).Should(BeNil()) }) }) Context("when VM's core fraction is incorrect", func() { + // Virtual machine with an incorrect core fraction vm := &v1alpha2.VirtualMachine{ Spec: v1alpha2.VirtualMachineSpec{ VirtualMachineClassName: "vmclasstest", @@ -399,8 +357,8 @@ var _ = Describe("SizePolicyService", func() { } BeforeEach(func() { - // Set mock VM class data with valid core fraction policies for the VM. - vmClassValues["vmclasstest"] = &v1alpha2.VirtualMachineClass{ + // Set mock VM class data with valid core fraction policies for the VM + vmClass = &v1alpha2.VirtualMachineClass{ Spec: v1alpha2.VirtualMachineClassSpec{ SizingPolicies: []v1alpha2.SizingPolicy{ { @@ -413,13 +371,15 @@ var _ = Describe("SizePolicyService", func() { }) It("should fail validation due to non-matching core fraction", func() { - service := service.NewSizePolicyService(mock) - err := service.CheckVMMatchedSizePolicy(ctx, vm) + service := service.NewSizePolicyService() + err := service.CheckVMMatchedSizePolicy(vm, vmClass) + // Expect an error because the core fraction does not match the policy Expect(err).ShouldNot(BeNil()) }) }) Context("when VM's memory step is correct", func() { + // Virtual machine with a correct memory step vm := &v1alpha2.VirtualMachine{ Spec: v1alpha2.VirtualMachineSpec{ VirtualMachineClassName: "vmclasstest", @@ -429,8 +389,8 @@ var _ = Describe("SizePolicyService", func() { } BeforeEach(func() { - // Set mock VM class data with valid memory step policies for the VM. - vmClassValues["vmclasstest"] = &v1alpha2.VirtualMachineClass{ + // Set mock VM class data with valid memory step policies for the VM + vmClass = &v1alpha2.VirtualMachineClass{ Spec: v1alpha2.VirtualMachineClassSpec{ SizingPolicies: []v1alpha2.SizingPolicy{ { @@ -448,14 +408,16 @@ var _ = Describe("SizePolicyService", func() { } }) - It("should pass validation due to match memory step", func() { - service := service.NewSizePolicyService(mock) - err := service.CheckVMMatchedSizePolicy(ctx, vm) + It("should pass validation due to matched memory step", func() { + service := service.NewSizePolicyService() + err := service.CheckVMMatchedSizePolicy(vm, vmClass) + // Expect no errors because the memory size matches the step policy Expect(err).Should(BeNil()) }) }) Context("when VM's memory step is incorrect", func() { + // Virtual machine with an incorrect memory step vm := &v1alpha2.VirtualMachine{ Spec: v1alpha2.VirtualMachineSpec{ VirtualMachineClassName: "vmclasstest", @@ -465,8 +427,8 @@ var _ = Describe("SizePolicyService", func() { } BeforeEach(func() { - // Set mock VM class data with invalid memory step policies for the VM. - vmClassValues["vmclasstest"] = &v1alpha2.VirtualMachineClass{ + // Set mock VM class data with invalid memory step policies for the VM + vmClass = &v1alpha2.VirtualMachineClass{ Spec: v1alpha2.VirtualMachineClassSpec{ SizingPolicies: []v1alpha2.SizingPolicy{ { @@ -485,13 +447,15 @@ var _ = Describe("SizePolicyService", func() { }) It("should fail validation due to non-matching memory step", func() { - service := service.NewSizePolicyService(mock) - err := service.CheckVMMatchedSizePolicy(ctx, vm) + service := service.NewSizePolicyService() + err := service.CheckVMMatchedSizePolicy(vm, vmClass) + // Expect an error because the memory size does not match the step policy Expect(err).ShouldNot(BeNil()) }) }) Context("when VM's per core memory step is correct", func() { + // Virtual machine with a correct per-core memory step vm := &v1alpha2.VirtualMachine{ Spec: v1alpha2.VirtualMachineSpec{ VirtualMachineClassName: "vmclasstest", @@ -501,8 +465,7 @@ var _ = Describe("SizePolicyService", func() { } BeforeEach(func() { - // Set mock VM class data with valid per core memory step policies for the VM. - vmClassValues["vmclasstest"] = &v1alpha2.VirtualMachineClass{ + vmClass = &v1alpha2.VirtualMachineClass{ Spec: v1alpha2.VirtualMachineClassSpec{ SizingPolicies: []v1alpha2.SizingPolicy{ { @@ -523,13 +486,15 @@ var _ = Describe("SizePolicyService", func() { }) It("should pass validation due to match per core memory step", func() { - service := service.NewSizePolicyService(mock) - err := service.CheckVMMatchedSizePolicy(ctx, vm) + service := service.NewSizePolicyService() + err := service.CheckVMMatchedSizePolicy(vm, vmClass) + // Expect no errors because the per-core memory size matches the step policy Expect(err).Should(BeNil()) }) }) Context("when VM's per core memory step is incorrect", func() { + // Virtual machine with an incorrect per-core memory step vm := &v1alpha2.VirtualMachine{ Spec: v1alpha2.VirtualMachineSpec{ VirtualMachineClassName: "vmclasstest", @@ -539,8 +504,8 @@ var _ = Describe("SizePolicyService", func() { } BeforeEach(func() { - // Set mock VM class data with invalid per core memory step policies for the VM. - vmClassValues["vmclasstest"] = &v1alpha2.VirtualMachineClass{ + // Set mock VM class data with invalid per-core memory step policies for the VM + vmClass = &v1alpha2.VirtualMachineClass{ Spec: v1alpha2.VirtualMachineClassSpec{ SizingPolicies: []v1alpha2.SizingPolicy{ { @@ -561,8 +526,9 @@ var _ = Describe("SizePolicyService", func() { }) It("should fail validation due to non-matching per core memory step", func() { - service := service.NewSizePolicyService(mock) - err := service.CheckVMMatchedSizePolicy(ctx, vm) + service := service.NewSizePolicyService() + err := service.CheckVMMatchedSizePolicy(vm, vmClass) + // Expect an error because the per-core memory size does not match the step policy Expect(err).ShouldNot(BeNil()) }) }) diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/validators/sizing_policy_validator.go b/images/virtualization-artifact/pkg/controller/vm/internal/validators/sizing_policy_validator.go index f4a1106cd..2947b51ff 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/validators/sizing_policy_validator.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/validators/sizing_policy_validator.go @@ -18,28 +18,60 @@ package validators import ( "context" + "fmt" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" "github.com/deckhouse/virtualization-controller/pkg/controller/service" + "github.com/deckhouse/virtualization-controller/pkg/logger" "github.com/deckhouse/virtualization/api/core/v1alpha2" ) type SizingPolicyValidator struct { + client client.Client service *service.SizePolicyService } func NewSizingPolicyValidator(client client.Client) *SizingPolicyValidator { return &SizingPolicyValidator{ - service: service.NewSizePolicyService(client), + client: client, + service: service.NewSizePolicyService(), } } func (v *SizingPolicyValidator) ValidateCreate(ctx context.Context, vm *v1alpha2.VirtualMachine) (admission.Warnings, error) { - return nil, v.service.CheckVMMatchedSizePolicy(ctx, vm) + return v.validate(ctx, vm) } func (v *SizingPolicyValidator) ValidateUpdate(ctx context.Context, _, newVM *v1alpha2.VirtualMachine) (admission.Warnings, error) { - return nil, v.service.CheckVMMatchedSizePolicy(ctx, newVM) + return v.validate(ctx, newVM) +} + +func (v *SizingPolicyValidator) validate(ctx context.Context, vm *v1alpha2.VirtualMachine) (admission.Warnings, error) { + var warnings admission.Warnings + vmClass := &v1alpha2.VirtualMachineClass{} + err := v.client.Get(ctx, types.NamespacedName{ + Name: vm.Spec.VirtualMachineClassName, + }, vmClass) + if err != nil { + if errors.IsNotFound(err) { + warnings = append(warnings, fmt.Sprintf( + "The VM class %q does not exist; it may not have been created yet. Until it is created, the virtual machine will remain in a pending status.", + vm.Spec.VirtualMachineClassName, + )) + return warnings, nil + } else { + log := logger.FromContext(ctx) + log.Error( + "An error occurred while retrieving the VM class.", + logger.SlogErr(err), + ) + return nil, err + } + } + + return nil, v.service.CheckVMMatchedSizePolicy(vm, vmClass) } diff --git a/werf.yaml b/werf.yaml index 2584d6d6d..145dd3903 100644 --- a/werf.yaml +++ b/werf.yaml @@ -26,6 +26,19 @@ configVersion: 1 {{- end }} {{- end }} + +# Distroless altlinux Images +{{- $AltDistroVirtImagesPath := "base-images/alt_image_versions.yml" }} +{{ $baseImages := (.Files.Get $AltDistroVirtImagesPath | fromYaml) }} + + {{- range $k, $v := $baseImages }} + {{ $altDistroVirtImagePath := (printf "%s%s" $baseImages.REGISTRY_PATH (trimSuffix "/" $v)) }} + + {{- if ne $k "REGISTRY_PATH" }} + {{- $_ := set $.Images $k $altDistroVirtImagePath }} + {{- end }} + + {{- end }} # Modules_images {{- define "module_image_template" }} {{- if eq .ImageInstructionType "Dockerfile" }}