This repository was archived by the owner on Aug 30, 2024. It is now read-only.
- Notifications
You must be signed in to change notification settings - Fork18
Uh oh!
There was an error while loading.Please reload this page.
Merged
Changes fromall commits
Commits
Show all changes
6 commits Select commitHold shift + click to select a range
7fc2aaa
Add new image tags commands
cmoog10eb0cc
fixup! Add new image tags commands
cmoog0caca7b
fixup! Add new image tags commands
cmoog1115494
Add ls integration test
cmoog0484bd3
fixup! Add ls integration test
cmooge022826
Hide tags cmd
cmoogFile filter
Filter by extension
Conversations
Failed to load comments.
Loading
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Jump to file
Failed to load files.
Loading
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
36 changes: 36 additions & 0 deletionsci/integration/tags_test.go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package integration | ||
import ( | ||
"context" | ||
"testing" | ||
"cdr.dev/coder-cli/coder-sdk" | ||
"cdr.dev/coder-cli/pkg/tcli" | ||
"cdr.dev/slog/sloggers/slogtest/assert" | ||
) | ||
func TestTags(t *testing.T) { | ||
t.Parallel() | ||
t.Skip("wait for dedicated test cluster so we can create an org") | ||
run(t, "tags-cli-tests", func(t *testing.T, ctx context.Context, c *tcli.ContainerRunner) { | ||
headlessLogin(ctx, t, c) | ||
client := cleanupClient(ctx, t) | ||
ensureImageImported(ctx, t, client, "ubuntu") | ||
c.Run(ctx, "coder tags ls").Assert(t, | ||
tcli.Error(), | ||
) | ||
c.Run(ctx, "coder tags ls --image ubuntu --org default").Assert(t, | ||
tcli.Success(), | ||
) | ||
var tags []coder.ImageTag | ||
c.Run(ctx, "coder tags ls --image ubuntu --org default --output json").Assert(t, | ||
tcli.Success(), | ||
tcli.StdoutJSONUnmarshal(&tags), | ||
) | ||
assert.True(t, "> 0 tags", len(tags) > 0) | ||
// TODO(@cmoog) add create and rm integration tests | ||
}) | ||
} |
68 changes: 68 additions & 0 deletionscoder-sdk/tags.go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package coder | ||
import ( | ||
"context" | ||
"net/http" | ||
"time" | ||
) | ||
// ImageTag is a Docker image tag. | ||
type ImageTag struct { | ||
ImageID string `json:"image_id" table:"-"` | ||
Tag string `json:"tag" table:"Tag"` | ||
LatestHash string `json:"latest_hash" table:"-"` | ||
HashLastUpdatedAt time.Time `json:"hash_last_updated_at" table:"-"` | ||
OSRelease *OSRelease `json:"os_release" table:"OS"` | ||
Environments []*Environment `json:"environments" table:"-"` | ||
UpdatedAt time.Time `json:"updated_at" table:"UpdatedAt"` | ||
CreatedAt time.Time `json:"created_at" table:"-"` | ||
} | ||
// OSRelease is the marshalled /etc/os-release file. | ||
type OSRelease struct { | ||
ID string `json:"id"` | ||
PrettyName string `json:"pretty_name"` | ||
HomeURL string `json:"home_url"` | ||
} | ||
func (o OSRelease) String() string { | ||
return o.PrettyName | ||
} | ||
// CreateImageTagReq defines the request parameters for creating a new image tag. | ||
type CreateImageTagReq struct { | ||
Tag string `json:"tag"` | ||
Default bool `json:"default"` | ||
} | ||
// CreateImageTag creates a new image tag resource. | ||
func (c Client) CreateImageTag(ctx context.Context, imageID string, req CreateImageTagReq) (*ImageTag, error) { | ||
var tag ImageTag | ||
if err := c.requestBody(ctx, http.MethodPost, "/api/images/"+imageID+"/tags", req, tag); err != nil { | ||
return nil, err | ||
} | ||
return &tag, nil | ||
} | ||
// DeleteImageTag deletes an image tag resource. | ||
func (c Client) DeleteImageTag(ctx context.Context, imageID, tag string) error { | ||
return c.requestBody(ctx, http.MethodDelete, "/api/images/"+imageID+"/tags/"+tag, nil, nil) | ||
} | ||
// ImageTags fetch all image tags. | ||
func (c Client) ImageTags(ctx context.Context, imageID string) ([]ImageTag, error) { | ||
var tags []ImageTag | ||
if err := c.requestBody(ctx, http.MethodGet, "/api/images/"+imageID+"/tags", nil, &tags); err != nil { | ||
return nil, err | ||
} | ||
return tags, nil | ||
} | ||
// ImageTagByID fetch an image tag by ID. | ||
func (c Client) ImageTagByID(ctx context.Context, imageID, tagID string) (*ImageTag, error) { | ||
var tag ImageTag | ||
if err := c.requestBody(ctx, http.MethodGet, "/api/images/"+imageID+"/tags/"+tagID, nil, &tag); err != nil { | ||
return nil, err | ||
} | ||
return &tag, nil | ||
} |
1 change: 1 addition & 0 deletionsinternal/cmd/cmd.go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
172 changes: 172 additions & 0 deletionsinternal/cmd/tags.go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
package cmd | ||
import ( | ||
"encoding/json" | ||
"os" | ||
"cdr.dev/coder-cli/coder-sdk" | ||
"cdr.dev/coder-cli/pkg/clog" | ||
"cdr.dev/coder-cli/pkg/tablewriter" | ||
"github.com/spf13/cobra" | ||
"golang.org/x/xerrors" | ||
) | ||
func tagsCmd() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "tags", | ||
Hidden: true, | ||
Short: "operate on Coder image tags", | ||
} | ||
cmd.AddCommand( | ||
tagsLsCmd(), | ||
tagsCreateCmd(), | ||
tagsRmCmd(), | ||
) | ||
return cmd | ||
} | ||
func tagsCreateCmd() *cobra.Command { | ||
var ( | ||
orgName string | ||
imageName string | ||
defaultTag bool | ||
) | ||
cmd := &cobra.Command{ | ||
Use: "create [tag]", | ||
Short: "add an image tag", | ||
Long: "allow users to create environments with this image tag", | ||
Example: `coder tags create latest --image ubuntu --org default`, | ||
Args: cobra.ExactArgs(1), | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
ctx := cmd.Context() | ||
client, err := newClient(ctx) | ||
if err != nil { | ||
return err | ||
} | ||
img, err := findImg(ctx, client, findImgConf{ | ||
orgName: orgName, | ||
imgName: imageName, | ||
email: coder.Me, | ||
}) | ||
if err != nil { | ||
return xerrors.Errorf("find image: %w", err) | ||
} | ||
_, err = client.CreateImageTag(ctx, img.ID, coder.CreateImageTagReq{ | ||
Tag: args[0], | ||
Default: defaultTag, | ||
}) | ||
if err != nil { | ||
return xerrors.Errorf("create image tag: %w", err) | ||
} | ||
clog.LogSuccess("created new tag") | ||
return nil | ||
}, | ||
} | ||
cmd.Flags().StringVarP(&imageName, "image", "i", "", "image name") | ||
cmd.Flags().StringVarP(&orgName, "org", "o", "", "organization name") | ||
cmd.Flags().BoolVar(&defaultTag, "default", false, "make this tag the default for its image") | ||
_ = cmd.MarkFlagRequired("org") | ||
_ = cmd.MarkFlagRequired("image") | ||
return cmd | ||
} | ||
func tagsLsCmd() *cobra.Command { | ||
var ( | ||
orgName string | ||
imageName string | ||
outputFmt string | ||
) | ||
cmd := &cobra.Command{ | ||
Use: "ls", | ||
Example: `coder tags ls --image ubuntu --org default --output json`, | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
ctx := cmd.Context() | ||
client, err := newClient(ctx) | ||
if err != nil { | ||
return err | ||
} | ||
img, err := findImg(ctx, client, findImgConf{ | ||
email: coder.Me, | ||
orgName: orgName, | ||
imgName: imageName, | ||
}) | ||
if err != nil { | ||
return err | ||
} | ||
tags, err := client.ImageTags(ctx, img.ID) | ||
if err != nil { | ||
return err | ||
} | ||
switch outputFmt { | ||
case humanOutput: | ||
err = tablewriter.WriteTable(len(tags), func(i int) interface{} { return tags[i] }) | ||
if err != nil { | ||
return err | ||
} | ||
case jsonOutput: | ||
err := json.NewEncoder(os.Stdout).Encode(tags) | ||
if err != nil { | ||
return err | ||
} | ||
default: | ||
return clog.Error("unknown --output value") | ||
} | ||
return nil | ||
}, | ||
} | ||
cmd.Flags().StringVar(&orgName, "org", "", "organization by name") | ||
cmd.Flags().StringVarP(&imageName, "image", "i", "", "image by name") | ||
cmd.Flags().StringVar(&outputFmt, "output", humanOutput, "output format (human|json)") | ||
_ = cmd.MarkFlagRequired("image") | ||
_ = cmd.MarkFlagRequired("org") | ||
return cmd | ||
} | ||
func tagsRmCmd() *cobra.Command { | ||
var ( | ||
imageName string | ||
orgName string | ||
) | ||
cmd := &cobra.Command{ | ||
Use: "rm [tag]", | ||
Short: "remove an image tag", | ||
Example: `coder tags rm latest --image ubuntu --org default`, | ||
Args: cobra.ExactArgs(1), | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
ctx := cmd.Context() | ||
client, err := newClient(ctx) | ||
if err != nil { | ||
return err | ||
} | ||
img, err := findImg(ctx, client, findImgConf{ | ||
email: coder.Me, | ||
imgName: imageName, | ||
orgName: orgName, | ||
}) | ||
if err != nil { | ||
return err | ||
} | ||
if err = client.DeleteImageTag(ctx, img.ID, args[0]); err != nil { | ||
return err | ||
} | ||
clog.LogSuccess("removed tag") | ||
return nil | ||
}, | ||
} | ||
cmd.Flags().StringVarP(&orgName, "org", "o", "", "organization by name") | ||
cmd.Flags().StringVarP(&imageName, "image", "i", "", "image by name") | ||
_ = cmd.MarkFlagRequired("image") | ||
_ = cmd.MarkFlagRequired("org") | ||
return cmd | ||
} |
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.