Thanks to visit codestin.com
Credit goes to github.com

Skip to content

feat: Support caching provisioner assets #574

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

Merged
merged 5 commits into from
Mar 28, 2022
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
36 changes: 18 additions & 18 deletions cli/cliflag/cliflag_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ import (
//nolint:paralleltest
func TestCliflag(t *testing.T) {
t.Run("StringDefault", func(t *testing.T) {
var p string
var ptr string
flagset, name, shorthand, env, usage := randomFlag()
def, _ := cryptorand.String(10)

cliflag.StringVarP(flagset, &p, name, shorthand, env, def, usage)
cliflag.StringVarP(flagset, &ptr, name, shorthand, env, def, usage)
got, err := flagset.GetString(name)
require.NoError(t, err)
require.Equal(t, def, got)
Expand All @@ -29,24 +29,24 @@ func TestCliflag(t *testing.T) {
})

t.Run("StringEnvVar", func(t *testing.T) {
var p string
var ptr string
flagset, name, shorthand, env, usage := randomFlag()
envValue, _ := cryptorand.String(10)
t.Setenv(env, envValue)
def, _ := cryptorand.String(10)

cliflag.StringVarP(flagset, &p, name, shorthand, env, def, usage)
cliflag.StringVarP(flagset, &ptr, name, shorthand, env, def, usage)
got, err := flagset.GetString(name)
require.NoError(t, err)
require.Equal(t, envValue, got)
})

t.Run("EmptyEnvVar", func(t *testing.T) {
var p string
var ptr string
flagset, name, shorthand, _, usage := randomFlag()
def, _ := cryptorand.String(10)

cliflag.StringVarP(flagset, &p, name, shorthand, "", def, usage)
cliflag.StringVarP(flagset, &ptr, name, shorthand, "", def, usage)
got, err := flagset.GetString(name)
require.NoError(t, err)
require.Equal(t, def, got)
Expand All @@ -55,11 +55,11 @@ func TestCliflag(t *testing.T) {
})

t.Run("IntDefault", func(t *testing.T) {
var p uint8
var ptr uint8
flagset, name, shorthand, env, usage := randomFlag()
def, _ := cryptorand.Int63n(10)

cliflag.Uint8VarP(flagset, &p, name, shorthand, env, uint8(def), usage)
cliflag.Uint8VarP(flagset, &ptr, name, shorthand, env, uint8(def), usage)
got, err := flagset.GetUint8(name)
require.NoError(t, err)
require.Equal(t, uint8(def), got)
Expand All @@ -68,37 +68,37 @@ func TestCliflag(t *testing.T) {
})

t.Run("IntEnvVar", func(t *testing.T) {
var p uint8
var ptr uint8
flagset, name, shorthand, env, usage := randomFlag()
envValue, _ := cryptorand.Int63n(10)
t.Setenv(env, strconv.FormatUint(uint64(envValue), 10))
def, _ := cryptorand.Int()

cliflag.Uint8VarP(flagset, &p, name, shorthand, env, uint8(def), usage)
cliflag.Uint8VarP(flagset, &ptr, name, shorthand, env, uint8(def), usage)
got, err := flagset.GetUint8(name)
require.NoError(t, err)
require.Equal(t, uint8(envValue), got)
})

t.Run("IntFailParse", func(t *testing.T) {
var p uint8
var ptr uint8
flagset, name, shorthand, env, usage := randomFlag()
envValue, _ := cryptorand.String(10)
t.Setenv(env, envValue)
def, _ := cryptorand.Int63n(10)

cliflag.Uint8VarP(flagset, &p, name, shorthand, env, uint8(def), usage)
cliflag.Uint8VarP(flagset, &ptr, name, shorthand, env, uint8(def), usage)
got, err := flagset.GetUint8(name)
require.NoError(t, err)
require.Equal(t, uint8(def), got)
})

t.Run("BoolDefault", func(t *testing.T) {
var p bool
var ptr bool
flagset, name, shorthand, env, usage := randomFlag()
def, _ := cryptorand.Bool()

cliflag.BoolVarP(flagset, &p, name, shorthand, env, def, usage)
cliflag.BoolVarP(flagset, &ptr, name, shorthand, env, def, usage)
got, err := flagset.GetBool(name)
require.NoError(t, err)
require.Equal(t, def, got)
Expand All @@ -107,26 +107,26 @@ func TestCliflag(t *testing.T) {
})

t.Run("BoolEnvVar", func(t *testing.T) {
var p bool
var ptr bool
flagset, name, shorthand, env, usage := randomFlag()
envValue, _ := cryptorand.Bool()
t.Setenv(env, strconv.FormatBool(envValue))
def, _ := cryptorand.Bool()

cliflag.BoolVarP(flagset, &p, name, shorthand, env, def, usage)
cliflag.BoolVarP(flagset, &ptr, name, shorthand, env, def, usage)
got, err := flagset.GetBool(name)
require.NoError(t, err)
require.Equal(t, envValue, got)
})

t.Run("BoolFailParse", func(t *testing.T) {
var p bool
var ptr bool
flagset, name, shorthand, env, usage := randomFlag()
envValue, _ := cryptorand.String(10)
t.Setenv(env, envValue)
def, _ := cryptorand.Bool()

cliflag.BoolVarP(flagset, &p, name, shorthand, env, def, usage)
cliflag.BoolVarP(flagset, &ptr, name, shorthand, env, def, usage)
got, err := flagset.GetBool(name)
require.NoError(t, err)
require.Equal(t, def, got)
Expand Down
11 changes: 8 additions & 3 deletions cli/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"net/url"
"os"
"os/signal"
"path/filepath"
"time"

"github.com/briandowns/spinner"
Expand Down Expand Up @@ -42,6 +43,7 @@ func start() *cobra.Command {
var (
accessURL string
address string
cacheDir string
dev bool
postgresURL string
// provisionerDaemonCount is a uint8 to ensure a number > 0.
Expand Down Expand Up @@ -161,7 +163,7 @@ func start() *cobra.Command {

provisionerDaemons := make([]*provisionerd.Server, 0)
for i := 0; uint8(i) < provisionerDaemonCount; i++ {
daemonClose, err := newProvisionerDaemon(cmd.Context(), client, logger)
daemonClose, err := newProvisionerDaemon(cmd.Context(), client, logger, cacheDir)
if err != nil {
return xerrors.Errorf("create provisioner daemon: %w", err)
}
Expand Down Expand Up @@ -305,6 +307,8 @@ func start() *cobra.Command {

cliflag.StringVarP(root.Flags(), &accessURL, "access-url", "", "CODER_ACCESS_URL", "", "Specifies the external URL to access Coder")
cliflag.StringVarP(root.Flags(), &address, "address", "a", "CODER_ADDRESS", "127.0.0.1:3000", "The address to serve the API and dashboard")
// systemd uses the CACHE_DIRECTORY environment variable!
cliflag.StringVarP(root.Flags(), &cacheDir, "cache-dir", "", "CACHE_DIRECTORY", filepath.Join(os.TempDir(), ".coder-cache"), "Specifies a directory to cache binaries for provision operations.")
cliflag.BoolVarP(root.Flags(), &dev, "dev", "", "CODER_DEV_MODE", false, "Serve Coder in dev mode for tinkering")
cliflag.StringVarP(root.Flags(), &postgresURL, "postgres-url", "", "CODER_PG_CONNECTION_URL", "", "URL of a PostgreSQL database to connect to")
cliflag.Uint8VarP(root.Flags(), &provisionerDaemonCount, "provisioner-daemons", "", "CODER_PROVISIONER_DAEMONS", 1, "The amount of provisioner daemons to create on start.")
Expand Down Expand Up @@ -358,14 +362,15 @@ func createFirstUser(cmd *cobra.Command, client *codersdk.Client, cfg config.Roo
return nil
}

func newProvisionerDaemon(ctx context.Context, client *codersdk.Client, logger slog.Logger) (*provisionerd.Server, error) {
func newProvisionerDaemon(ctx context.Context, client *codersdk.Client, logger slog.Logger, cacheDir string) (*provisionerd.Server, error) {
terraformClient, terraformServer := provisionersdk.TransportPipe()
go func() {
err := terraform.Serve(ctx, &terraform.ServeOptions{
ServeOptions: &provisionersdk.ServeOptions{
Listener: terraformServer,
},
Logger: logger,
CachePath: cacheDir,
Logger: logger,
})
if err != nil {
panic(err)
Expand Down
1 change: 1 addition & 0 deletions coder.service
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ PrivateTmp=yes
PrivateDevices=yes
SecureBits=keep-caps
AmbientCapabilities=CAP_IPC_LOCK
CacheDirectory=coder
CapabilityBoundingSet=CAP_SYSLOG CAP_IPC_LOCK CAP_NET_BIND_SERVICE
NoNewPrivileges=yes
ExecStart=/usr/bin/coder start
Expand Down
8 changes: 8 additions & 0 deletions provisioner/terraform/provision.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,14 @@ func (t *terraform) Provision(stream proto.DRPCProvisioner_ProvisionStream) erro
})
}
}()
if t.cachePath != "" {
err = terraform.SetEnv(map[string]string{
"TF_PLUGIN_CACHE_DIR": t.cachePath,
})
if err != nil {
return xerrors.Errorf("set terraform plugin cache dir: %w", err)
}
}
terraform.SetStdout(writer)
t.logger.Debug(shutdown, "running initialization")
err = terraform.Init(shutdown)
Expand Down
8 changes: 6 additions & 2 deletions provisioner/terraform/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type ServeOptions struct {
// BinaryPath specifies the "terraform" binary to use.
// If omitted, the $PATH will attempt to find it.
BinaryPath string
CachePath string
Logger slog.Logger
}

Expand All @@ -43,8 +44,9 @@ func Serve(ctx context.Context, options *ServeOptions) error {
binaryPath, err := exec.LookPath("terraform")
if err != nil {
installer := &releases.ExactVersion{
Product: product.Terraform,
Version: version.Must(version.NewVersion("1.1.7")),
InstallDir: options.CachePath,
Product: product.Terraform,
Version: version.Must(version.NewVersion("1.1.7")),
}

execPath, err := installer.Install(ctx)
Expand All @@ -58,11 +60,13 @@ func Serve(ctx context.Context, options *ServeOptions) error {
}
return provisionersdk.Serve(ctx, &terraform{
binaryPath: options.BinaryPath,
cachePath: options.CachePath,
logger: options.Logger,
}, options.ServeOptions)
}

type terraform struct {
binaryPath string
cachePath string
logger slog.Logger
}