Skip to content

Commit

Permalink
src!: change all references of "repository" to "registry" for images
Browse files Browse the repository at this point in the history
When dealing with images, instead of referring to an image repository,
let's instead use the more correct term "registry", even though we're
actually using "registry/namespace" in most case.

Signed-off-by: Lance Ball <lball@redhat.com>
  • Loading branch information
lance committed Oct 6, 2020
1 parent d822303 commit f2cb3bb
Show file tree
Hide file tree
Showing 10 changed files with 123 additions and 127 deletions.
10 changes: 5 additions & 5 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ type Client struct {
describer Describer
dnsProvider DNSProvider // Provider of DNS services
templates string // path to extensible templates
repository string // default repo for OCI image tags
registry string // default registry for OCI image tags
domainSearchLimit int // max recursion when deriving domain
progressListener ProgressListener // progress listener
}
Expand Down Expand Up @@ -241,13 +241,13 @@ func WithTemplates(templates string) Option {
}
}

// WithRepository sets the default registry which is consulted when an image name/tag
// WithRegistry sets the default registry which is consulted when an image name/tag
// is not explocitly provided. Can be fully qualified, including the registry
// (ex: 'quay.io/myname') or simply the namespace 'myname' which indicates the
// the use of the default registry.
func WithRepository(repository string) Option {
func WithRegistry(registry string) Option {
return func(c *Client) {
c.repository = repository
c.registry = registry
}
}

Expand Down Expand Up @@ -393,7 +393,7 @@ func (c *Client) Build(path string) (err error) {
}

// Derive Image from the path (precedence is given to extant config)
if f.Image, err = DerivedImage(path, c.repository); err != nil {
if f.Image, err = DerivedImage(path, c.registry); err != nil {
return
}

Expand Down
57 changes: 28 additions & 29 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ import (
"github.com/boson-project/faas/mock"
)

// TestRepository for calculating destination image during tests.
// TestRegistry for calculating destination image during tests.
// Will be optional once we support in-cluster container registries
// by default. See TestRepositoryRequired for details.
const TestRepository = "quay.io/alice"
// by default. See TestRegistryRequired for details.
const TestRegistry = "quay.io/alice"

// TestCreate completes without error using all defaults and zero values. The base case.
func TestCreate(t *testing.T) {
Expand All @@ -25,7 +25,7 @@ func TestCreate(t *testing.T) {
}
defer os.RemoveAll(root)

client := faas.New(faas.WithRepository(TestRepository))
client := faas.New(faas.WithRegistry(TestRegistry))

if err := client.Create(faas.Function{Root: root}); err != nil {
t.Fatal(err)
Expand All @@ -42,7 +42,7 @@ func TestCreateWritesTemplate(t *testing.T) {
defer os.RemoveAll(root)

// Create the function at root
client := faas.New(faas.WithRepository(TestRepository))
client := faas.New(faas.WithRegistry(TestRegistry))
if err := client.Create(faas.Function{Root: root}); err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -125,7 +125,7 @@ func TestCreateDefaultRuntime(t *testing.T) {
defer os.RemoveAll(root)

// Create a new function at root with all defaults.
client := faas.New(faas.WithRepository(TestRepository))
client := faas.New(faas.WithRegistry(TestRegistry))
if err := client.Create(faas.Function{Root: root}); err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -154,8 +154,7 @@ func TestCreateDefaultTrigger(t *testing.T) {
// location is not defined herein but expected to be provided because, for
// example, a CLI may want to use XDG_CONFIG_HOME. Assuming a repository path
// $FAAS_TEMPLATES, a Go template named 'json' which is provided in the
// repository repository 'boson-experimental', would be expected to be in the
// location:
// repository 'boson-experimental', would be expected to be in the location:
// $FAAS_TEMPLATES/boson-experimental/go/json
// See the CLI for full details, but a standard default location is
// $HOME/.config/templates/boson-experimental/go/json
Expand All @@ -170,7 +169,7 @@ func TestExtensibleTemplates(t *testing.T) {
// Create a new client with a path to the extensible templates
client := faas.New(
faas.WithTemplates("testdata/templates"),
faas.WithRepository(TestRepository))
faas.WithRegistry(TestRegistry))

// Create a Function specifying a template, 'json' that only exists in the extensible set
if err := client.Create(faas.Function{Root: root, Trigger: "boson-experimental/json"}); err != nil {
Expand Down Expand Up @@ -243,7 +242,7 @@ func TestNamed(t *testing.T) {
}
defer os.RemoveAll(root)

client := faas.New(faas.WithRepository(TestRepository))
client := faas.New(faas.WithRegistry(TestRegistry))

if err := client.Create(faas.Function{Root: root, Name: name}); err != nil {
t.Fatal(err)
Expand All @@ -259,19 +258,19 @@ func TestNamed(t *testing.T) {
}
}

// TestRepository ensures that a repository is required, and is
// TestRegistry ensures that a registry is required, and is
// prepended with the DefaultRegistry if a single token.
// Repository is the namespace at the container image registry.
// Registry is the namespace at the container image registry.
// If not prepended with the registry, it will be defaulted:
// Examples: "docker.io/alice"
// "quay.io/bob"
// "charlie" (becomes [DefaultRegistry]/charlie
// At this time a repository namespace is required as we rely on a third-party
// At this time a registry namespace is required as we rely on a third-party
// registry in all cases. When we support in-cluster container registries,
// this configuration parameter will become optional.
func TestRepositoryRequired(t *testing.T) {
func TestRegistryRequired(t *testing.T) {
// Create a root for the Function
root := "testdata/example.com/testRepository"
root := "testdata/example.com/testRegistry"
if err := os.MkdirAll(root, 0700); err != nil {
t.Fatal(err)
}
Expand All @@ -285,7 +284,7 @@ func TestRepositoryRequired(t *testing.T) {
}

// TestDeriveImage ensures that the full image (tag) of the resultant OCI
// container is populated based of a derivation using configured repository
// container is populated based of a derivation using configured registry
// plus the service name.
func TestDeriveImage(t *testing.T) {
// Create the root Function directory
Expand All @@ -296,7 +295,7 @@ func TestDeriveImage(t *testing.T) {
defer os.RemoveAll(root)

// Create the function which calculates fields such as name and image.
client := faas.New(faas.WithRepository(TestRepository))
client := faas.New(faas.WithRegistry(TestRegistry))
if err := client.Create(faas.Function{Root: root}); err != nil {
t.Fatal(err)
}
Expand All @@ -307,14 +306,14 @@ func TestDeriveImage(t *testing.T) {
t.Fatal(err)
}

// In form: [Default Registry]/[Repository Namespace]/[Service Name]:latest
expected := TestRepository + "/" + f.Name + ":latest"
// In form: [Default Registry]/[Registry Namespace]/[Service Name]:latest
expected := TestRegistry + "/" + f.Name + ":latest"
if f.Image != expected {
t.Fatalf("expected image '%v' got '%v'", expected, f.Image)
}
}

// TestDeriveImageDefaultRegistry ensures that a Repository which does not have
// TestDeriveImageDefaultRegistry ensures that a Registry which does not have
// a registry prefix has the DefaultRegistry prepended.
// For example "alice" becomes "docker.io/alice"
func TestDeriveImageDefaultRegistry(t *testing.T) {
Expand All @@ -326,9 +325,9 @@ func TestDeriveImageDefaultRegistry(t *testing.T) {
defer os.RemoveAll(root)

// Create the function which calculates fields such as name and image.
// Rather than use TestRepository, use a single-token name and expect
// Rather than use TestRegistry, use a single-token name and expect
// the DefaultRegistry to be prepended.
client := faas.New(faas.WithRepository("alice"))
client := faas.New(faas.WithRegistry("alice"))
if err := client.Create(faas.Function{Root: root}); err != nil {
t.Fatal(err)
}
Expand All @@ -351,7 +350,7 @@ func TestDeriveImageDefaultRegistry(t *testing.T) {
func TestCreateDelegates(t *testing.T) {
var (
root = "testdata/example.com/testCreateDelegates" // .. in which to initialize
expectedName = "testCreateDelegates" // expected to be derived
expectedName = "testCreateDelegates" // expected to be derived
expectedImage = "quay.io/alice/testCreateDelegates:latest"
builder = mock.NewBuilder()
pusher = mock.NewPusher()
Expand All @@ -366,7 +365,7 @@ func TestCreateDelegates(t *testing.T) {

// Create a client with mocks for each of the subcomponents.
client := faas.New(
faas.WithRepository(TestRepository),
faas.WithRegistry(TestRegistry),
faas.WithBuilder(builder), // builds an image
faas.WithPusher(pusher), // pushes images to a registry
faas.WithDeployer(deployer), // deploys images as a running service
Expand Down Expand Up @@ -437,7 +436,7 @@ func TestRun(t *testing.T) {

// Create a client with the mock runner and the new test Function
runner := mock.NewRunner()
client := faas.New(faas.WithRepository(TestRepository), faas.WithRunner(runner))
client := faas.New(faas.WithRegistry(TestRegistry), faas.WithRunner(runner))
if err := client.Create(faas.Function{Root: root}); err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -480,7 +479,7 @@ func TestUpdate(t *testing.T) {

// A client with mocks whose implementaton will validate input.
client := faas.New(
faas.WithRepository(TestRepository),
faas.WithRegistry(TestRegistry),
faas.WithBuilder(builder),
faas.WithPusher(pusher),
faas.WithUpdater(updater))
Expand Down Expand Up @@ -554,7 +553,7 @@ func TestRemoveByPath(t *testing.T) {
defer os.RemoveAll(root)

client := faas.New(
faas.WithRepository(TestRepository),
faas.WithRegistry(TestRegistry),
faas.WithRemover(remover))

if err := client.Create(faas.Function{Root: root}); err != nil {
Expand Down Expand Up @@ -593,7 +592,7 @@ func TestRemoveByName(t *testing.T) {
defer os.RemoveAll(root)

client := faas.New(
faas.WithRepository(TestRepository),
faas.WithRegistry(TestRegistry),
faas.WithRemover(remover))

if err := client.Create(faas.Function{Root: root}); err != nil {
Expand Down Expand Up @@ -644,7 +643,7 @@ func TestRemoveUninitializedFails(t *testing.T) {

// Instantiate the client with the failing remover.
client := faas.New(
faas.WithRepository(TestRepository),
faas.WithRegistry(TestRegistry),
faas.WithRemover(remover))

// Attempt to remove by path (uninitialized), expecting an error.
Expand Down
56 changes: 27 additions & 29 deletions cmd/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ func init() {
root.AddCommand(buildCmd)
buildCmd.Flags().StringP("builder", "b", "default", "Buildpacks builder")
buildCmd.Flags().BoolP("confirm", "c", false, "Prompt to confirm all configuration options - $FAAS_CONFIRM")
buildCmd.Flags().StringP("image", "i", "", "Optional full image name, in form [registry]/[namespace]/[name]:[tag] for example quay.io/myrepo/project.name:latest (overrides --repository) - $FAAS_IMAGE")
buildCmd.Flags().StringP("image", "i", "", "Optional full image name, in form [registry]/[namespace]/[name]:[tag] for example quay.io/myrepo/project.name:latest (overrides --registry) - $FAAS_IMAGE")
buildCmd.Flags().StringP("path", "p", cwd(), "Path to the Function project directory - $FAAS_PATH")
buildCmd.Flags().StringP("repository", "r", "", "Repository for built images, ex 'docker.io/myuser' or just 'myuser'. Optional if --image provided. - $FAAS_REPOSITORY")
buildCmd.Flags().StringP("registry", "r", "", "Registry for built images, ex 'docker.io/myuser' or just 'myuser'. Optional if --image provided. - $FAAS_REGISTRY")

err := buildCmd.RegisterFlagCompletionFunc("builder", CompleteBuilderList)
if err != nil {
Expand All @@ -32,20 +32,20 @@ var buildCmd = &cobra.Command{
Builds the Function project in the current directory or in the directory
specified by the --path flag. The faas.yaml file is read to determine the
image name and repository. If both of these values are unset in the
configuration file the --repository or -r flag should be provided and an image
image name and registry. If both of these values are unset in the
configuration file the --registry or -r flag should be provided and an image
name will be derived from the project name.
Any value provided for --image or --repository will be persisted in the
faas.yaml configuration file. On subsequent invocations of the "build" command
Any value provided for the --image flag will be persisted in the faas.yaml
configuration file. On subsequent invocations of the "build" command
these values will be read from the configuration file.
It's possible to use a custom Buildpack builder with the --builder flag.
The value may be image name e.g. "cnbs/sample-builder:bionic",
or reference to builderMaps in the config file e.g. "default".
`,
SuggestFor: []string{"biuld", "buidl", "built"},
PreRunE: bindEnv("image", "path", "builder", "repository", "confirm"),
PreRunE: bindEnv("image", "path", "builder", "registry", "confirm"),
RunE: runBuild,
}

Expand All @@ -57,12 +57,12 @@ func runBuild(cmd *cobra.Command, _ []string) (err error) {
}

// If the Function does not yet have an image name, and one was not provided
// on the command line AND a --repository was not provided, then we need to
// prompt for a repository from which we can derive an image name.
if function.Image == "" && config.Repository == "" {
fmt.Print("A repository for Function images is required. For example, 'docker.io/tigerteam'.\n\n")
config.Repository = prompt.ForString("Repository for Function images", "")
if config.Repository == "" {
// on the command line AND a --registry was not provided, then we need to
// prompt for a registry from which we can derive an image name.
if function.Image == "" && config.Registry == "" {
fmt.Print("A registry for Function images is required. For example, 'docker.io/tigerteam'.\n\n")
config.Registry = prompt.ForString("Registry for Function images", "")
if config.Registry == "" {
return fmt.Errorf("Unable to determine Function image name")
}
}
Expand All @@ -72,7 +72,7 @@ func runBuild(cmd *cobra.Command, _ []string) (err error) {

client := faas.New(
faas.WithVerbose(config.Verbose),
faas.WithRepository(config.Repository), // for deriving image name when --image not provided explicitly.
faas.WithRegistry(config.Registry), // for deriving image name when --image not provided explicitly.
faas.WithBuilder(builder))

config.Prompt()
Expand All @@ -82,21 +82,19 @@ func runBuild(cmd *cobra.Command, _ []string) (err error) {

type buildConfig struct {
// Image name in full, including registry, repo and tag (overrides
// image name derivation based on Repository and Function Name)
// image name derivation based on Registry and Function Name)
Image string

// Path of the Function implementation on local disk. Defaults to current
// working directory of the process.
Path string

// Push the resultnat image to the repository after building.
// Push the resulting image to the registry after building.
Push bool

// Repository at which interstitial build artifacts should be kept.
// Registry is optional and is defaulted to faas.DefaultRegistry.
// ex: "quay.io/myrepo" or "myrepo"
// Registry at which interstitial build artifacts should be kept.
// This setting is ignored if Image is specified, which includes the full
Repository string
Registry string

// Verbose logging.
Verbose bool
Expand All @@ -109,20 +107,20 @@ type buildConfig struct {

func newBuildConfig() buildConfig {
return buildConfig{
Image: viper.GetString("image"),
Path: viper.GetString("path"),
Repository: viper.GetString("repository"),
Verbose: viper.GetBool("verbose"), // defined on root
Confirm: viper.GetBool("confirm"),
Builder: viper.GetString("builder"),
Image: viper.GetString("image"),
Path: viper.GetString("path"),
Registry: viper.GetString("registry"),
Verbose: viper.GetBool("verbose"), // defined on root
Confirm: viper.GetBool("confirm"),
Builder: viper.GetString("builder"),
}
}

// Prompt the user with value of config members, allowing for interaractive changes.
// Skipped if not in an interactive terminal (non-TTY), or if --confirm false (agree to
// all prompts) was set (default).
func (c buildConfig) Prompt() buildConfig {
imageName := deriveImage(c.Image, c.Repository, c.Path)
imageName := deriveImage(c.Image, c.Registry, c.Path)
if !interactiveTerminal() || !c.Confirm {
// If --confirm false or non-interactive, just print the image name
fmt.Printf("Building image: %v\n", imageName)
Expand All @@ -132,7 +130,7 @@ func (c buildConfig) Prompt() buildConfig {
Path: prompt.ForString("Path to project directory", c.Path),
Image: prompt.ForString("Image name", imageName, prompt.WithRequired(true)),
Verbose: c.Verbose,
// Repository not prompted for as it would be confusing when combined with explicit image. Instead it is
// inferred by the derived default for Image, which uses Repository for derivation.
// Registry not prompted for as it would be confusing when combined with explicit image. Instead it is
// inferred by the derived default for Image, which uses Registry for derivation.
}
}
Loading

0 comments on commit f2cb3bb

Please sign in to comment.