diff --git a/cloud/services/compute/instance/cloudinit.go b/cloud/services/compute/instance/cloudinit.go index 8520f09..e46bd87 100644 --- a/cloud/services/compute/instance/cloudinit.go +++ b/cloud/services/compute/instance/cloudinit.go @@ -11,27 +11,55 @@ import ( "github.com/sp-yduck/cluster-api-provider-proxmox/cloud/scope" ) -// reconcileCloudInit -func reconcileCloudInit(s *Service, vmid int, bootstrap string) error { - vmName := s.scope.Name() - storageName := s.scope.GetStorage().Name - cloudInit := s.scope.GetCloudInit() +const ( + userSnippetPathFormat = "snippets/%s-user.yml" +) +// reconcileCloudInit +func (s *Service) reconcileCloudInit(bootstrap string) error { // user - if err := reconcileCloudInitUser(vmid, vmName, storageName, bootstrap, *cloudInit.User, s.remote); err != nil { + if err := s.reconcileCloudInitUser(bootstrap); err != nil { return err } return nil } -func reconcileCloudInitUser(vmid int, vmName, storageName, bootstrap string, config infrav1.User, ssh scope.SSHClient) error { - base := baseUserData(vmName) +// delete CloudConfig +func (s *Service) deleteCloudConfig() error { + storageName := s.scope.GetStorage().Name + path := userSnippetPath(s.scope.Name()) + volumeID := fmt.Sprintf("%s:%s", storageName, path) + + node, err := s.client.Node(s.scope.NodeName()) + if err != nil { + return err + } + storage, err := node.Storage(storageName) + if err != nil { + return err + } + content, err := storage.GetContent(volumeID) + if IsNotFound(err) { // return nil if it's already deleted + return nil + } + if err != nil { + return err + } + + return content.DeleteVolume() +} + +func (s *Service) reconcileCloudInitUser(bootstrap string) error { + vmName := s.scope.Name() + storagePath := s.scope.GetStorage().Path + config := s.scope.GetCloudInit().User bootstrapConfig, err := cloudinit.ParseUser(bootstrap) if err != nil { return err } - additional, err := cloudinit.MergeUsers(config, base) + base := baseUserData(vmName) + additional, err := cloudinit.MergeUsers(*config, base) if err != nil { return err } @@ -47,8 +75,7 @@ func reconcileCloudInitUser(vmid int, vmName, storageName, bootstrap string, con klog.Info(configYaml) // to do: should be set via API - // to do: storage path - out, err := ssh.RunWithStdin(fmt.Sprintf("tee /var/lib/vz/%s/snippets/%s-user.yml", storageName, vmName), configYaml) + out, err := s.remote.RunWithStdin(fmt.Sprintf("tee %s/%s", storagePath, userSnippetPath(vmName)), configYaml) if err != nil { return errors.Errorf("ssh command error : %s : %v", out, err) } @@ -56,6 +83,10 @@ func reconcileCloudInitUser(vmid int, vmName, storageName, bootstrap string, con return nil } +func userSnippetPath(vmName string) string { + return fmt.Sprintf(userSnippetPathFormat, vmName) +} + // DEPRECATED : cicustom should be set via API func ApplyCICustom(vmid int, vmName, storageName, ciType string, ssh scope.SSHClient) error { if !cloudinit.IsValidType(ciType) { diff --git a/cloud/services/compute/instance/qemu.go b/cloud/services/compute/instance/qemu.go index 1b915a7..96a4035 100644 --- a/cloud/services/compute/instance/qemu.go +++ b/cloud/services/compute/instance/qemu.go @@ -129,7 +129,7 @@ func generateVMOptions(vmName, storageName string, network infrav1.Network, hard NameServer: network.NameServer, Boot: "order=scsi0", Ide: vm.Ide{Ide2: fmt.Sprintf("file=%s:cloudinit,media=cdrom", storageName)}, - CiCustom: fmt.Sprintf("user=%s:snippets/%s-user.yml", storageName, vmName), + CiCustom: fmt.Sprintf("user=%s:%s", storageName, userSnippetPath(vmName)), IPConfig: vm.IPConfig{IPConfig0: network.IPConfig.String()}, OSType: vm.L26, Net: vm.Net{Net0: "model=virtio,bridge=vmbr0,firewall=1"}, diff --git a/cloud/services/compute/instance/reconcile.go b/cloud/services/compute/instance/reconcile.go index ec95921..1eea51b 100644 --- a/cloud/services/compute/instance/reconcile.go +++ b/cloud/services/compute/instance/reconcile.go @@ -61,6 +61,13 @@ func (s *Service) Delete(ctx context.Context) error { if err := EnsureStoppedOrPaused(*instance); err != nil { return err } + + // delete cloud-config file + if err := s.deleteCloudConfig(); err != nil { + return err + } + + // delete qemu return instance.Delete() } @@ -200,7 +207,7 @@ func (s *Service) CreateInstance(ctx context.Context, bootstrap string) (*vm.Vir log.Info(fmt.Sprintf("reconciled qemu: node=%s,vmid=%d", vm.Node.Name(), vmid)) // cloud init - if err := reconcileCloudInit(s, vmid, bootstrap); err != nil { + if err := s.reconcileCloudInit(bootstrap); err != nil { return nil, err } diff --git a/cloud/services/compute/storage/reconcile.go b/cloud/services/compute/storage/reconcile.go index ae695d6..7076012 100644 --- a/cloud/services/compute/storage/reconcile.go +++ b/cloud/services/compute/storage/reconcile.go @@ -28,7 +28,10 @@ func (s *Service) Reconcile(ctx context.Context) error { } func (s *Service) Delete(ctx context.Context) error { - // to do + // return s.deleteStorage(ctx) + // not worthy to delete Storage + // since deleting Storage will block vm deletion + // and does not delete actual content in the node return nil } @@ -62,6 +65,26 @@ func (s *Service) createStorage(options storage.StorageCreateOptions) error { return nil } +func (s *Service) deleteStorage(ctx context.Context) error { + log := log.FromContext(ctx) + nodes, err := s.client.Nodes() + if err != nil { + return err + } + for _, node := range nodes { + storage, err := node.Storage(s.scope.Storage().Name) + if err != nil { + log.Info(err.Error()) + continue + } + if _, err := storage.Delete(); err != nil { + log.Info(err.Error()) + return err + } + } + return nil +} + func generateVMStorageOptions(scope Scope) storage.StorageCreateOptions { storageSpec := scope.Storage() options := storage.StorageCreateOptions{ diff --git a/controllers/proxmoxcluster_controller.go b/controllers/proxmoxcluster_controller.go index 8af7298..1739f71 100644 --- a/controllers/proxmoxcluster_controller.go +++ b/controllers/proxmoxcluster_controller.go @@ -144,7 +144,7 @@ func (r *ProxmoxClusterReconciler) reconcileDelete(ctx context.Context, clusterS log.Info("Reconciling Delete ProxmoxCluster") reconcilers := []cloud.Reconciler{ - // to do + storage.NewService(clusterScope), } for _, r := range reconcilers { diff --git a/go.mod b/go.mod index 016acb9..7630dce 100644 --- a/go.mod +++ b/go.mod @@ -7,12 +7,13 @@ require ( github.com/onsi/ginkgo/v2 v2.9.2 github.com/onsi/gomega v1.27.5 github.com/pkg/errors v0.9.1 - github.com/sp-yduck/proxmox v0.0.0-20230627144956-64b565d07db7 + github.com/sp-yduck/proxmox v0.0.0-20230702124708-d086ca37fd8f golang.org/x/crypto v0.9.0 gopkg.in/yaml.v3 v3.0.1 k8s.io/api v0.26.1 k8s.io/apimachinery v0.26.1 k8s.io/client-go v0.26.1 + k8s.io/klog/v2 v2.80.1 k8s.io/utils v0.0.0-20221128185143-99ec85e7a448 sigs.k8s.io/cluster-api v1.4.1 sigs.k8s.io/controller-runtime v0.14.5 @@ -72,7 +73,6 @@ require ( gopkg.in/yaml.v2 v2.4.0 // indirect k8s.io/apiextensions-apiserver v0.26.1 // indirect k8s.io/component-base v0.26.1 // indirect - k8s.io/klog/v2 v2.80.1 // indirect k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect diff --git a/go.sum b/go.sum index c9dc12b..742bf04 100644 --- a/go.sum +++ b/go.sum @@ -288,8 +288,8 @@ github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5g github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/sp-yduck/proxmox v0.0.0-20230627144956-64b565d07db7 h1:y2VI0xIOh35Dl3vKdbns6TVwe6ReSw4Akyr5qUVyUWU= -github.com/sp-yduck/proxmox v0.0.0-20230627144956-64b565d07db7/go.mod h1:VIKtGZXlx0nO9Y+K2vJ4z3rJLkZ3v0OvTnKbO22EnL4= +github.com/sp-yduck/proxmox v0.0.0-20230702124708-d086ca37fd8f h1:n32eSWqWLtjk+jb4B1Ok+W5KoAxuYuouEkXjumqySXI= +github.com/sp-yduck/proxmox v0.0.0-20230702124708-d086ca37fd8f/go.mod h1:VIKtGZXlx0nO9Y+K2vJ4z3rJLkZ3v0OvTnKbO22EnL4= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=