Merge lp:~axwalk/juju-core/lp1121914-confirm-destroy-environment into lp:~go-bot/juju-core/trunk

Proposed by Andrew Wilkins
Status: Merged
Approved by: Andrew Wilkins
Approved revision: no longer in the source branch.
Merged at revision: 1604
Proposed branch: lp:~axwalk/juju-core/lp1121914-confirm-destroy-environment
Merge into: lp:~go-bot/juju-core/trunk
Diff against target: 177 lines (+92/-6)
3 files modified
cmd/juju/bootstrap_test.go (+1/-1)
cmd/juju/cmd_test.go (+60/-4)
cmd/juju/destroyenvironment.go (+31/-1)
To merge this branch: bzr merge lp:~axwalk/juju-core/lp1121914-confirm-destroy-environment
Reviewer Review Type Date Requested Status
Juju Engineering Pending
Review via email: mp+177820@code.launchpad.net

Commit message

cmd/juju: confirm destroy-environment

Fixes bug 1121914

https://codereview.appspot.com/12158043/

Description of the change

cmd/juju: confirm destroy-environment

Fixes bug 1121914

https://codereview.appspot.com/12158043/

To post a comment you must log in.
Revision history for this message
Andrew Wilkins (axwalk) wrote :

Reviewers: mp+177820_code.launchpad.net,

Message:
Please take a look.

Description:
cmd/juju: confirm destroy-environment

https://code.launchpad.net/~axwalk/juju-core/lp1121914-confirm-destroy-environment/+merge/177820

(do not edit description out of merge proposal)

Please review this at https://codereview.appspot.com/12158043/

Affected files:
   A [revision details]
   M cmd/juju/bootstrap_test.go
   M cmd/juju/cmd_test.go
   M cmd/juju/destroyenvironment.go

Revision history for this message
William Reade (fwereade) wrote :
Revision history for this message
Roger Peppe (rogpeppe) wrote :

LGTM for backwards compatibility, despite
my meh about the functionality itself.

Please reference bug 1121914 in the description
and attach it to the merge proposal.

https://codereview.appspot.com/12158043/diff/1/cmd/juju/destroyenvironment.go
File cmd/juju/destroyenvironment.go (right):

https://codereview.appspot.com/12158043/diff/1/cmd/juju/destroyenvironment.go#newcode32
cmd/juju/destroyenvironment.go:32: f.BoolVar(&c.assumeYes, "yes", false,
"Do not ask for confirmation")
You can delete the flag description from this line - it's taken from
the shortest alias.

https://codereview.appspot.com/12158043/diff/1/cmd/juju/destroyenvironment.go#newcode51
cmd/juju/destroyenvironment.go:51: return nil
I think this should probably return an error here.
The destroy-environment command has not succeeded.

https://codereview.appspot.com/12158043/diff/1/cmd/juju/destroyenvironment.go#newcode62
cmd/juju/destroyenvironment.go:62: Continue [y/N]? `
s/N/n/ ?

https://codereview.appspot.com/12158043/

Revision history for this message
Andrew Wilkins (axwalk) wrote :
Revision history for this message
Go Bot (go-bot) wrote :

Attempt to merge into lp:juju-core failed due to conflicts:

text conflict in cmd/juju/destroyenvironment.go

Revision history for this message
John A Meinel (jameinel) wrote :

https://codereview.appspot.com/12158043/diff/1/cmd/juju/destroyenvironment.go
File cmd/juju/destroyenvironment.go (right):

https://codereview.appspot.com/12158043/diff/1/cmd/juju/destroyenvironment.go#newcode62
cmd/juju/destroyenvironment.go:62: Continue [y/N]? `
On 2013/08/01 01:34:32, axw1 wrote:
> On 2013/07/31 13:41:26, rog wrote:
> > s/N/n/ ?

> I don't think so. It's taken straight from pyjuju, and capitalising
the default
> option is fairly standard IMHO. If there's a preferred way of
conveying the
> default (e.g. "[y/n] (default: n)?") then I'm happy to do a follow-up.

I agree. It is standard practice to capitalize the default option.

https://codereview.appspot.com/12158043/

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'cmd/juju/bootstrap_test.go'
2--- cmd/juju/bootstrap_test.go 2013-07-30 15:24:12 +0000
3+++ cmd/juju/bootstrap_test.go 2013-08-06 05:26:58 +0000
4@@ -108,7 +108,7 @@
5 }
6
7 // Run command and check for uploads.
8- opc, errc := runCommand(new(BootstrapCommand), test.args...)
9+ opc, errc := runCommand(nil, new(BootstrapCommand), test.args...)
10 if uploadCount > 0 {
11 for i := 0; i < uploadCount; i++ {
12 c.Check((<-opc).(dummy.OpPutFile).Env, gc.Equals, "peckham")
13
14=== modified file 'cmd/juju/cmd_test.go'
15--- cmd/juju/cmd_test.go 2013-07-31 04:52:39 +0000
16+++ cmd/juju/cmd_test.go 2013-08-06 05:26:58 +0000
17@@ -4,6 +4,7 @@
18 package main
19
20 import (
21+ "bytes"
22 "os"
23 "reflect"
24
25@@ -118,7 +119,7 @@
26 }
27 }
28
29-func runCommand(com cmd.Command, args ...string) (opc chan dummy.Operation, errc chan error) {
30+func runCommand(ctx *cmd.Context, com cmd.Command, args ...string) (opc chan dummy.Operation, errc chan error) {
31 errc = make(chan error, 1)
32 opc = make(chan dummy.Operation, 200)
33 dummy.Listen(opc)
34@@ -132,7 +133,10 @@
35 return
36 }
37
38- err = com.Run(cmd.DefaultContext())
39+ if ctx == nil {
40+ ctx = cmd.DefaultContext()
41+ }
42+ err = com.Run(ctx)
43 errc <- err
44 }()
45 return
46@@ -140,17 +144,69 @@
47
48 func (*CmdSuite) TestDestroyEnvironmentCommand(c *C) {
49 // normal destroy
50- opc, errc := runCommand(new(DestroyEnvironmentCommand))
51+ opc, errc := runCommand(nil, new(DestroyEnvironmentCommand), "--yes")
52 c.Check(<-errc, IsNil)
53 c.Check((<-opc).(dummy.OpDestroy).Env, Equals, "peckham")
54
55 // destroy with broken environment
56- opc, errc = runCommand(new(DestroyEnvironmentCommand), "-e", "brokenenv")
57+ opc, errc = runCommand(nil, new(DestroyEnvironmentCommand), "--yes", "-e", "brokenenv")
58 c.Check(<-opc, IsNil)
59 c.Check(<-errc, ErrorMatches, "dummy.Destroy is broken")
60 c.Check(<-opc, IsNil)
61 }
62
63+func (*CmdSuite) TestDestroyEnvironmentCommandConfirmation(c *C) {
64+ com := new(DestroyEnvironmentCommand)
65+ c.Check(coretesting.InitCommand(com, nil), IsNil)
66+ c.Check(com.assumeYes, Equals, false)
67+
68+ com = new(DestroyEnvironmentCommand)
69+ c.Check(coretesting.InitCommand(com, []string{"-y"}), IsNil)
70+ c.Check(com.assumeYes, Equals, true)
71+
72+ com = new(DestroyEnvironmentCommand)
73+ c.Check(coretesting.InitCommand(com, []string{"--yes"}), IsNil)
74+ c.Check(com.assumeYes, Equals, true)
75+
76+ var stdin, stdout bytes.Buffer
77+ ctx := cmd.DefaultContext()
78+ ctx.Stdout = &stdout
79+ ctx.Stdin = &stdin
80+
81+ // Ensure confirmation is requested if "-y" is not specified.
82+ stdin.WriteString("n")
83+ opc, errc := runCommand(ctx, new(DestroyEnvironmentCommand))
84+ c.Check(<-errc, ErrorMatches, "Environment destruction aborted")
85+ c.Check(<-opc, IsNil)
86+ c.Check(stdout.String(), Matches, "WARNING:.*peckham.*\\(type: dummy\\)(.|\n)*")
87+
88+ // EOF on stdin: equivalent to answering no.
89+ stdin.Reset()
90+ stdout.Reset()
91+ opc, errc = runCommand(ctx, new(DestroyEnvironmentCommand))
92+ c.Check(<-opc, IsNil)
93+ c.Check(<-errc, ErrorMatches, "Environment destruction aborted")
94+
95+ // "--yes" passed: no confirmation request.
96+ stdin.Reset()
97+ stdout.Reset()
98+ opc, errc = runCommand(ctx, new(DestroyEnvironmentCommand), "--yes")
99+ c.Check(<-errc, IsNil)
100+ c.Check((<-opc).(dummy.OpDestroy).Env, Equals, "peckham")
101+ c.Check(stdout.String(), Equals, "")
102+
103+ // Any of casing of "y" and "yes" will confirm.
104+ for _, answer := range []string{"y", "Y", "yes", "YES"} {
105+ stdin.Reset()
106+ stdout.Reset()
107+ stdin.WriteString(answer)
108+ opc, errc = runCommand(ctx, new(DestroyEnvironmentCommand))
109+ c.Check(<-errc, IsNil)
110+ c.Check((<-opc).(dummy.OpDestroy).Env, Equals, "peckham")
111+ c.Check(stdout.String(), Matches, "WARNING:.*peckham.*\\(type: dummy\\)(.|\n)*")
112+ }
113+}
114+
115 var deployTests = []struct {
116 args []string
117 com *DeployCommand
118
119=== modified file 'cmd/juju/destroyenvironment.go'
120--- cmd/juju/destroyenvironment.go 2013-07-30 01:31:52 +0000
121+++ cmd/juju/destroyenvironment.go 2013-08-06 05:26:58 +0000
122@@ -4,6 +4,12 @@
123 package main
124
125 import (
126+ "errors"
127+ "fmt"
128+ "strings"
129+
130+ "launchpad.net/gnuflag"
131+
132 "launchpad.net/juju-core/cmd"
133 "launchpad.net/juju-core/environs"
134 )
135@@ -11,6 +17,7 @@
136 // DestroyEnvironmentCommand destroys an environment.
137 type DestroyEnvironmentCommand struct {
138 cmd.EnvCommandBase
139+ assumeYes bool
140 }
141
142 func (c *DestroyEnvironmentCommand) Info() *cmd.Info {
143@@ -20,10 +27,33 @@
144 }
145 }
146
147-func (c *DestroyEnvironmentCommand) Run(_ *cmd.Context) error {
148+func (c *DestroyEnvironmentCommand) SetFlags(f *gnuflag.FlagSet) {
149+ c.EnvCommandBase.SetFlags(f)
150+ f.BoolVar(&c.assumeYes, "y", false, "Do not ask for confirmation")
151+ f.BoolVar(&c.assumeYes, "yes", false, "")
152+}
153+
154+func (c *DestroyEnvironmentCommand) Run(ctx *cmd.Context) error {
155 environ, err := environs.NewFromName(c.EnvName)
156 if err != nil {
157 return err
158 }
159+
160+ if !c.assumeYes {
161+ var answer string
162+ fmt.Fprintf(ctx.Stdout, destroyEnvMsg[1:], environ.Name(), environ.Config().Type())
163+ fmt.Fscanln(ctx.Stdin, &answer) // ignore error, treat as "n"
164+ answer = strings.ToLower(answer)
165+ if answer != "y" && answer != "yes" {
166+ return errors.New("Environment destruction aborted")
167+ }
168+ }
169+
170 return environ.Destroy(nil)
171 }
172+
173+const destroyEnvMsg = `
174+WARNING: this command will destroy the %q environment (type: %s)
175+This includes all machines, services, data and other resources.
176+
177+Continue [y/N]? `

Subscribers

People subscribed via source and target branches

to status/vote changes: