Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Client auto updates integration for {tctl,tsh} #47815

Merged
merged 16 commits into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions api/client/webclient/webclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -338,8 +338,8 @@ type ProxySettings struct {
type AutoUpdateSettings struct {
// ToolsVersion defines the version of {tsh, tctl} for client auto update.
ToolsVersion string `json:"tools_version"`
// ToolsMode defines mode client auto update feature `enabled|disabled`.
ToolsMode string `json:"tools_mode"`
// ToolsAutoUpdate indicates if the requesting tools client should be updated.
ToolsAutoUpdate bool `json:"tools_auto_update"`
// AgentVersion defines the version of teleport that agents enrolled into autoupdates should run.
AgentVersion string `json:"agent_version"`
// AgentAutoUpdate indicates if the requesting agent should attempt to update now.
Expand Down
17 changes: 9 additions & 8 deletions integration/autoupdate/tools/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ import (

"github.com/gravitational/trace"

"github.com/gravitational/teleport/integration/helpers"
"github.com/gravitational/teleport/api/constants"
"github.com/gravitational/teleport/integration/helpers/archive"
)

const (
Expand Down Expand Up @@ -133,25 +134,25 @@ func buildAndArchiveApps(ctx context.Context, path string, toolsDir string, vers
for _, app := range []string{"tsh", "tctl"} {
output := filepath.Join(versionPath, app)
switch runtime.GOOS {
case "windows":
case constants.WindowsOS:
output = filepath.Join(versionPath, app+".exe")
case "darwin":
case constants.DarwinOS:
output = filepath.Join(versionPath, app+".app", "Contents", "MacOS", app)
}
if err := buildBinary(output, toolsDir, version, baseURL); err != nil {
return trace.Wrap(err)
}
}
switch runtime.GOOS {
case "darwin":
case constants.DarwinOS:
archivePath := filepath.Join(path, fmt.Sprintf("teleport-%s.pkg", version))
return trace.Wrap(helpers.CompressDirToPkgFile(ctx, versionPath, archivePath, "com.example.pkgtest"))
case "windows":
return trace.Wrap(archive.CompressDirToPkgFile(ctx, versionPath, archivePath, "com.example.pkgtest"))
case constants.WindowsOS:
archivePath := filepath.Join(path, fmt.Sprintf("teleport-v%s-windows-amd64-bin.zip", version))
return trace.Wrap(helpers.CompressDirToZipFile(ctx, versionPath, archivePath))
return trace.Wrap(archive.CompressDirToZipFile(ctx, versionPath, archivePath))
default:
archivePath := filepath.Join(path, fmt.Sprintf("teleport-v%s-linux-%s-bin.tar.gz", version, runtime.GOARCH))
return trace.Wrap(helpers.CompressDirToTarGzFile(ctx, versionPath, archivePath))
return trace.Wrap(archive.CompressDirToTarGzFile(ctx, versionPath, archivePath))
}
}

Expand Down
21 changes: 6 additions & 15 deletions integration/autoupdate/tools/updater/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,9 @@ import (
"log"
"os"
"os/signal"
"runtime"
"syscall"
"time"

"github.com/gravitational/teleport/api/constants"
"github.com/gravitational/teleport/lib/autoupdate/tools"
)

Expand All @@ -40,17 +38,20 @@ var (
)

func main() {
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()
ctx, _ = signal.NotifyContext(ctx, syscall.SIGINT, syscall.SIGTERM)

updater := tools.NewUpdater(
clientTools(),
tools.DefaultClientTools(),
toolsDir,
version,
tools.WithBaseURL(baseURL),
)
toolsVersion, reExec := updater.CheckLocal()
toolsVersion, reExec, err := updater.CheckLocal()
if err != nil {
log.Fatal(err)
}
if reExec {
// Download and update the version of client tools required by the cluster.
// This is required if the user passed in the TELEPORT_TOOLS_VERSION explicitly.
Expand All @@ -76,13 +77,3 @@ func main() {
fmt.Printf("Teleport v%v git\n", version)
}
}

// clientTools list of the client tools needs to be updated.
func clientTools() []string {
switch runtime.GOOS {
case constants.WindowsOS:
return []string{"tsh.exe", "tctl.exe"}
default:
return []string{"tsh", "tctl"}
}
}
17 changes: 3 additions & 14 deletions integration/autoupdate/tools/updater_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,13 @@ import (
"os/exec"
"path/filepath"
"regexp"
"runtime"
"strings"
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/gravitational/teleport/api/constants"
"github.com/gravitational/teleport/lib/autoupdate/tools"
)

Expand All @@ -51,7 +49,7 @@ func TestUpdate(t *testing.T) {

// Fetch compiled test binary with updater logic and install to $TELEPORT_HOME.
updater := tools.NewUpdater(
clientTools(),
tools.DefaultClientTools(),
toolsDir,
testVersions[0],
tools.WithBaseURL(baseURL),
Expand Down Expand Up @@ -93,7 +91,7 @@ func TestParallelUpdate(t *testing.T) {

// Initial fetch the updater binary un-archive and replace.
updater := tools.NewUpdater(
clientTools(),
tools.DefaultClientTools(),
toolsDir,
testVersions[0],
tools.WithBaseURL(baseURL),
Expand Down Expand Up @@ -167,7 +165,7 @@ func TestUpdateInterruptSignal(t *testing.T) {

// Initial fetch the updater binary un-archive and replace.
updater := tools.NewUpdater(
clientTools(),
tools.DefaultClientTools(),
toolsDir,
testVersions[0],
tools.WithBaseURL(baseURL),
Expand Down Expand Up @@ -220,12 +218,3 @@ func TestUpdateInterruptSignal(t *testing.T) {
}
assert.Contains(t, output.String(), "Update progress:")
}

func clientTools() []string {
switch runtime.GOOS {
case constants.WindowsOS:
return []string{"tsh.exe", "tctl.exe"}
default:
return []string{"tsh", "tctl"}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package helpers
package archive

import (
"archive/tar"
Expand Down
1 change: 1 addition & 0 deletions integrations/terraform/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ require (
github.com/google/go-tspi v0.3.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af // indirect
github.com/google/renameio/v2 v2.0.0 // indirect
github.com/google/s2a-go v0.1.8 // indirect
github.com/google/safetext v0.0.0-20240104143208-7a7d9b3d812f // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
Expand Down
1 change: 0 additions & 1 deletion integrations/terraform/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1252,7 +1252,6 @@ github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLe
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM=
github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo=
github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg=
github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4=
Expand Down
51 changes: 43 additions & 8 deletions lib/autoupdate/tools/progress.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,59 @@ package tools

import (
"fmt"
"io"
"strings"

"github.com/gravitational/trace"
)

type progressWriter struct {
n int64
limit int64
n int64
limit int64
size int
progress int
}

func (w *progressWriter) Write(p []byte) (int, error) {
w.n = w.n + int64(len(p))
// newProgressWriter creates progress writer instance and prints empty
// progress bar right after initialisation.
func newProgressWriter(size int) (*progressWriter, func()) {
pw := &progressWriter{size: size}
pw.Print(0)
return pw, func() {
fmt.Print("\n")
}
}

n := int((w.n*100)/w.limit) / 10
bricks := strings.Repeat("▒", n) + strings.Repeat(" ", 10-n)
// Print prints the update progress bar with `n` bricks.
func (w *progressWriter) Print(n int) {
bricks := strings.Repeat("▒", n) + strings.Repeat(" ", w.size-n)
fmt.Print("\rUpdate progress: [" + bricks + "] (Ctrl-C to cancel update)")
}

if w.n == w.limit {
fmt.Print("\n")
func (w *progressWriter) Write(p []byte) (int, error) {
if w.limit == 0 || w.size == 0 {
return len(p), nil
}

w.n += int64(len(p))
bricks := int((w.n*100)/w.limit) / w.size
if w.progress != bricks {
w.Print(bricks)
w.progress = bricks
}

return len(p), nil
}

// CopyLimit sets the limit of writing bytes to the progress writer and initiate copying process.
func (w *progressWriter) CopyLimit(dst io.Writer, src io.Reader, limit int64) (written int64, err error) {
if limit < 0 {
n, err := io.Copy(dst, io.TeeReader(src, w))
w.Print(w.size)
return n, trace.Wrap(err)
}

w.limit = limit
n, err := io.CopyN(dst, io.TeeReader(src, w), limit)
return n, trace.Wrap(err)
}
Loading
Loading