diff --git a/integration/autoupdate/tools/updater_test.go b/integration/autoupdate/tools/updater_test.go index 0ef2eabb4aa41..47b2e3460fa23 100644 --- a/integration/autoupdate/tools/updater_test.go +++ b/integration/autoupdate/tools/updater_test.go @@ -69,9 +69,7 @@ func TestUpdate(t *testing.T) { out, err := cmd.Output() require.NoError(t, err) - matches := pattern.FindStringSubmatch(string(out)) - require.Len(t, matches, 2) - require.Equal(t, testVersions[0], matches[1]) + matchVersion(t, string(out), testVersions[0]) // Execute version command again with setting the new version which must // trigger re-execution of the same command after downloading requested version. @@ -83,9 +81,7 @@ func TestUpdate(t *testing.T) { out, err = cmd.Output() require.NoError(t, err) - matches = pattern.FindStringSubmatch(string(out)) - require.Len(t, matches, 2) - require.Equal(t, testVersions[1], matches[1]) + matchVersion(t, string(out), testVersions[1]) } // TestParallelUpdate launches multiple updater commands in parallel while defining a new version. @@ -258,9 +254,7 @@ func TestUpdateForOSSBuild(t *testing.T) { out, err := cmd.Output() require.NoError(t, err) - matches := pattern.FindStringSubmatch(string(out)) - require.Len(t, matches, 2) - require.Equal(t, testVersions[0], matches[1]) + matchVersion(t, string(out), testVersions[0]) // Next update is set with the base URL env variable, must download new version. t.Setenv(autoupdate.BaseURLEnvVar, baseURL) @@ -272,7 +266,12 @@ func TestUpdateForOSSBuild(t *testing.T) { out, err = cmd.Output() require.NoError(t, err) - matches = pattern.FindStringSubmatch(string(out)) + matchVersion(t, string(out), testVersions[1]) +} + +func matchVersion(t *testing.T, output string, version string) { + t.Helper() + matches := pattern.FindStringSubmatch(output) require.Len(t, matches, 2) - require.Equal(t, testVersions[1], matches[1]) + require.Equal(t, version, matches[1]) } diff --git a/integration/autoupdate/tools/updater_tsh_test.go b/integration/autoupdate/tools/updater_tsh_test.go index 78d674002efd4..5c92ac07fb080 100644 --- a/integration/autoupdate/tools/updater_tsh_test.go +++ b/integration/autoupdate/tools/updater_tsh_test.go @@ -105,9 +105,7 @@ func TestAliasLoginWithUpdater(t *testing.T) { cmd = exec.CommandContext(ctx, tshPath, "version") out, err = cmd.Output() require.NoError(t, err) - matches := pattern.FindStringSubmatch(string(out)) - require.Len(t, matches, 2) - require.Equal(t, testVersions[1], matches[1]) + matchVersion(t, string(out), testVersions[1]) // Verifies that version commands shows version re-executed from. require.Contains(t, string(out), fmt.Sprintf("Re-executed from version: %s", testVersions[0])) @@ -152,9 +150,7 @@ func TestLoginWithUpdaterAndProfile(t *testing.T) { cmd = exec.CommandContext(ctx, tshPath, "version") out, err := cmd.Output() require.NoError(t, err) - matches := pattern.FindStringSubmatch(string(out)) - require.Len(t, matches, 2) - require.Equal(t, testVersions[1], matches[1]) + matchVersion(t, string(out), testVersions[1]) } // TestLoginWithDisabledUpdateInProfile runs test cluster with enabled managed updates for client tools, @@ -188,9 +184,7 @@ func TestLoginWithDisabledUpdateInProfile(t *testing.T) { out, err := cmd.Output() require.NoError(t, err) // Check the version. - matches := pattern.FindStringSubmatch(string(out)) - require.Len(t, matches, 2) - require.Equal(t, testVersions[1], matches[1]) + matchVersion(t, string(out), testVersions[1]) // Unset the version after update process. require.NoError(t, os.Unsetenv("TELEPORT_TOOLS_VERSION")) @@ -208,10 +202,7 @@ func TestLoginWithDisabledUpdateInProfile(t *testing.T) { out, err = cmd.Output() require.NoError(t, err) // Check the version. - matches = pattern.FindStringSubmatch(string(out)) - require.Len(t, matches, 2) - fmt.Println(string(out)) - require.Equal(t, testVersions[0], matches[1]) + matchVersion(t, string(out), testVersions[0]) } // TestLoginWithDisabledUpdateForcedByEnv verifies that on disabled cluster we are still @@ -253,10 +244,7 @@ func TestLoginWithDisabledUpdateForcedByEnv(t *testing.T) { out, err := cmd.Output() require.NoError(t, err) // Check that version is used that requested from env variable. - matches := pattern.FindStringSubmatch(string(out)) - require.Len(t, matches, 2) - fmt.Println(string(out)) - require.Equal(t, testVersions[1], matches[1]) + matchVersion(t, string(out), testVersions[1]) // Unset the version after update process. require.NoError(t, os.Unsetenv("TELEPORT_TOOLS_VERSION")) @@ -266,10 +254,39 @@ func TestLoginWithDisabledUpdateForcedByEnv(t *testing.T) { cmd = exec.CommandContext(ctx, tshPath, "version") out, err = cmd.Output() require.NoError(t, err) - matches = pattern.FindStringSubmatch(string(out)) - require.Len(t, matches, 2) - fmt.Println(string(out)) - require.Equal(t, testVersions[0], matches[1]) + matchVersion(t, string(out), testVersions[0]) +} + +// TestMigratedUpdateNotReExec verifies that the version is migrated without errors, +// and that the previous version of the updated tools is ignored. +func TestMigratedUpdateNotReExec(t *testing.T) { + testToolsDir := t.TempDir() + t.Setenv(types.HomeEnvVar, testToolsDir) + ctx := context.Background() + + // Fetch compiled test binary with updater logic and install to $TELEPORT_HOME. + updater := tools.NewUpdater( + testToolsDir, + testVersions[0], + tools.WithBaseURL(baseURL), + ) + err := updater.Update(ctx, testVersions[0]) + require.NoError(t, err) + + tshPath, err := updater.ToolPath("tsh", testVersions[0]) + require.NoError(t, err) + + require.NoError(t, os.MkdirAll(filepath.Join(testToolsDir, "bin"), 0755)) + require.NoError(t, os.WriteFile(filepath.Join(testToolsDir, "bin", "tsh"), []byte("#!/bin/sh\n echo 'Teleport v5.5.5 git'\n"), 0755)) + + // Verify that the installed version is equal to requested one. + cmd := exec.CommandContext(ctx, tshPath, "version") + out, err := cmd.Output() + require.NoError(t, err) + + require.NotContains(t, string(out), "version check failed") + + matchVersion(t, string(out), testVersions[0]) } func bootstrapTestServer(t *testing.T) (*service.TeleportProcess, string, string) { diff --git a/lib/autoupdate/tools/updater.go b/lib/autoupdate/tools/updater.go index 1d470e586d131..348d6f581c7bc 100644 --- a/lib/autoupdate/tools/updater.go +++ b/lib/autoupdate/tools/updater.go @@ -202,7 +202,7 @@ func (u *Updater) CheckLocal(ctx context.Context, profileName string) (resp *Upd } } - return &UpdateResponse{Version: toolsVersion, ReExec: true}, nil + return &UpdateResponse{Version: toolsVersion, ReExec: false}, nil } // CheckRemote first checks the version set by the environment variable. If not set or disabled,