From 574ff6b99f2eeca354a04f2b2b3ab3a2a16ec556 Mon Sep 17 00:00:00 2001 From: mitchell Date: Tue, 19 Nov 2024 17:55:59 -0500 Subject: [PATCH 1/2] Added "--portable" flag to `state checkout` for copying runtime files instead of linking them. Also make `state deploy` runtimes portable by default. --- cmd/state/internal/cmdtree/checkout.go | 5 +++++ internal/assets/contents/activestate.yaml.cache.tpl | 1 + internal/runbits/checkout/checkout.go | 7 ++++--- internal/runbits/runtime/runtime.go | 3 +++ internal/runners/activate/activate.go | 2 +- internal/runners/checkout/checkout.go | 3 ++- internal/runners/deploy/deploy.go | 2 +- pkg/project/project.go | 2 ++ pkg/projectfile/projectfile.go | 9 ++++++--- pkg/runtime/options.go | 4 ++++ pkg/runtime/setup.go | 3 ++- 11 files changed, 31 insertions(+), 10 deletions(-) diff --git a/cmd/state/internal/cmdtree/checkout.go b/cmd/state/internal/cmdtree/checkout.go index e83fc6ee1c..0e1c91ab23 100644 --- a/cmd/state/internal/cmdtree/checkout.go +++ b/cmd/state/internal/cmdtree/checkout.go @@ -26,6 +26,11 @@ func newCheckoutCommand(prime *primer.Values) *captain.Command { Description: locale.Tl("flag_state_checkout_runtime-path_description", "Path to store the runtime files"), Value: ¶ms.RuntimePath, }, + { + Name: "portable", + Description: locale.Tl("flag_state_checkout_portable_description", "Copy files to runtime-path instead of linking to them"), + Value: ¶ms.Portable, + }, { Name: "no-clone", Description: locale.Tl("flag_state_checkout_no_clone_description", "Do not clone the github repository associated with this project (if any)"), diff --git a/internal/assets/contents/activestate.yaml.cache.tpl b/internal/assets/contents/activestate.yaml.cache.tpl index fcf8468204..7adaa70bc0 100644 --- a/internal/assets/contents/activestate.yaml.cache.tpl +++ b/internal/assets/contents/activestate.yaml.cache.tpl @@ -1,2 +1,3 @@ # It is recommended that you do not commit this file as it contains configuration that is specific to your machine cache: {{ .Cache }} +portable: {{ .Portable }} diff --git a/internal/runbits/checkout/checkout.go b/internal/runbits/checkout/checkout.go index 8e25d88b4e..fccb4ec9a8 100644 --- a/internal/runbits/checkout/checkout.go +++ b/internal/runbits/checkout/checkout.go @@ -52,7 +52,7 @@ func New(repo git.Repository, prime primeable) *Checkout { return &Checkout{repo, prime} } -func (r *Checkout) Run(ns *project.Namespaced, branchName, cachePath, targetPath string, noClone, bareCheckout bool) (_ string, rerr error) { +func (r *Checkout) Run(ns *project.Namespaced, branchName, cachePath, targetPath string, noClone, bareCheckout, portable bool) (_ string, rerr error) { defer r.rationalizeError(&rerr) path, err := r.pathToUse(ns, targetPath) @@ -94,7 +94,7 @@ func (r *Checkout) Run(ns *project.Namespaced, branchName, cachePath, targetPath return "", errNoCommitID } - if err := CreateProjectFiles(path, cachePath, owner, proj, branchName, commitID.String(), language); err != nil { + if err := CreateProjectFiles(path, cachePath, owner, proj, branchName, commitID.String(), language, portable); err != nil { return "", errs.Wrap(err, "Could not create project files") } @@ -182,7 +182,7 @@ func (r *Checkout) fetchProject( return owner, proj, commitID, branchName, language, pj.RepoURL, nil } -func CreateProjectFiles(checkoutPath, cachePath, owner, name, branch, commitID, language string) error { +func CreateProjectFiles(checkoutPath, cachePath, owner, name, branch, commitID, language string, portable bool) error { configFile := filepath.Join(checkoutPath, constants.ConfigFileName) if !fileutils.FileExists(configFile) { _, err := projectfile.Create(&projectfile.CreateParams{ @@ -192,6 +192,7 @@ func CreateProjectFiles(checkoutPath, cachePath, owner, name, branch, commitID, Directory: checkoutPath, Language: language, Cache: cachePath, + Portable: portable, }) if err != nil { if osutils.IsAccessDeniedError(err) { diff --git a/internal/runbits/runtime/runtime.go b/internal/runbits/runtime/runtime.go index 83b995ff75..88305f47a6 100644 --- a/internal/runbits/runtime/runtime.go +++ b/internal/runbits/runtime/runtime.go @@ -271,6 +271,9 @@ func Update( u.RawQuery = q.Encode() rtOpts = append(rtOpts, runtime.WithBuildProgressUrl(u.String())) } + if proj.IsPortable() { + rtOpts = append(rtOpts, runtime.WithPortable()) + } if err := rt.Update(buildPlan, rtHash, rtOpts...); err != nil { return nil, locale.WrapError(err, "err_packages_update_runtime_install") diff --git a/internal/runners/activate/activate.go b/internal/runners/activate/activate.go index 1cf3c2f389..1edb95cb37 100644 --- a/internal/runners/activate/activate.go +++ b/internal/runners/activate/activate.go @@ -95,7 +95,7 @@ func (r *Activate) Run(params *ActivateParams) (rerr error) { } // Perform fresh checkout - pathToUse, err := r.activateCheckout.Run(params.Namespace, params.Branch, "", params.PreferredPath, false, false) + pathToUse, err := r.activateCheckout.Run(params.Namespace, params.Branch, "", params.PreferredPath, false, false, false) if err != nil { return locale.WrapError(err, "err_activate_pathtouse", "Could not figure out what path to use.") } diff --git a/internal/runners/checkout/checkout.go b/internal/runners/checkout/checkout.go index ea2105031e..5d4025d4d9 100644 --- a/internal/runners/checkout/checkout.go +++ b/internal/runners/checkout/checkout.go @@ -38,6 +38,7 @@ type Params struct { RuntimePath string NoClone bool Force bool + Portable bool } type primeable interface { @@ -121,7 +122,7 @@ func (u *Checkout) Run(params *Params) (rerr error) { u.out.Notice(locale.Tr("checking_out", ns.String())) - projectDir, err := u.checkout.Run(ns, params.Branch, params.RuntimePath, params.PreferredPath, params.NoClone, archive != nil) + projectDir, err := u.checkout.Run(ns, params.Branch, params.RuntimePath, params.PreferredPath, params.NoClone, archive != nil, params.Portable) if err != nil { return errs.Wrap(err, "Checkout failed") } diff --git a/internal/runners/deploy/deploy.go b/internal/runners/deploy/deploy.go index b69ac6587b..472c8ecffd 100644 --- a/internal/runners/deploy/deploy.go +++ b/internal/runners/deploy/deploy.go @@ -168,7 +168,7 @@ func (d *Deploy) install(params *Params, commitID strfmt.UUID) (rerr error) { if err := checkout.CreateProjectFiles( params.Path, params.Path, params.Namespace.Owner, params.Namespace.Project, - constants.DefaultBranchName, commitID.String(), "", + constants.DefaultBranchName, commitID.String(), "", true, ); err != nil { return errs.Wrap(err, "Could not create project files") } diff --git a/pkg/project/project.go b/pkg/project/project.go index 22c3d46c60..06ea03ccbe 100644 --- a/pkg/project/project.go +++ b/pkg/project/project.go @@ -255,6 +255,8 @@ func (p *Project) Lock() string { return p.projectfile.Lock } // Cache returns the cache information for this project func (p *Project) Cache() string { return p.projectfile.Cache } +func (p *Project) IsPortable() bool { return p.projectfile.Portable && p.projectfile.Cache != "" } + // Namespace returns project namespace func (p *Project) Namespace() *Namespaced { return &Namespaced{Owner: p.projectfile.Owner(), Project: p.projectfile.Name()} diff --git a/pkg/projectfile/projectfile.go b/pkg/projectfile/projectfile.go index 9761cbb17b..e3ebcc5c62 100644 --- a/pkg/projectfile/projectfile.go +++ b/pkg/projectfile/projectfile.go @@ -108,6 +108,7 @@ type Project struct { Jobs Jobs `yaml:"jobs,omitempty"` Private bool `yaml:"private,omitempty"` Cache string `yaml:"cache,omitempty"` + Portable bool `yaml:"portable,omitempty"` path string // "private" parsedURL projectURL // parsed url data parsedChannel string @@ -920,6 +921,7 @@ type CreateParams struct { path string ProjectURL string Cache string + Portable bool } // Create will create a new activestate.yaml with a projectURL for the given details @@ -1019,7 +1021,7 @@ func createCustom(params *CreateParams, lang language.Language) (*Project, error } if params.Cache != "" { - createErr := createHostFile(params.Directory, params.Cache) + createErr := createHostFile(params.Directory, params.Cache, params.Portable) if createErr != nil { return nil, errs.Wrap(createErr, "Could not create cache file") } @@ -1028,14 +1030,15 @@ func createCustom(params *CreateParams, lang language.Language) (*Project, error return Parse(params.path) } -func createHostFile(filePath, cachePath string) error { +func createHostFile(filePath, cachePath string, portable bool) error { user, err := user.Current() if err != nil { return errs.Wrap(err, "Could not get current user") } data := map[string]interface{}{ - "Cache": cachePath, + "Cache": cachePath, + "Portable": portable, } tplName := "activestate.yaml.cache.tpl" diff --git a/pkg/runtime/options.go b/pkg/runtime/options.go index 19492243cf..d5d57ceb49 100644 --- a/pkg/runtime/options.go +++ b/pkg/runtime/options.go @@ -21,6 +21,10 @@ func WithPreferredLibcVersion(version string) SetOpt { return func(opts *Opts) { opts.PreferredLibcVersion = version } } +func WithPortable() SetOpt { + return func(opts *Opts) { opts.Portable = true } +} + func WithArchive(dir string, platformID strfmt.UUID, ext string) SetOpt { return func(opts *Opts) { opts.FromArchive = &fromArchive{dir, platformID, ext} diff --git a/pkg/runtime/setup.go b/pkg/runtime/setup.go index d35ca25805..a1159454a2 100644 --- a/pkg/runtime/setup.go +++ b/pkg/runtime/setup.go @@ -47,6 +47,7 @@ type Opts struct { EventHandlers []events.HandlerFunc BuildlogFilePath string BuildProgressUrl string + Portable bool FromArchive *fromArchive @@ -467,7 +468,7 @@ func (s *setup) install(id strfmt.UUID) (rerr error) { return errs.Wrap(err, "Could not get env") } - if envDef.NeedsTransforms() || !s.supportsHardLinks { + if envDef.NeedsTransforms() || !s.supportsHardLinks || s.opts.Portable { if err := s.depot.DeployViaCopy(id, envDef.InstallDir, s.path); err != nil { return errs.Wrap(err, "Could not deploy artifact via copy") } From 8b4a5afabc184e0de6c44fb85a52f4988547ab72 Mon Sep 17 00:00:00 2001 From: mitchell Date: Thu, 21 Nov 2024 19:05:36 -0500 Subject: [PATCH 2/2] Do not require custom runtime path for portable projects. --- cmd/state/internal/cmdtree/checkout.go | 2 +- pkg/project/project.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/state/internal/cmdtree/checkout.go b/cmd/state/internal/cmdtree/checkout.go index 0e1c91ab23..05ee821101 100644 --- a/cmd/state/internal/cmdtree/checkout.go +++ b/cmd/state/internal/cmdtree/checkout.go @@ -28,7 +28,7 @@ func newCheckoutCommand(prime *primer.Values) *captain.Command { }, { Name: "portable", - Description: locale.Tl("flag_state_checkout_portable_description", "Copy files to runtime-path instead of linking to them"), + Description: locale.Tl("flag_state_checkout_portable_description", "Copy files to their runtime path instead of linking to them"), Value: ¶ms.Portable, }, { diff --git a/pkg/project/project.go b/pkg/project/project.go index 06ea03ccbe..ad911807fd 100644 --- a/pkg/project/project.go +++ b/pkg/project/project.go @@ -255,7 +255,7 @@ func (p *Project) Lock() string { return p.projectfile.Lock } // Cache returns the cache information for this project func (p *Project) Cache() string { return p.projectfile.Cache } -func (p *Project) IsPortable() bool { return p.projectfile.Portable && p.projectfile.Cache != "" } +func (p *Project) IsPortable() bool { return p.projectfile.Portable } // Namespace returns project namespace func (p *Project) Namespace() *Namespaced {