Skip to content

Commit

Permalink
Add optional digest suffix to template locator
Browse files Browse the repository at this point in the history
The suffix is "@digest" which may include an optional algorithm
(defaults to "sha256"). The encoded digest must be at least 7
characters long.

Examples:
- template://my@sha256:60a87371451eabcd211c929759db61746a7c6a1c068f59d868db6aa8dca637bd
- template://my@sha256:60a87371451
- template://my@60a8737

Signed-off-by: Jan Dubois <[email protected]>
  • Loading branch information
jandubois committed Dec 14, 2024
1 parent 138f55c commit 2ab5c20
Showing 1 changed file with 47 additions and 15 deletions.
62 changes: 47 additions & 15 deletions pkg/limatmpl/locator.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/containerd/containerd/identifiers"
"github.com/lima-vm/lima/pkg/ioutilx"
"github.com/lima-vm/lima/pkg/templatestore"
"github.com/opencontainers/go-digest"
"github.com/sirupsen/logrus"
)

Expand All @@ -33,12 +34,33 @@ func Read(ctx context.Context, name, locator string) (*Template, error) {
Locator: locator,
}

isTemplateURL, templateURL := SeemsTemplateURL(locator)
algorithm := digest.SHA256
expectedDigest := ""

// Split off optional digest suffix
index := strings.LastIndex(locator, "@")
if index > strings.LastIndex(locator, "/") {
tmpl.Locator = locator[:index]
expectedDigest = locator[index+1:]
index = strings.LastIndex(expectedDigest, ":")
if index != -1 {
algorithm = digest.Algorithm(expectedDigest[:index])
expectedDigest = expectedDigest[index+1:]
if !algorithm.Available() {
return nil, fmt.Errorf("locator %q digest algorithm is not available", locator)
}
}
if len(expectedDigest) < 7 {
return nil, fmt.Errorf("locator %q expected digest length less than 7 characters", locator)
}
}

isTemplateURL, templateURL := SeemsTemplateURL(tmpl.Locator)
switch {
case isTemplateURL:
// No need to use SecureJoin here. https://github.com/lima-vm/lima/pull/805#discussion_r853411702
templateName := filepath.Join(templateURL.Host, templateURL.Path)
logrus.Debugf("interpreting argument %q as a template name %q", locator, templateName)
logrus.Debugf("interpreting argument %q as a template name %q", tmpl.Locator, templateName)
if tmpl.Name == "" {
// e.g., templateName = "deprecated/centos-7" , tmpl.Name = "centos-7"
tmpl.Name = filepath.Base(templateName)
Expand All @@ -47,15 +69,15 @@ func Read(ctx context.Context, name, locator string) (*Template, error) {
if err != nil {
return nil, err
}
case SeemsHTTPURL(locator):
case SeemsHTTPURL(tmpl.Locator):
if tmpl.Name == "" {
tmpl.Name, err = InstNameFromURL(locator)
tmpl.Name, err = InstNameFromURL(tmpl.Locator)
if err != nil {
return nil, err
}
}
logrus.Debugf("interpreting argument %q as a http url for instance %q", locator, tmpl.Name)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, locator, http.NoBody)
logrus.Debugf("interpreting argument %q as a http url for instance %q", tmpl.Locator, tmpl.Name)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, tmpl.Locator, http.NoBody)
if err != nil {
return nil, err
}
Expand All @@ -68,15 +90,15 @@ func Read(ctx context.Context, name, locator string) (*Template, error) {
if err != nil {
return nil, err
}
case SeemsFileURL(locator):
case SeemsFileURL(tmpl.Locator):
if tmpl.Name == "" {
tmpl.Name, err = InstNameFromURL(locator)
tmpl.Name, err = InstNameFromURL(tmpl.Locator)
if err != nil {
return nil, err
}
}
logrus.Debugf("interpreting argument %q as a file url for instance %q", locator, tmpl.Name)
r, err := os.Open(strings.TrimPrefix(locator, "file://"))
logrus.Debugf("interpreting argument %q as a file url for instance %q", tmpl.Locator, tmpl.Name)
r, err := os.Open(strings.TrimPrefix(tmpl.Locator, "file://"))
if err != nil {
return nil, err
}
Expand All @@ -85,15 +107,15 @@ func Read(ctx context.Context, name, locator string) (*Template, error) {
if err != nil {
return nil, err
}
case SeemsYAMLPath(locator):
case SeemsYAMLPath(tmpl.Locator):
if tmpl.Name == "" {
tmpl.Name, err = InstNameFromYAMLPath(locator)
tmpl.Name, err = InstNameFromYAMLPath(tmpl.Locator)
if err != nil {
return nil, err
}
}
logrus.Debugf("interpreting argument %q as a file path for instance %q", locator, tmpl.Name)
r, err := os.Open(locator)
logrus.Debugf("interpreting argument %q as a file path for instance %q", tmpl.Locator, tmpl.Name)
r, err := os.Open(tmpl.Locator)
if err != nil {
return nil, err
}
Expand All @@ -102,12 +124,22 @@ func Read(ctx context.Context, name, locator string) (*Template, error) {
if err != nil {
return nil, err
}
case locator == "-":
case tmpl.Locator == "-":
tmpl.Bytes, err = io.ReadAll(os.Stdin)
if err != nil {
return nil, fmt.Errorf("unexpected error reading stdin: %w", err)
}
}

if expectedDigest != "" {
actualDigest := algorithm.FromBytes(tmpl.Bytes).Encoded()
if len(expectedDigest) < len(actualDigest) {
actualDigest = actualDigest[:len(expectedDigest)]
}
if actualDigest != expectedDigest {
return nil, fmt.Errorf("locator %q digest doesn't match content digest %q", locator, actualDigest)
}
}
return tmpl, nil
}

Expand Down

0 comments on commit 2ab5c20

Please sign in to comment.