From 49ead5de73be87eeacc3ed15d1ba77f806f377fd Mon Sep 17 00:00:00 2001 From: amithk Date: Wed, 4 Nov 2026 14:49:41 +0530 Subject: [PATCH] JFMIG-82 - Remove data-transfer plugin dependency from transfer-files; deprecate transfer-plugin-install --- .github/workflows/transferTests.yml | 4 +- CONTRIBUTING.md | 1 - artifactory/cli.go | 39 +------ artifactory/cli_test.go | 22 ++++ docs/artifactory/transferfiles/help.go | 5 +- .../artifactory/transferplugininstall/help.go | 25 ++-- go.mod | 2 +- go.sum | 4 +- transfer_test.go | 10 -- utils/cliutils/commandsflags.go | 6 +- utils/tests/utils.go | 108 +++++++++--------- 11 files changed, 98 insertions(+), 128 deletions(-) diff --git a/.github/workflows/transferTests.yml b/.github/workflows/transferTests.yml index 8ecf5981a..0aab83bb7 100644 --- a/.github/workflows/transferTests.yml +++ b/.github/workflows/transferTests.yml @@ -68,7 +68,7 @@ jobs: - name: Run transfer tests if: matrix.os.name != 'macos' run: >- - go test -v github.com/jfrog/jfrog-cli --timeout 0 --test.transfer --test.installDataTransferPlugin + go test -v github.com/jfrog/jfrog-cli --timeout 0 --test.transfer --jfrog.url=${{ env.JFROG_TESTS_URL || 'http://127.0.0.1:8082' }} --jfrog.adminToken=${{ env.JFROG_TESTS_LOCAL_ACCESS_TOKEN }} --jfrog.targetUrl=${{ secrets.PLATFORM_URL }} @@ -121,7 +121,7 @@ jobs: - name: Run transfer tests run: >- - go test -v github.com/jfrog/jfrog-cli --timeout 0 --test.transfer --test.installDataTransferPlugin + go test -v github.com/jfrog/jfrog-cli --timeout 0 --test.transfer --jfrog.targetUrl=${{ secrets.PLATFORM_URL }} --jfrog.targetAdminToken=${{ secrets.PLATFORM_ADMIN_TOKEN }} --jfrog.home=${{ runner.temp }} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index af119d768..bca8ca184 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -279,7 +279,6 @@ The Transfer tests execute `transfer-files` commands between a local Artifactory | `-jfrog.targetUrl` | JFrog target platform URL. | | `-jfrog.targetAdminToken` | JFrog target platform admin token. | | `-jfrog.jfrogHome` | The JFrog home directory of the local Artifactory installation. | -| `-jfrog.installDataTransferPlugin` | Set this flag to `true` if you want the test to automatically install the data-transfer plugin in the source Artifactory server. | To run Transfer tests, execute the following command: diff --git a/artifactory/cli.go b/artifactory/cli.go index 8160ff3eb..e311b6a24 100644 --- a/artifactory/cli.go +++ b/artifactory/cli.go @@ -15,8 +15,6 @@ import ( "github.com/jfrog/jfrog-cli/utils/accesstoken" - "github.com/jfrog/gofrog/version" - "github.com/jfrog/jfrog-cli-core/v2/artifactory/commands/transferinstall" "github.com/jfrog/jfrog-cli/docs/artifactory/transferplugininstall" "github.com/jfrog/jfrog-cli-artifactory/artifactory/commands/generic" @@ -557,6 +555,7 @@ func GetCommands() []cli.Command { BashComplete: corecommon.CreateBashCompletionFunc(), Action: dataTransferPluginInstallCmd, Category: transferCategory, + Hidden: true, }, }) } @@ -1245,38 +1244,10 @@ func buildTransferConfigMergeResult(csvPath string, originalErr error) transferC } } -func dataTransferPluginInstallCmd(c *cli.Context) error { - // Get the Artifactory serverID from the argument or use default if not exists - serverID := "" - if c.NArg() > 1 { - return cliutils.WrongNumberOfArgumentsHandler(c) - } else if c.NArg() == 1 { - serverID = c.Args()[0] - } - serverDetails, err := coreConfig.GetSpecificConfig(serverID, true, true) - if err != nil { - return err - } - installCmd := transferinstall.NewInstallDataTransferCommand(serverDetails) - // Optional flags - versionToInstall := c.String(cliutils.Version) - if versionToInstall != "" { - installCmd.SetInstallVersion(version.NewVersion(versionToInstall)) - } - sourceFilesPath := c.String(cliutils.InstallPluginSrcDir) - if sourceFilesPath != "" { - installCmd.SetLocalPluginFiles(sourceFilesPath) - } - - if versionToInstall != "" && sourceFilesPath != "" { - return cliutils.PrintHelpAndReturnError("Only version or dir is allowed, not both.", c) - } - - homePath := c.String(cliutils.InstallPluginHomeDir) - if homePath != "" { - installCmd.SetJFrogHomePath(homePath) - } - return commands.Exec(installCmd) +func dataTransferPluginInstallCmd(_ *cli.Context) error { + log.Warn("The 'transfer-plugin-install' command is deprecated and no longer installs the data-transfer user plugin. " + + "'jf rt transfer-files' does not require the plugin on the source Artifactory. This command will be removed in a future release.") + return nil } func transferFilesCmd(c *cli.Context) error { diff --git a/artifactory/cli_test.go b/artifactory/cli_test.go index cab47779e..5299d35fd 100644 --- a/artifactory/cli_test.go +++ b/artifactory/cli_test.go @@ -222,6 +222,28 @@ func newTransferFilesFormatContext(formatVal string) *cli.Context { return cli.NewContext(app, fs, nil) } +func TestTransferPluginInstallIsHiddenAndDeprecated(t *testing.T) { + var found bool + for _, cmd := range GetCommands() { + if cmd.Name != "transfer-plugin-install" { + continue + } + found = true + assert.True(t, cmd.Hidden) + assert.Contains(t, cmd.Usage, "[DEPRECATED]") + } + assert.True(t, found, "transfer-plugin-install command should remain registered to inform users that the plugin is no longer required") +} + +func TestTransferPluginInstallOnlyWarns(t *testing.T) { + // A non-existent server ID and conflicting flags would fail if the command still attempted an installation. + set := flag.NewFlagSet("transfer-plugin-install", flag.ContinueOnError) + set.String(cliutils.Version, "", "") + set.String(cliutils.InstallPluginSrcDir, "", "") + require.NoError(t, set.Parse([]string{"--version=1.0.0", "--dir=/non/existent", "no-such-server-id", "extra-arg"})) + assert.NoError(t, dataTransferPluginInstallCmd(cli.NewContext(nil, set, nil))) +} + // --------------------------------------------------------------------------- // GetOutputFormat (transfer-files) tests // --------------------------------------------------------------------------- diff --git a/docs/artifactory/transferfiles/help.go b/docs/artifactory/transferfiles/help.go index fa4f7de2c..f9d50d302 100644 --- a/docs/artifactory/transferfiles/help.go +++ b/docs/artifactory/transferfiles/help.go @@ -24,7 +24,6 @@ When to use: Prerequisites: - Both source and target server IDs configured with admin tokens. - 'jf rt transfer-config' (or transfer-config-merge) already run so repos exist on the target. -- 'jf rt transfer-plugin-install' installed on the source server's primary node. - 'jf rt transfer-settings' tuned for throughput. Common patterns: @@ -33,12 +32,12 @@ Common patterns: $ jf rt transfer-files source-prod target-cloud --status # check progress Gotchas: -- Requires the data-transfer plugin on the source (install via 'jf rt transfer-plugin-install'). +- Does not require the data-transfer user plugin on the source; 'jf rt transfer-plugin-install' is deprecated. - Long-running; expect hours-to-days for large stores. Run inside a long-lived session (nohup, tmux, screen). - Throughput is governed by 'jf rt transfer-settings'; defaults are conservative. - Idempotent on file content but not on repo property changes; re-running after a target-side delete causes redelivery. -Related: jf rt transfer-config, jf rt transfer-settings, jf rt transfer-plugin-install +Related: jf rt transfer-config, jf rt transfer-settings QA: Q: What's the JFrog CLI command to transfer the configuration from my artifactory to the target artifactory? diff --git a/docs/artifactory/transferplugininstall/help.go b/docs/artifactory/transferplugininstall/help.go index e80f3701c..bb34cf6e5 100644 --- a/docs/artifactory/transferplugininstall/help.go +++ b/docs/artifactory/transferplugininstall/help.go @@ -3,38 +3,27 @@ package transferplugininstall var Usage = []string{"rt transfer-plugin-install [command options]"} func GetDescription() string { - return "Download and install the data-transfer user plugin on the primary node of Artifactory, which is running on this local machine." + return "[DEPRECATED] This command no longer installs the data-transfer user plugin and only prints a deprecation warning. 'jf rt transfer-files' does not require the plugin." } func GetArguments() string { return ` server-id - The ID of the source server, on which the plugin should be installed.` + Ignored.` } func GetAIDescription() string { - return `Download the data-transfer Artifactory user plugin and install it on the primary node of the source Artifactory. Required as a one-time prep before 'jf rt transfer-files'. The plugin handles the actual byte streaming on the server side. + return `[DEPRECATED] Informational command only. It no longer downloads or installs the data-transfer Artifactory user plugin; it only prints a deprecation warning and exits successfully. 'jf rt transfer-files' does not require the plugin on the source server. The command will be removed in a future release. When to use: -- One-time setup on the source server before starting a self-hosted-to-cloud migration. - -Prerequisites: -- Must be run on the same host as the source Artifactory's primary node (or with filesystem access to its etc/artifactory/plugins/ directory). -- Admin privileges on the source server. -- The source server ID is configured locally. - -Common patterns: - $ jf rt transfer-plugin-install source-prod - $ jf rt transfer-plugin-install source-prod --dir=/opt/jfrog/artifactory/var/etc/artifactory/plugins +- Do not use. Run 'jf rt transfer-files' directly. Gotchas: -- Must run as the user that owns the Artifactory installation; otherwise the file write fails. -- The plugin requires a Groovy plugins admin restart (or wait for the scheduled reload). -- This command only targets self-hosted instances; cloud-hosted sources need a different transfer mechanism. +- All arguments and flags (--version, --dir, --home-dir) are accepted but ignored. Related: jf rt transfer-files, jf rt transfer-settings QA: -Q: What's the JFrog CLI command to install the data-transfer user plugin in the primary node of the source instance? -A: jf rt transfer-plugin-install source-server +Q: Do I need to install the data-transfer user plugin before running 'jf rt transfer-files'? +A: No. The plugin is no longer required, and 'jf rt transfer-plugin-install' is deprecated and does nothing. ` } diff --git a/go.mod b/go.mod index 2fef35cdb..29b16c69a 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( github.com/jfrog/gofrog v1.7.7 github.com/jfrog/jfrog-cli-application v1.0.2-0.20260917110731-d7783acedd8c github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20261103060251-30c80a7deec4 - github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20261102064148-e4c77ed13cc6 + github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20261104085101-89d932ea6d45 github.com/jfrog/jfrog-cli-evidence v0.11.1-0.20261102090321-5b0bce39abfe github.com/jfrog/jfrog-cli-platform-services v1.10.1-0.20261030162302-b4948e3a2cb1 github.com/jfrog/jfrog-cli-security v1.41.2 diff --git a/go.sum b/go.sum index f6590b7c9..b8bd381fa 100644 --- a/go.sum +++ b/go.sum @@ -404,8 +404,8 @@ github.com/jfrog/jfrog-cli-application v1.0.2-0.20260917110731-d7783acedd8c h1:B github.com/jfrog/jfrog-cli-application v1.0.2-0.20260917110731-d7783acedd8c/go.mod h1:RHjDVsgfIE+6N49R1t1nBjbK2Je4VTN7CQm9OlwtFnQ= github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20261103060251-30c80a7deec4 h1:Z4WqOlZZe3NA02ekqFrbSNlO8hkdGPHn/PuWq1sb+CA= github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20261103060251-30c80a7deec4/go.mod h1:94/aLloMSK6avu4umcJS3DJ6IuGM5K10PwZ6kDqgzSo= -github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20261102064148-e4c77ed13cc6 h1:7Jdj+FiaMN5jiQ94+Xlehf9OSLqSbAqAvO44XB9d7E4= -github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20261102064148-e4c77ed13cc6/go.mod h1:dxy3GflCOX9kGxcdEkCXWhV+EMUAGBWO+CY5fGjWcCQ= +github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20261104085101-89d932ea6d45 h1:1FDVeHvnUQJEww5HE23JA/7aiSVuEzET/WNkJiy6u64= +github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20261104085101-89d932ea6d45/go.mod h1:dxy3GflCOX9kGxcdEkCXWhV+EMUAGBWO+CY5fGjWcCQ= github.com/jfrog/jfrog-cli-evidence v0.11.1-0.20261102090321-5b0bce39abfe h1:BRaNdb6JIdGqGa79XwxIsZHDmZ26pQ5V1cPJ7zYLJoM= github.com/jfrog/jfrog-cli-evidence v0.11.1-0.20261102090321-5b0bce39abfe/go.mod h1:4OGLCLQjdHg9PpjFkxvn8bGflOZGEJsoBHAGys7gUio= github.com/jfrog/jfrog-cli-platform-services v1.10.1-0.20261030162302-b4948e3a2cb1 h1:1NA6meQs1Nbe7B1AKcvLdX+hKpxyWVe+cNpTDJznZcs= diff --git a/transfer_test.go b/transfer_test.go index 9bce1c5fe..f3358ac2e 100644 --- a/transfer_test.go +++ b/transfer_test.go @@ -65,13 +65,6 @@ func initTransferTest(t *testing.T) func() { t.Skip("Skipping transfer test. To run transfer test add the '-test.transfer=true' option.") } oldHomeDir, newHomeDir := prepareHomeDir(t) - if *tests.InstallDataTransferPlugin { - if *tests.JfrogHome != "" { - coreutils.ExitOnErr(artifactoryCli.WithoutCredentials().Exec("transfer-plugin-install", inttestutils.SourceServerId, "--home-dir="+*tests.JfrogHome)) - } else { - coreutils.ExitOnErr(artifactoryCli.WithoutCredentials().Exec("transfer-plugin-install", inttestutils.SourceServerId)) - } - } // Delete the target server if exist targetConfig, err := commands.GetConfig(inttestutils.TargetServerId, false) @@ -83,9 +76,6 @@ func initTransferTest(t *testing.T) func() { err = coretests.NewJfrogCli(execMain, "jfrog config", "--access-token="+*tests.JfrogTargetAccessToken).Exec("add", inttestutils.TargetServerId, "--interactive=false", "--url="+*tests.JfrogTargetUrl) assert.NoError(t, err) - if *tests.InstallDataTransferPlugin { - assert.NoError(t, artifactoryCli.WithoutCredentials().Exec("curl", "-XPOST", "/api/plugins/reload")) - } return func() { cleanArtifactory() inttestutils.CleanTargetRepos(targetArtifactoryCli) diff --git a/utils/cliutils/commandsflags.go b/utils/cliutils/commandsflags.go index 194a8bcf1..9735d4bc1 100644 --- a/utils/cliutils/commandsflags.go +++ b/utils/cliutils/commandsflags.go @@ -1969,15 +1969,15 @@ var flagsMap = map[string]cli.Flag{ }, installPluginVersion: cli.StringFlag{ Name: Version, - Usage: "[Default: latest] The plugin version to download and install.` `", + Usage: "[DEPRECATED] Ignored.` `", }, InstallPluginSrcDir: cli.StringFlag{ Name: InstallPluginSrcDir, - Usage: "[Optional] The local directory that contains the plugin files to install.` `", + Usage: "[DEPRECATED] Ignored.` `", }, InstallPluginHomeDir: cli.StringFlag{ Name: InstallPluginHomeDir, - Usage: "[Default: /opt/jfrog] The local JFrog home directory to install the plugin in.` `", + Usage: "[DEPRECATED] Ignored.` `", }, PreChecks: cli.BoolFlag{ Name: PreChecks, diff --git a/utils/tests/utils.go b/utils/tests/utils.go index cfbe44540..5e72aec9c 100644 --- a/utils/tests/utils.go +++ b/utils/tests/utils.go @@ -43,59 +43,58 @@ import ( ) var ( - JfrogUrl *string - JfrogUser *string - JfrogPassword *string - JfrogSshKeyPath *string - JfrogSshPassphrase *string - JfrogAccessToken *string - JfrogTargetUrl *string - JfrogTargetAccessToken *string - JfrogHome *string - TestArtifactoryProject *bool - TestArtifactory *bool - TestArtifactoryProxy *bool - TestDistribution *bool - TestDocker *bool - TestPodman *bool - TestDockerScan *bool - ContainerRegistry *string - TestGo *bool - TestNpm *bool - TestPnpm *bool - TestGradle *bool - TestMaven *bool - TestNuget *bool - TestChoco *bool - TestPSResource *bool - TestPip *bool - TestPipenv *bool - TestPoetry *bool - TestUv *bool - TestNix *bool - TestCargo *bool - TestAlpine *bool - TestRuby *bool - TestApt *bool - TestAgentPlugins *bool - TestAgentSkills *bool - TestApm *bool - TestConan *bool - TestHelm *bool - TestHuggingFace *bool - TestPlugins *bool - TestXray *bool - TestAccess *bool - TestTransfer *bool - TestLifecycle *bool - TestEvidence *bool - TestApi *bool - TestGhostFrog *bool - TestIde *bool - HideUnitTestLog *bool - ciRunId *string - InstallDataTransferPlugin *bool - timestampAdded bool + JfrogUrl *string + JfrogUser *string + JfrogPassword *string + JfrogSshKeyPath *string + JfrogSshPassphrase *string + JfrogAccessToken *string + JfrogTargetUrl *string + JfrogTargetAccessToken *string + JfrogHome *string + TestArtifactoryProject *bool + TestArtifactory *bool + TestArtifactoryProxy *bool + TestDistribution *bool + TestDocker *bool + TestPodman *bool + TestDockerScan *bool + ContainerRegistry *string + TestGo *bool + TestNpm *bool + TestPnpm *bool + TestGradle *bool + TestMaven *bool + TestNuget *bool + TestChoco *bool + TestPSResource *bool + TestPip *bool + TestPipenv *bool + TestPoetry *bool + TestUv *bool + TestNix *bool + TestCargo *bool + TestAlpine *bool + TestRuby *bool + TestApt *bool + TestAgentPlugins *bool + TestAgentSkills *bool + TestApm *bool + TestConan *bool + TestHelm *bool + TestHuggingFace *bool + TestPlugins *bool + TestXray *bool + TestAccess *bool + TestTransfer *bool + TestLifecycle *bool + TestEvidence *bool + TestApi *bool + TestGhostFrog *bool + TestIde *bool + HideUnitTestLog *bool + ciRunId *string + timestampAdded bool ) // nonProjectKeyCharsRegex matches any character that isn't allowed in an Artifactory @@ -171,8 +170,9 @@ func init() { TestIde = flag.Bool("test.ide", false, "Test IDE (VS Code / Cursor / Windsurf / Kiro / JetBrains) setup commands") ContainerRegistry = flag.String("test.containerRegistry", "localhost:8082", "Container registry") HideUnitTestLog = flag.Bool("test.hideUnitTestLog", false, "Hide unit tests logs and print it in a file") - InstallDataTransferPlugin = flag.Bool("test.installDataTransferPlugin", false, "Install data-transfer plugin on the source Artifactory server") ciRunId = flag.String("ci.runId", "", "A unique identifier used as a suffix to create repositories and builds in the tests") + // Deprecated: ignored, kept so existing pipelines don't fail on an unknown flag. + _ = flag.Bool("test.installDataTransferPlugin", false, "[DEPRECATED] Ignored") } func CleanFileSystem() {