forked from arschles/deisrel
-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(main.go,actions): create a docker image tagging command #89
Merged
Merged
Changes from 1 commit
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
09dba8a
feat(main.go,actions): create a docker image tagging command
79bf288
fix(docker,actions,git): make lines less than 90 chars
f89ec9a
doc(docker/sdk_client.go): add godocs for sdkClient funcs
04f7ad5
fix(git/move_milestones.go): adjust types according to updated gh code
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains 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
This file contains 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,43 @@ | ||
package docker | ||
|
||
import ( | ||
"github.com/codegangsta/cli" | ||
"github.com/deis/deisrel/actions" | ||
"github.com/deis/deisrel/docker" | ||
"github.com/google/go-github/github" | ||
) | ||
|
||
// Command returns the entire set of subcommands for the 'deisrel docker ...' command | ||
func Command(ghClient *github.Client, dockerCl docker.Client) cli.Command { | ||
return cli.Command{ | ||
Name: "docker", | ||
Subcommands: []cli.Command{ | ||
cli.Command{ | ||
Name: "retag", | ||
Description: "This command pulls specific Docker images for each corresponding repository's Git SHA, then retags each one to a uniform release tag", | ||
Usage: "Retag each specific Docker image from a repo-specific Git SHA to a uniform release tag", | ||
Flags: []cli.Flag{ | ||
cli.BoolFlag{ | ||
Name: actions.YesFlag, | ||
Usage: "If true, skip the prompt to confirm that newly-tagged images will be pushed", | ||
}, | ||
cli.StringFlag{ | ||
Name: actions.ShaFilepathFlag, | ||
Value: "", | ||
Usage: "the file path which to read in the shas to release", | ||
}, | ||
cli.StringFlag{ | ||
Name: newOrgFlag, | ||
Usage: "The Docker registry organization for the new tagged images (default: deis)", | ||
}, | ||
cli.StringFlag{ | ||
Name: actions.RefFlag, | ||
Value: "master", | ||
Usage: "Optional ref to add to GitHub repo request (can be SHA, branch or tag)", | ||
}, | ||
}, | ||
Action: retagCmd(ghClient, dockerCl), | ||
}, | ||
}, | ||
} | ||
} |
This file contains 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,122 @@ | ||
package docker | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
|
||
"github.com/codegangsta/cli" | ||
"github.com/deis/deisrel/actions" | ||
"github.com/deis/deisrel/docker" | ||
"github.com/deis/deisrel/git" | ||
"github.com/google/go-github/github" | ||
) | ||
|
||
const ( | ||
newOrgFlag = "new-org" | ||
defaultNewOrg = "deis" | ||
) | ||
|
||
func getAllReposAndShas(ghClient *github.Client, shaFilePath, ref string) ([]git.RepoAndSha, error) { | ||
var allReposAndShas []git.RepoAndSha | ||
if shaFilePath != "" { | ||
reposFromFile, err := git.GetShasFromFilepath(shaFilePath) | ||
if err != nil { | ||
return nil, fmt.Errorf("getting git SHAs from %s (%s)", shaFilePath, err) | ||
} | ||
allReposAndShas = reposFromFile | ||
} | ||
|
||
reposAndShas, err := git.GetSHAs(ghClient, git.RepoNames(), git.NoTransform, ref) | ||
if err != nil { | ||
return nil, fmt.Errorf("getting all SHAs from HEAD on each repository (%s)", err) | ||
} | ||
allReposAndShas = reposAndShas | ||
return allReposAndShas, nil | ||
} | ||
|
||
func ensureImages(dockerCl docker.Client, images []*docker.Image) { | ||
imgsCh, errCh, doneCh := docker.PullImages(dockerCl, images) | ||
for { | ||
select { | ||
case img := <-imgsCh: | ||
fmt.Printf("pulled %s\n", img.String()) | ||
case err := <-errCh: | ||
fmt.Printf("error pulling %s (%s)\n", err.Img.String(), err.Err) | ||
case <-doneCh: | ||
return | ||
} | ||
} | ||
} | ||
|
||
func retagAll(dockerCl docker.Client, imageTagPairs []docker.ImageTagPair) { | ||
pairsCh, errCh, doneCh := docker.RetagImages(dockerCl, imageTagPairs) | ||
for { | ||
select { | ||
case pair := <-pairsCh: | ||
fmt.Printf("re-tagged %s to %s\n", pair.Source.String(), pair.Target.String()) | ||
case err := <-errCh: | ||
fmt.Printf("error re-tagging %s to %s (%s)\n", err.SourceImage.String(), err.TargetImage.String(), err.Err) | ||
case <-doneCh: | ||
return | ||
} | ||
} | ||
} | ||
|
||
func pushTargets(dockerCl docker.Client, imageTagPairs []docker.ImageTagPair) { | ||
images := make([]*docker.Image, len(imageTagPairs)) | ||
for i, imageTagPair := range imageTagPairs { | ||
images[i] = imageTagPair.Target | ||
} | ||
if err := docker.PushImages(dockerCl, images); err != nil { | ||
log.Printf("Error pushing (%s)", err) | ||
return | ||
} | ||
} | ||
|
||
func retagCmd(ghClient *github.Client, dockerCl docker.Client) func(c *cli.Context) error { | ||
return func(c *cli.Context) error { | ||
newTag := c.Args().Get(0) | ||
if newTag == "" { | ||
log.Fatal("This command should have 1 argument to specify the new tag to use") | ||
} | ||
newOrg := c.String(newOrgFlag) | ||
if newOrg == "" { | ||
newOrg = defaultNewOrg | ||
} | ||
// only prompt to push new images if the yes flag was false | ||
shaFilepath := c.String(actions.ShaFilepathFlag) | ||
ref := c.String(actions.RefFlag) | ||
promptPush := !c.Bool(actions.YesFlag) | ||
|
||
allReposAndShas, err := getAllReposAndShas(ghClient, shaFilepath, ref) | ||
if err != nil { | ||
log.Fatalf("Error getting all git SHAs (%s)", err) | ||
} | ||
|
||
repoAndShaList := git.NewRepoAndShaListFromSlice(allReposAndShas) | ||
repoAndShaList.Sort() | ||
images, err := docker.ParseImagesFromRepoAndShaList(docker.DeisCIDockerOrg, repoAndShaList) | ||
if err != nil { | ||
log.Fatalf("Error parsing docker images (%s)", err) | ||
} | ||
|
||
fmt.Printf("Pulling %d images\n", len(images)) | ||
ensureImages(dockerCl, images) | ||
fmt.Println("Re-tagging images...") | ||
imageTagPairs := docker.CreateImageTagPairsFromTransform(images, func(img docker.Image) *docker.Image { | ||
img.SetRepo(newOrg) | ||
img.SetTag(newTag) | ||
return &img | ||
}) | ||
retagAll(dockerCl, imageTagPairs) | ||
fmt.Println("done") | ||
|
||
if promptPush { | ||
fmt.Println("Pushing new tags") | ||
pushTargets(dockerCl, imageTagPairs) | ||
} else { | ||
fmt.Println("Not pushing newly tagged images") | ||
} | ||
return nil | ||
} | ||
} |
This file contains 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
This file contains 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,8 @@ | ||
package docker | ||
|
||
// Client is the interface to interact with the docker daemon. | ||
type Client interface { | ||
Push(*Image) error | ||
Pull(*Image) error | ||
Retag(*Image, *Image) error | ||
} |
This file contains 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,27 @@ | ||
package docker | ||
|
||
import ( | ||
"os/exec" | ||
) | ||
|
||
type cmdClient struct{} | ||
|
||
// NewCmdClient creates a new Client that does all of its operations by shelling out to the docker CLI | ||
func NewCmdClient() Client { | ||
return &cmdClient{} | ||
} | ||
|
||
func (c *cmdClient) Push(img *Image) error { | ||
cmd := exec.Command("docker", "push", img.String()) | ||
return cmd.Run() | ||
} | ||
|
||
func (c *cmdClient) Pull(img *Image) error { | ||
cmd := exec.Command("docker", "pull", img.String()) | ||
return cmd.Run() | ||
} | ||
|
||
func (c *cmdClient) Retag(src *Image, tar *Image) error { | ||
cmd := exec.Command("docker", "tag", src.String(), tar.String()) | ||
return cmd.Run() | ||
} |
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@arschles can we also allow use of theaddressed in latest changeset.--ref <ref>
flag for this command so that the shas can be pulled from HEAD of a branch other thanmaster
?