Skip to content

Commit

Permalink
Merge pull request #25 from spinkube/executor-flag
Browse files Browse the repository at this point in the history
Add executor option to ScaffoldOptions
  • Loading branch information
bacongobbler authored Feb 23, 2024
2 parents 3c1b742 + c8e7507 commit a9bc71e
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 1 deletion.
32 changes: 31 additions & 1 deletion pkg/cmd/scaffold.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"log"
"os"
"regexp"
"strings"
"text/template"

Expand All @@ -15,6 +16,7 @@ import (
type ScaffoldOptions struct {
from string
replicas int32
executor string
output string
configfile string
}
Expand All @@ -24,6 +26,7 @@ var scaffoldOpts = ScaffoldOptions{}
type appConfig struct {
Name string
Image string
Executor string
Replicas int32
RuntimeConfig string
}
Expand All @@ -35,7 +38,7 @@ metadata:
spec:
image: "{{ .Image }}"
replicas: {{ .Replicas }}
executor: containerd-shim-spin
executor: {{ .Executor }}
{{- if .RuntimeConfig }}
runtimeConfig:
loadFromSecret: {{ .Name }}-runtime-config
Expand Down Expand Up @@ -79,6 +82,18 @@ var scaffoldCmd = &cobra.Command{
}

func scaffold(opts ScaffoldOptions) ([]byte, error) {
// flag validation

// replica count must be greater than 0
if opts.replicas < 0 {
return nil, fmt.Errorf("replicas must be greater than 0")
}

// check that the image reference is valid
if !validateImageReference(opts.from) {
return nil, fmt.Errorf("invalid image reference")
}

reference := strings.Split(opts.from, ":")[0]
referenceParts := strings.Split(reference, "/")
name := referenceParts[len(referenceParts)-1]
Expand All @@ -87,6 +102,7 @@ func scaffold(opts ScaffoldOptions) ([]byte, error) {
Name: name,
Image: opts.from,
Replicas: opts.replicas,
Executor: opts.executor,
}

if opts.configfile != "" {
Expand All @@ -112,9 +128,23 @@ func scaffold(opts ScaffoldOptions) ([]byte, error) {
return output.Bytes(), nil
}

func validateImageReference(imageRef string) bool {
// This regex is designed to match strings that are valid image references, which include an optional registry (like
// "ghcr.io"), a repository name (like "bacongobbler/hello-rust"), and an optional tag (like "1.0.0").
//
// The regex is quite complex, but in general it's looking for sequences of alphanumeric characters, separated by
// periods, underscores, or hyphens, and optionally followed by a slash and more such sequences. The sequences can
// be repeated any number of times. The final sequence can optionally be followed by a colon and another sequence,
// representing the tag.
pattern := `^([a-zA-Z0-9]+(?:[._-][a-zA-Z0-9]+)*/)*([a-zA-Z0-9]+(?:[._-][a-zA-Z0-9]+)*)?(:[a-zA-Z0-9]+(?:[._-][a-zA-Z0-9]+)*)?$|^([a-zA-Z0-9]+(?:[._-][a-zA-Z0-9]+)*/)*([a-zA-Z0-9]+(?:[._-][a-zA-Z0-9]+)*)?(:[a-zA-Z0-9]+(?:[._-][a-zA-Z0-9]+)*)?/([a-zA-Z0-9]+(?:[._-][a-zA-Z0-9]+)*)?(:[a-zA-Z0-9]+(?:[._-][a-zA-Z0-9]+)*)?$`
regex := regexp.MustCompile(pattern)
return regex.MatchString(imageRef)
}

func init() {
scaffoldCmd.Flags().Int32VarP(&scaffoldOpts.replicas, "replicas", "r", 2, "Number of replicas for the spin app")
scaffoldCmd.Flags().StringVarP(&scaffoldOpts.from, "from", "f", "", "Reference in the registry of the Spin application")
scaffoldCmd.Flags().StringVarP(&scaffoldOpts.executor, "executor", "", "containerd-shim-spin", "The executor used to run the Spin application")
scaffoldCmd.Flags().StringVarP(&scaffoldOpts.output, "out", "o", "", "path to file to write manifest yaml")
scaffoldCmd.Flags().StringVarP(&scaffoldOpts.configfile, "runtime-config-file", "c", "", "path to runtime config file")

Expand Down
22 changes: 22 additions & 0 deletions pkg/cmd/scaffold_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ func TestScaffoldCmd(t *testing.T) {
opts: ScaffoldOptions{
from: "ghcr.io/foo/example-app:v0.1.0",
replicas: 2,
executor: "containerd-shim-spin",
},
expected: "scaffold_image.yml",
},
Expand All @@ -27,6 +28,7 @@ func TestScaffoldCmd(t *testing.T) {
opts: ScaffoldOptions{
from: "ghcr.io/foo/example-app:v0.1.0",
replicas: 2,
executor: "containerd-shim-spin",
configfile: "testdata/runtime-config.toml",
},
expected: "scaffold_runtime_config.yml",
Expand All @@ -45,3 +47,23 @@ func TestScaffoldCmd(t *testing.T) {
})
}
}

func TestValidateImageReference_ValidImageReference(t *testing.T) {
testCases := []string{
"bacongobbler/hello-rust",
"bacongobbler/hello-rust:v1.0.0",
"ghcr.io/bacongobbler/hello-rust",
"ghcr.io/bacongobbler/hello-rust:v1.0.0",
"ghcr.io/spinkube/spinkube/runtime-class-manager:v1",
"nginx:latest",
"nginx",
}

for _, tc := range testCases {
t.Run(tc, func(t *testing.T) {
valid := validateImageReference(tc)
require.True(t, valid, "Expected image reference to be valid")
})

}
}

0 comments on commit a9bc71e

Please sign in to comment.