Skip to content

Commit

Permalink
Merge pull request #9482 from kargakis/deploy-follow
Browse files Browse the repository at this point in the history
Merged by openshift-bot
  • Loading branch information
OpenShift Bot authored Jul 22, 2016
2 parents 8a4af70 + 11e813f commit f924e3b
Show file tree
Hide file tree
Showing 11 changed files with 128 additions and 46 deletions.
1 change: 1 addition & 0 deletions contrib/completions/bash/oc
Original file line number Diff line number Diff line change
Expand Up @@ -1138,6 +1138,7 @@ _oc_deploy()

flags+=("--cancel")
flags+=("--enable-triggers")
flags+=("--follow")
flags+=("--latest")
flags+=("--retry")
flags+=("--api-version=")
Expand Down
1 change: 1 addition & 0 deletions contrib/completions/bash/openshift
Original file line number Diff line number Diff line change
Expand Up @@ -5307,6 +5307,7 @@ _openshift_cli_deploy()

flags+=("--cancel")
flags+=("--enable-triggers")
flags+=("--follow")
flags+=("--latest")
flags+=("--retry")
flags+=("--api-version=")
Expand Down
1 change: 1 addition & 0 deletions contrib/completions/zsh/oc
Original file line number Diff line number Diff line change
Expand Up @@ -1299,6 +1299,7 @@ _oc_deploy()
flags+=("--cancel")
flags+=("--enable-triggers")
flags+=("--follow")
flags+=("--latest")
flags+=("--retry")
flags+=("--api-version=")
Expand Down
1 change: 1 addition & 0 deletions contrib/completions/zsh/openshift
Original file line number Diff line number Diff line change
Expand Up @@ -5468,6 +5468,7 @@ _openshift_cli_deploy()

flags+=("--cancel")
flags+=("--enable-triggers")
flags+=("--follow")
flags+=("--latest")
flags+=("--retry")
flags+=("--api-version=")
Expand Down
3 changes: 3 additions & 0 deletions docs/generated/oc_by_example_content.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -1250,6 +1250,9 @@ View, start, cancel, or retry a deployment
# Start a new deployment based on the 'database'
oc deploy database --latest
# Start a new deployment and follow its log
oc deploy database --latest --follow
# Retry the latest failed deployment based on 'frontend'
# The deployer pod and any hook pods are deleted for the latest failed deployment
oc deploy frontend --retry
Expand Down
7 changes: 7 additions & 0 deletions docs/man/man1/oc-deploy.1
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ If no options are given, shows information about the latest deployment.
\fB\-\-enable\-triggers\fP=false
Enables all image triggers for the deployment config.

.PP
\fB\-\-follow\fP=false
Follow the logs of a deployment

.PP
\fB\-\-latest\fP=false
Start a new deployment now.
Expand Down Expand Up @@ -146,6 +150,9 @@ If no options are given, shows information about the latest deployment.
# Start a new deployment based on the 'database'
oc deploy database \-\-latest

# Start a new deployment and follow its log
oc deploy database \-\-latest \-\-follow

# Retry the latest failed deployment based on 'frontend'
# The deployer pod and any hook pods are deleted for the latest failed deployment
oc deploy frontend \-\-retry
Expand Down
7 changes: 7 additions & 0 deletions docs/man/man1/openshift-cli-deploy.1
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ If no options are given, shows information about the latest deployment.
\fB\-\-enable\-triggers\fP=false
Enables all image triggers for the deployment config.

.PP
\fB\-\-follow\fP=false
Follow the logs of a deployment

.PP
\fB\-\-latest\fP=false
Start a new deployment now.
Expand Down Expand Up @@ -146,6 +150,9 @@ If no options are given, shows information about the latest deployment.
# Start a new deployment based on the 'database'
openshift cli deploy database \-\-latest

# Start a new deployment and follow its log
openshift cli deploy database \-\-latest \-\-follow

# Retry the latest failed deployment based on 'frontend'
# The deployer pod and any hook pods are deleted for the latest failed deployment
openshift cli deploy frontend \-\-retry
Expand Down
73 changes: 54 additions & 19 deletions pkg/cmd/cli/cmd/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ type DeployOptions struct {
retryDeploy bool
cancelDeploy bool
enableTriggers bool
follow bool
}

const (
Expand Down Expand Up @@ -79,6 +80,9 @@ If no options are given, shows information about the latest deployment.`
# Start a new deployment based on the 'database'
%[1]s deploy database --latest
# Start a new deployment and follow its log
%[1]s deploy database --latest --follow
# Retry the latest failed deployment based on 'frontend'
# The deployer pod and any hook pods are deleted for the latest failed deployment
%[1]s deploy frontend --retry
Expand Down Expand Up @@ -118,6 +122,7 @@ func NewCmdDeploy(fullName string, f *clientcmd.Factory, out io.Writer) *cobra.C
cmd.Flags().BoolVar(&options.retryDeploy, "retry", false, "Retry the latest failed deployment.")
cmd.Flags().BoolVar(&options.cancelDeploy, "cancel", false, "Cancel the in-progress deployment.")
cmd.Flags().BoolVar(&options.enableTriggers, "enable-triggers", false, "Enables all image triggers for the deployment config.")
cmd.Flags().BoolVar(&options.follow, "follow", false, "Follow the logs of a deployment")

return cmd
}
Expand Down Expand Up @@ -161,9 +166,15 @@ func (o DeployOptions) Validate() error {
numOptions++
}
if o.cancelDeploy {
if o.follow {
return errors.New("cannot follow the logs while canceling a deployment")
}
numOptions++
}
if o.enableTriggers {
if o.follow {
return errors.New("cannot follow the logs while enabling triggers for a deployment")
}
numOptions++
}
if numOptions > 1 {
Expand All @@ -189,14 +200,17 @@ func (o DeployOptions) RunDeploy() error {

switch {
case o.deployLatest:
err = o.deploy(config, o.out)
err = o.deploy(config)
case o.retryDeploy:
err = o.retry(config, o.out)
err = o.retry(config)
case o.cancelDeploy:
err = o.cancel(config, o.out)
err = o.cancel(config)
case o.enableTriggers:
err = o.reenableTriggers(config, o.out)
err = o.reenableTriggers(config)
default:
if o.follow {
return o.getLogs(config)
}
describer := describe.NewLatestDeploymentsDescriber(o.osClient, o.kubeClient, -1)
desc, err := describer.Describe(config.Namespace, config.Name)
if err != nil {
Expand All @@ -210,7 +224,7 @@ func (o DeployOptions) RunDeploy() error {

// deploy launches a new deployment unless there's already a deployment
// process in progress for config.
func (o DeployOptions) deploy(config *deployapi.DeploymentConfig, out io.Writer) error {
func (o DeployOptions) deploy(config *deployapi.DeploymentConfig) error {
if config.Spec.Paused {
return fmt.Errorf("cannot deploy a paused deployment config")
}
Expand Down Expand Up @@ -238,15 +252,18 @@ func (o DeployOptions) deploy(config *deployapi.DeploymentConfig, out io.Writer)
if err != nil {
return err
}
fmt.Fprintf(out, "Started deployment #%d\n", dc.Status.LatestVersion)
fmt.Fprintf(out, "Use '%s logs -f dc/%s' to track its progress.\n", o.baseCommandName, dc.Name)
fmt.Fprintf(o.out, "Started deployment #%d\n", dc.Status.LatestVersion)
if o.follow {
return o.getLogs(dc)
}
fmt.Fprintf(o.out, "Use '%s logs -f dc/%s' to track its progress.\n", o.baseCommandName, dc.Name)
return nil
}

// retry resets the status of the latest deployment to New, which will cause
// the deployment to be retried. An error is returned if the deployment is not
// currently in a failed state.
func (o DeployOptions) retry(config *deployapi.DeploymentConfig, out io.Writer) error {
func (o DeployOptions) retry(config *deployapi.DeploymentConfig) error {
if config.Spec.Paused {
return fmt.Errorf("cannot retry a paused deployment config")
}
Expand Down Expand Up @@ -295,14 +312,19 @@ func (o DeployOptions) retry(config *deployapi.DeploymentConfig, out io.Writer)
delete(deployment.Annotations, deployapi.DeploymentStatusReasonAnnotation)
delete(deployment.Annotations, deployapi.DeploymentCancelledAnnotation)
_, err = o.kubeClient.ReplicationControllers(deployment.Namespace).Update(deployment)
if err == nil {
fmt.Fprintf(out, "Retried #%d\n", config.Status.LatestVersion)
if err != nil {
return err
}
return err
fmt.Fprintf(o.out, "Retried #%d\n", config.Status.LatestVersion)
if o.follow {
return o.getLogs(config)
}
fmt.Fprintf(o.out, "Use '%s logs -f dc/%s' to track its progress.\n", o.baseCommandName, config.Name)
return nil
}

// cancel cancels any deployment process in progress for config.
func (o DeployOptions) cancel(config *deployapi.DeploymentConfig, out io.Writer) error {
func (o DeployOptions) cancel(config *deployapi.DeploymentConfig) error {
if config.Spec.Paused {
return fmt.Errorf("cannot cancel a paused deployment config")
}
Expand All @@ -311,7 +333,7 @@ func (o DeployOptions) cancel(config *deployapi.DeploymentConfig, out io.Writer)
return err
}
if len(deployments.Items) == 0 {
fmt.Fprintf(out, "There have been no deployments for %s/%s\n", config.Namespace, config.Name)
fmt.Fprintf(o.out, "There have been no deployments for %s/%s\n", config.Namespace, config.Name)
return nil
}
sort.Sort(deployutil.ByLatestVersionDesc(deployments.Items))
Expand All @@ -332,10 +354,10 @@ func (o DeployOptions) cancel(config *deployapi.DeploymentConfig, out io.Writer)
deployment.Annotations[deployapi.DeploymentStatusReasonAnnotation] = deployapi.DeploymentCancelledByUser
_, err := o.kubeClient.ReplicationControllers(deployment.Namespace).Update(&deployment)
if err == nil {
fmt.Fprintf(out, "Cancelled deployment #%d\n", config.Status.LatestVersion)
fmt.Fprintf(o.out, "Cancelled deployment #%d\n", config.Status.LatestVersion)
anyCancelled = true
} else {
fmt.Fprintf(out, "Couldn't cancel deployment #%d (status: %s): %v\n", deployutil.DeploymentVersionFor(&deployment), status, err)
fmt.Fprintf(o.out, "Couldn't cancel deployment #%d (status: %s): %v\n", deployutil.DeploymentVersionFor(&deployment), status, err)
failedCancellations = append(failedCancellations, strconv.FormatInt(deployutil.DeploymentVersionFor(&deployment), 10))
}
}
Expand All @@ -350,7 +372,7 @@ func (o DeployOptions) cancel(config *deployapi.DeploymentConfig, out io.Writer)
maybeCancelling = " (cancelling)"
}
timeAt := strings.ToLower(units.HumanDuration(time.Now().Sub(latest.CreationTimestamp.Time)))
fmt.Fprintf(out, "No deployments are in progress (latest deployment #%d %s%s %s ago)\n",
fmt.Fprintf(o.out, "No deployments are in progress (latest deployment #%d %s%s %s ago)\n",
deployutil.DeploymentVersionFor(latest),
strings.ToLower(string(deployutil.DeploymentStatusFor(latest))),
maybeCancelling,
Expand All @@ -360,7 +382,7 @@ func (o DeployOptions) cancel(config *deployapi.DeploymentConfig, out io.Writer)
}

// reenableTriggers enables all image triggers and then persists config.
func (o DeployOptions) reenableTriggers(config *deployapi.DeploymentConfig, out io.Writer) error {
func (o DeployOptions) reenableTriggers(config *deployapi.DeploymentConfig) error {
enabled := []string{}
for _, trigger := range config.Spec.Triggers {
if trigger.Type == deployapi.DeploymentTriggerOnImageChange {
Expand All @@ -369,13 +391,26 @@ func (o DeployOptions) reenableTriggers(config *deployapi.DeploymentConfig, out
}
}
if len(enabled) == 0 {
fmt.Fprintln(out, "No image triggers found to enable")
fmt.Fprintln(o.out, "No image triggers found to enable")
return nil
}
_, err := o.osClient.DeploymentConfigs(config.Namespace).Update(config)
if err != nil {
return err
}
fmt.Fprintf(out, "Enabled image triggers: %s\n", strings.Join(enabled, ","))
fmt.Fprintf(o.out, "Enabled image triggers: %s\n", strings.Join(enabled, ","))
return nil
}

func (o DeployOptions) getLogs(config *deployapi.DeploymentConfig) error {
opts := deployapi.DeploymentLogOptions{
Follow: true,
}
readCloser, err := o.osClient.DeploymentLogs(config.Namespace).Get(config.Name, opts).Stream()
if err != nil {
return err
}
defer readCloser.Close()
_, err = io.Copy(o.out, readCloser)
return err
}
28 changes: 14 additions & 14 deletions pkg/cmd/cli/cmd/deploy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ func TestCmdDeploy_latestOk(t *testing.T) {
return true, deploymentFor(config, status), nil
})

o := &DeployOptions{osClient: osClient, kubeClient: kubeClient}
err := o.deploy(config, ioutil.Discard)
o := &DeployOptions{osClient: osClient, kubeClient: kubeClient, out: ioutil.Discard}
err := o.deploy(config)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
Expand All @@ -84,9 +84,9 @@ func TestCmdDeploy_latestConcurrentRejection(t *testing.T) {
config := deploytest.OkDeploymentConfig(1)
existingDeployment := deploymentFor(config, status)
kubeClient := ktc.NewSimpleFake(existingDeployment)
o := &DeployOptions{kubeClient: kubeClient}
o := &DeployOptions{kubeClient: kubeClient, out: ioutil.Discard}

err := o.deploy(config, ioutil.Discard)
err := o.deploy(config)
if err == nil {
t.Errorf("expected an error starting deployment with existing status %s", status)
}
Expand All @@ -102,8 +102,8 @@ func TestCmdDeploy_latestLookupError(t *testing.T) {
})

config := deploytest.OkDeploymentConfig(1)
o := &DeployOptions{kubeClient: kubeClient}
err := o.deploy(config, ioutil.Discard)
o := &DeployOptions{kubeClient: kubeClient, out: ioutil.Discard}
err := o.deploy(config)

if err == nil {
t.Fatal("expected an error")
Expand Down Expand Up @@ -150,8 +150,8 @@ func TestCmdDeploy_retryOk(t *testing.T) {
return true, nil, nil
})

o := &DeployOptions{kubeClient: kubeClient}
err := o.retry(config, ioutil.Discard)
o := &DeployOptions{kubeClient: kubeClient, out: ioutil.Discard}
err := o.retry(config)

if err != nil {
t.Fatalf("unexpected error: %v", err)
Expand Down Expand Up @@ -194,8 +194,8 @@ func TestCmdDeploy_retryRejectNonFailed(t *testing.T) {
config := deploytest.OkDeploymentConfig(1)
existingDeployment := deploymentFor(config, status)
kubeClient := ktc.NewSimpleFake(existingDeployment)
o := &DeployOptions{kubeClient: kubeClient}
err := o.retry(config, ioutil.Discard)
o := &DeployOptions{kubeClient: kubeClient, out: ioutil.Discard}
err := o.retry(config)
if err == nil {
t.Errorf("expected an error retrying deployment with status %s", status)
}
Expand Down Expand Up @@ -255,9 +255,9 @@ func TestCmdDeploy_cancelOk(t *testing.T) {
return true, existingDeployments, nil
})

o := &DeployOptions{kubeClient: kubeClient}
o := &DeployOptions{kubeClient: kubeClient, out: ioutil.Discard}

err := o.cancel(config, ioutil.Discard)
err := o.cancel(config)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
Expand Down Expand Up @@ -309,8 +309,8 @@ func TestDeploy_reenableTriggers(t *testing.T) {
config.Spec.Triggers = append(config.Spec.Triggers, mktrigger())
}

o := &DeployOptions{osClient: osClient}
err := o.reenableTriggers(config, ioutil.Discard)
o := &DeployOptions{osClient: osClient, out: ioutil.Discard}
err := o.reenableTriggers(config)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
Expand Down
Loading

0 comments on commit f924e3b

Please sign in to comment.