From 70e5c70c7f6dd42004ab5f70e92b5dbc1ab93d33 Mon Sep 17 00:00:00 2001 From: Dominik Przybyl Date: Sun, 29 Sep 2024 23:08:44 +0200 Subject: [PATCH] added handle for multiple instances for push, copy command --- cmd/aem/content.go | 37 +++++++++------- pkg/content_manager.go | 98 +++++++++++++++++++++--------------------- 2 files changed, 71 insertions(+), 64 deletions(-) diff --git a/cmd/aem/content.go b/cmd/aem/content.go index 7ad87b09..ea459f82 100644 --- a/cmd/aem/content.go +++ b/cmd/aem/content.go @@ -178,7 +178,7 @@ func (c *CLI) contentPushCmd() *cobra.Command { Aliases: []string{"ps"}, Short: "Push content from JCR root directory or local file to running instance", Run: func(cmd *cobra.Command, args []string) { - instance, err := c.aem.InstanceManager().One() + instances, err := c.aem.InstanceManager().Some() if err != nil { c.Error(err) return @@ -201,7 +201,7 @@ func (c *CLI) contentPushCmd() *cobra.Command { excludePatterns := determineExcludePatterns(cmd) clean, _ := cmd.Flags().GetBool("clean") vault, _ := cmd.Flags().GetBool("vault") - if err = c.aem.ContentManager().Push(instance, path, clean, vault, pkg.PackageCreateOpts{ + if err = c.aem.ContentManager().Push(instances, path, clean, vault, pkg.PackageCreateOpts{ PID: fmt.Sprintf("aemc:content-push:%s-SNAPSHOT", timex.FileTimestampForNow()), FilterRoots: filterRoots, ExcludePatterns: excludePatterns, @@ -238,7 +238,7 @@ func (c *CLI) contentCopyCmd() *cobra.Command { c.Error(err) return } - targetInstance, err := determineContentTargetInstance(cmd, c.aem.InstanceManager()) + targetInstances, err := determineContentTargetInstances(cmd, c.aem.InstanceManager()) if err != nil { c.Error(err) return @@ -248,7 +248,7 @@ func (c *CLI) contentCopyCmd() *cobra.Command { clean, _ := cmd.Flags().GetBool("clean") vault, _ := cmd.Flags().GetBool("vault") rcpArgs, _ := cmd.Flags().GetString("rcp-args") - if err = c.aem.ContentManager().Copy(instance, targetInstance, clean, vault, rcpArgs, pkg.PackageCreateOpts{ + if err = c.aem.ContentManager().Copy(instance, targetInstances, clean, vault, rcpArgs, pkg.PackageCreateOpts{ PID: fmt.Sprintf("aemc:content-copy:%s-SNAPSHOT", timex.FileTimestampForNow()), FilterRoots: filterRoots, FilterFile: filterFile, @@ -259,8 +259,8 @@ func (c *CLI) contentCopyCmd() *cobra.Command { c.Changed("content copied") }, } - cmd.Flags().StringP("instance-target-url", "u", "", "Destination instance URL") - cmd.Flags().StringP("instance-target-id", "i", "", "Destination instance ID") + cmd.Flags().StringSliceP("instance-target-url", "u", []string{}, "Destination instance URL") + cmd.Flags().StringSliceP("instance-target-id", "i", []string{}, "Destination instance ID") cmd.MarkFlagsOneRequired("instance-target-url", "instance-target-id") cmd.Flags().StringSliceP("filter-roots", "r", []string{}, "Vault filter root paths") cmd.Flags().StringP("filter-file", "f", "", "Vault filter file path") @@ -271,20 +271,25 @@ func (c *CLI) contentCopyCmd() *cobra.Command { return cmd } -func determineContentTargetInstance(cmd *cobra.Command, instanceManager *pkg.InstanceManager) (*pkg.Instance, error) { - var instance *pkg.Instance - url, _ := cmd.Flags().GetString("instance-target-url") - if url != "" { - instance, _ = instanceManager.NewByIDAndURL("remote_adhoc_target", url) +func determineContentTargetInstances(cmd *cobra.Command, instanceManager *pkg.InstanceManager) ([]pkg.Instance, error) { + var instances []pkg.Instance + urls, _ := cmd.Flags().GetStringSlice("instance-target-url") + for _, url := range urls { + instance, err := instanceManager.NewByIDAndURL("remote_adhoc_target", url) + if err != nil { + return nil, err + } + instances = append(instances, *instance) } - id, _ := cmd.Flags().GetString("instance-target-id") - if id != "" { - instance = instanceManager.NewByID(id) + ids, _ := cmd.Flags().GetStringSlice("instance-target-id") + for _, id := range ids { + instance := instanceManager.NewByID(id) + instances = append(instances, *instance) } - if instance == nil { + if instances == nil { return nil, fmt.Errorf("missing 'instance-target-url' or 'instance-target-id'") } - return instance, nil + return instances, nil } func determineContentDir(cmd *cobra.Command) (string, error) { diff --git a/pkg/content_manager.go b/pkg/content_manager.go index 68c6b059..24a53fbc 100644 --- a/pkg/content_manager.go +++ b/pkg/content_manager.go @@ -148,27 +148,33 @@ func (cm *ContentManager) PullFile(instance *Instance, file string, clean bool, return nil } -func (cm *ContentManager) pushContent(instance *Instance, vault bool, opts PackageCreateOpts) error { - if vault { - mainDir, _, _ := strings.Cut(opts.ContentPath, content.JCRRoot) - jcrPath := DetermineFilterRoot(opts.ContentPath) - if err := cm.vaultCli.PushContent(instance, mainDir, jcrPath); err != nil { - return err - } - } else { - remotePath, err := instance.PackageManager().Create(opts) - defer func() { _ = instance.PackageManager().Delete(remotePath) }() - if err != nil { - return err - } - if err = instance.PackageManager().Install(remotePath); err != nil { - return err +func (cm *ContentManager) pushContent(instances []Instance, vault bool, opts PackageCreateOpts) error { + _, err := InstanceProcess(cm.aem, instances, func(instance Instance) (any, error) { + if vault { + mainDir, _, _ := strings.Cut(opts.ContentPath, content.JCRRoot) + jcrPath := DetermineFilterRoot(opts.ContentPath) + if err := cm.vaultCli.PushContent(&instance, mainDir, jcrPath); err != nil { + return nil, err + } + } else { + remotePath, err := instance.PackageManager().Create(opts) + defer func() { _ = instance.PackageManager().Delete(remotePath) }() + if err != nil { + return nil, err + } + if err = instance.PackageManager().Install(remotePath); err != nil { + return nil, err + } } + return nil, nil + }) + if err != nil { + return err } return nil } -func (cm *ContentManager) Push(instance *Instance, path string, clean bool, vault bool, opts PackageCreateOpts) error { +func (cm *ContentManager) Push(instances []Instance, path string, clean bool, vault bool, opts PackageCreateOpts) error { if !pathx.Exists(path) { return fmt.Errorf("cannot push content as it does not exist '%s'", path) } @@ -185,46 +191,36 @@ func (cm *ContentManager) Push(instance *Instance, path string, clean bool, vaul } opts.ContentPath = filepath.Join(workDir, content.JCRRoot) } - if err := cm.pushContent(instance, vault, opts); err != nil { + if err := cm.pushContent(instances, vault, opts); err != nil { return err } return nil } -func (cm *ContentManager) copyByPkgMgr(srcInstance *Instance, destInstance *Instance, clean bool, opts PackageCreateOpts) error { +func (cm *ContentManager) copyByPkgMgr(srcInstance *Instance, destInstances []Instance, clean bool, opts PackageCreateOpts) error { pkgFile := pathx.RandomFileName(cm.tmpDir(), "content_copy", ".zip") defer func() { _ = pathx.DeleteIfExists(pkgFile) }() - if clean { - workDir := pathx.RandomDir(cm.tmpDir(), "content_copy") - defer func() { _ = pathx.DeleteIfExists(workDir) }() - if err := cm.pullContent(srcInstance, workDir, false, opts); err != nil { - return err - } - if clean { - if err := cm.contentManager.Clean(filepath.Join(workDir, content.JCRRoot)); err != nil { - return err - } + if err := cm.Download(srcInstance, pkgFile, clean, false, opts); err != nil { + return err + } + _, err := InstanceProcess(cm.aem, destInstances, func(destInstance Instance) (any, error) { + remotePath, err := destInstance.PackageManager().Upload(pkgFile) + defer func() { _ = destInstance.PackageManager().Delete(remotePath) }() + if err != nil { + return nil, err } - if err := content.Zip(workDir, pkgFile); err != nil { - return err + if err = destInstance.PackageManager().Install(remotePath); err != nil { + return nil, err } - } else { - if err := cm.downloadByPkgMgr(srcInstance, pkgFile, opts); err != nil { - return err - } - } - remotePath, err := destInstance.PackageManager().Upload(pkgFile) - defer func() { _ = destInstance.PackageManager().Delete(remotePath) }() + return nil, err + }) if err != nil { return err } - if err = destInstance.PackageManager().Install(remotePath); err != nil { - return err - } return nil } -func (cm *ContentManager) copyByVaultCli(srcInstance *Instance, destInstance *Instance, clean bool, rcpArgs string, opts PackageCreateOpts) error { +func (cm *ContentManager) copyByVaultCli(srcInstance *Instance, destInstances []Instance, clean bool, rcpArgs string, opts PackageCreateOpts) error { if clean || opts.FilterFile != "" { workDir := pathx.RandomDir(cm.tmpDir(), "content_copy") defer func() { _ = pathx.DeleteIfExists(workDir) }() @@ -237,27 +233,33 @@ func (cm *ContentManager) copyByVaultCli(srcInstance *Instance, destInstance *In } } opts.ContentPath = filepath.Join(workDir, content.JCRRoot) - if err := cm.pushContent(destInstance, true, opts); err != nil { + if err := cm.pushContent(destInstances, true, opts); err != nil { return err } } else { if rcpArgs == "" { rcpArgs = "-b 100 -r -u" } - for _, filterRoot := range opts.FilterRoots { - if err := cm.vaultCli.CopyContent(srcInstance, destInstance, strings.Fields(rcpArgs), filterRoot); err != nil { - return err + _, err := InstanceProcess(cm.aem, destInstances, func(destInstance Instance) (any, error) { + for _, filterRoot := range opts.FilterRoots { + if err := cm.vaultCli.CopyContent(srcInstance, &destInstance, strings.Fields(rcpArgs), filterRoot); err != nil { + return nil, err + } } + return nil, nil + }) + if err != nil { + return err } } return nil } -func (cm *ContentManager) Copy(srcInstance *Instance, destInstance *Instance, clean bool, vault bool, rcpArgs string, opts PackageCreateOpts) error { +func (cm *ContentManager) Copy(srcInstance *Instance, destInstances []Instance, clean bool, vault bool, rcpArgs string, opts PackageCreateOpts) error { if vault { - return cm.copyByVaultCli(srcInstance, destInstance, clean, rcpArgs, opts) + return cm.copyByVaultCli(srcInstance, destInstances, clean, rcpArgs, opts) } - return cm.copyByPkgMgr(srcInstance, destInstance, clean, opts) + return cm.copyByPkgMgr(srcInstance, destInstances, clean, opts) } func DetermineSyncFile(file string) string {