fix: fix setup for custom tofu versions (#8)

This commit is contained in:
Robert Kaussow 2024-02-07 13:17:58 +01:00 committed by GitHub
parent f819abd64b
commit 3481dbc61a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 41 additions and 15 deletions

2
go.mod
View File

@ -4,6 +4,7 @@ go 1.21
require (
github.com/Masterminds/semver/v3 v3.2.1
github.com/rs/zerolog v1.31.0
github.com/thegeeklab/wp-plugin-go v1.5.0
github.com/urfave/cli/v2 v2.27.1
golang.org/x/sys v0.16.0
@ -21,7 +22,6 @@ require (
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mitchellh/copystructure v1.0.0 // indirect
github.com/mitchellh/reflectwalk v1.0.0 // indirect
github.com/rs/zerolog v1.31.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/shopspring/decimal v1.2.0 // indirect
github.com/spf13/cast v1.3.1 // indirect

View File

@ -14,10 +14,11 @@ var (
ErrMaxSizeSizeLimit = errors.New("max size limit of decoded data exceeded")
ErrActionUnknown = errors.New("action not found")
ErrInvalidTofuVersion = errors.New("invalid version string")
ErrHTTPError = errors.New("http error")
)
const (
maxDecompressionSize = 1024
maxDecompressionSize = 100 * 1024 * 1024
defaultDirPerm = 0o755
)

View File

@ -3,6 +3,7 @@ package plugin
import (
"archive/zip"
"context"
"errors"
"fmt"
"io"
"net/http"
@ -11,29 +12,48 @@ import (
"strings"
"github.com/Masterminds/semver/v3"
"github.com/rs/zerolog/log"
)
func installPackage(ctx context.Context, client *http.Client, version string, maxSize int64) error {
// Sanitize user input
if _, err := semver.NewVersion(version); err != nil {
semverVersion, err := semver.NewVersion(version)
if err != nil {
return fmt.Errorf("%w: %v", ErrInvalidTofuVersion, version)
}
err := downloadPackage(
ctx,
client,
"/tmp/tofu.zip",
fmt.Sprintf(
"https://github.com/opentofu/opentofu/releases/download/%s/tofu_%s_linux_amd64.zip",
version,
strings.TrimPrefix(version, ""),
),
packageURL := fmt.Sprintf(
"https://github.com/opentofu/opentofu/releases/download/v%s/tofu_%s_linux_amd64.zip",
semverVersion.String(),
semverVersion.String(),
)
tmpdir, err := os.MkdirTemp("/tmp", "tofu_dl_")
if err != nil {
return err
return fmt.Errorf("failed to create tmp dir: %w", err)
}
return unzip("/tmp/tofu.zip", "/bin", maxSize)
defer os.RemoveAll(tmpdir)
log.Debug().
Str("tmpdir", tmpdir).
Msgf("Download OpenTofu '%s' from URL '%s'", version, packageURL)
tmpfile := filepath.Join(tmpdir, "tofu.zip")
if err := downloadPackage(ctx, client, tmpfile, packageURL); err != nil {
return fmt.Errorf("failed to download: %w", err)
}
if err := unzip(tmpfile, tmpdir, maxSize); err != nil {
return fmt.Errorf("failed to unzip: %w", err)
}
if err := os.Rename(filepath.Join(tmpdir, "tofu"), tofuBin); err != nil {
return fmt.Errorf("failed to rename: %w", err)
}
return nil
}
func downloadPackage(ctx context.Context, client *http.Client, filepath, url string) error {
@ -54,6 +74,11 @@ func downloadPackage(ctx context.Context, client *http.Client, filepath, url str
if err != nil {
return err
}
if resp.StatusCode > http.StatusBadRequest {
return fmt.Errorf("%w: %v", ErrHTTPError, resp.Status)
}
defer resp.Body.Close()
// Writer the body to file
@ -113,7 +138,7 @@ func unzip(src, dest string, maxSize int64) error {
}()
written, err := io.CopyN(f, rc, maxSize)
if err != nil {
if err != nil && !errors.Is(err, io.EOF) {
return err
} else if written == maxSize {
return fmt.Errorf("%w: %d", ErrMaxSizeSizeLimit, maxSize)