Merge lp:~chipaca/snappy/dont-panic into lp:snappy/15.04

Proposed by John Lenton
Status: Merged
Approved by: Michael Vogt
Approved revision: 712
Merged at revision: 710
Proposed branch: lp:~chipaca/snappy/dont-panic
Merge into: lp:snappy/15.04
Diff against target: 324 lines (+249/-4)
7 files modified
_integration-tests/testutils/image/image.go (+1/-1)
cmd/snappy/cmd_console.go (+165/-0)
cmd/snappy/cmd_console_test.go (+57/-0)
coreconfig/config.go (+12/-3)
coreconfig/config_test.go (+12/-0)
debian/control (+1/-0)
dependencies.tsv (+1/-0)
To merge this branch: bzr merge lp:~chipaca/snappy/dont-panic
Reviewer Review Type Date Requested Status
Michael Vogt (community) Approve
Review via email: mp+271833@code.launchpad.net

This proposal supersedes a proposal from 2015-09-21.

Commit message

Avoid a panic when coreconfig is given invalid config.

To post a comment you must log in.
Revision history for this message
Michael Vogt (mvo) wrote : Posted in a previous version of this proposal

Thanks!

review: Approve
Revision history for this message
Michael Vogt (mvo) wrote : Posted in a previous version of this proposal

We should probably target this to 15.04, ok?

Revision history for this message
Michael Vogt (mvo) wrote :

\o/

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file '_integration-tests/testutils/image/image.go'
--- _integration-tests/testutils/image/image.go 2015-07-28 04:03:52 +0000
+++ _integration-tests/testutils/image/image.go 2015-09-21 15:47:26 +0000
@@ -51,7 +51,7 @@
51 udfCommand := []string{"sudo", "ubuntu-device-flash", "--verbose"}51 udfCommand := []string{"sudo", "ubuntu-device-flash", "--verbose"}
5252
53 if img.revision != "" {53 if img.revision != "" {
54 udfCommand = append(udfCommand, "--revision", img.revision)54 udfCommand = append(udfCommand, "--revision="+img.revision)
55 }55 }
5656
57 imagePath := img.imagePath(imageDir)57 imagePath := img.imagePath(imageDir)
5858
=== added file 'cmd/snappy/cmd_console.go'
--- cmd/snappy/cmd_console.go 1970-01-01 00:00:00 +0000
+++ cmd/snappy/cmd_console.go 2015-09-21 15:47:26 +0000
@@ -0,0 +1,165 @@
1// -*- Mode: Go; indent-tabs-mode: t -*-
2
3/*
4 * Copyright (C) 2014-2015 Canonical Ltd
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 3 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 */
19
20package main
21
22import (
23 "fmt"
24 "io"
25 "os"
26 "os/exec"
27 "strings"
28
29 "github.com/peterh/liner"
30
31 "launchpad.net/snappy/logger"
32)
33
34// for testing
35var stdout io.Writer = os.Stdout
36
37type cmdConsole struct {
38 repl *liner.State
39 extraCommands []consoleCommand
40}
41
42func init() {
43 _, err := parser.AddCommand("console",
44 "Run snappy console interface",
45 "Run snappy console interface",
46 &cmdConsole{})
47 if err != nil {
48 logger.Panicf("Unable to console: %v", err)
49 }
50}
51
52func (x *cmdConsole) Execute(args []string) error {
53 return x.doConsole()
54}
55
56type consoleCommand struct {
57 name string
58 fn func(line string) error
59}
60
61func (x *cmdConsole) snappyCompleter(line string) (c []string) {
62 // FIXME: add smartz and also complete arguments of
63 // commands
64 for _, cmd := range parser.Commands() {
65 if strings.HasPrefix(cmd.Name, strings.ToLower(line)) {
66 c = append(c, cmd.Name)
67 }
68 }
69 for _, cmd := range x.extraCommands {
70 if strings.HasPrefix(cmd.name, line) {
71 c = append(c, cmd.name)
72 }
73 }
74
75 return c
76}
77
78func (x *cmdConsole) initConsole() error {
79 // FIXME: add history (ReadHistory/WriteHistory)
80
81 x.extraCommands = []consoleCommand{
82 {"help", x.doHelp},
83 {"shell", x.doShell},
84 }
85
86 x.repl = liner.NewLiner()
87 x.repl.SetCompleter(x.snappyCompleter)
88
89 return nil
90}
91
92func (x *cmdConsole) CloseConsole() {
93 x.repl.Close()
94}
95
96func (x *cmdConsole) PrintWelcomeMessage() {
97 fmt.Println("Welcome to the snappy console")
98 fmt.Println("Type 'help' for help")
99 fmt.Println("Type 'shell' for entering a shell")
100}
101
102func (x *cmdConsole) doShell(line string) error {
103 // restore terminal for the shell
104 x.CloseConsole()
105 defer x.initConsole()
106
107 sh := os.Getenv("SHELL")
108 if sh == "" {
109 sh = "/bin/sh"
110 }
111 cmd := exec.Command(sh)
112 cmd.Stdin = os.Stdin
113 cmd.Stdout = os.Stdout
114 cmd.Stderr = os.Stderr
115 if err := cmd.Run(); err != nil {
116 return err
117 }
118
119 return nil
120}
121
122func (x *cmdConsole) doHelp(line string) error {
123 line = strings.TrimPrefix(line, "help")
124 line = strings.TrimSpace(line)
125 parser.Active = nil
126 // find subcmd
127 for _, cmd := range parser.Commands() {
128 if strings.HasPrefix(line, cmd.Name) {
129 parser.Active = cmd
130 break
131 }
132 }
133 parser.WriteHelp(stdout)
134
135 return nil
136}
137
138func (x *cmdConsole) doConsole() error {
139 x.initConsole()
140 defer x.CloseConsole()
141 x.PrintWelcomeMessage()
142
143outer:
144 for {
145 line, err := x.repl.Prompt("> ")
146 if err != nil {
147 return err
148 }
149 x.repl.AppendHistory(line)
150
151 for _, cmd := range x.extraCommands {
152 if strings.HasPrefix(line, cmd.name) {
153 if err := cmd.fn(line); err != nil {
154 fmt.Println(err)
155 }
156 continue outer
157 }
158 }
159
160 if _, err = parser.ParseArgs(strings.Fields(line)); err != nil {
161 fmt.Println(err)
162 }
163
164 }
165}
0166
=== added file 'cmd/snappy/cmd_console_test.go'
--- cmd/snappy/cmd_console_test.go 1970-01-01 00:00:00 +0000
+++ cmd/snappy/cmd_console_test.go 2015-09-21 15:47:26 +0000
@@ -0,0 +1,57 @@
1// -*- Mode: Go; indent-tabs-mode: t -*-
2
3/*
4 * Copyright (C) 2014-2015 Canonical Ltd
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 3 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 */
19
20package main
21
22import (
23 "bytes"
24
25 . "gopkg.in/check.v1"
26)
27
28func (s *CmdTestSuite) TestCmdConsoleCompleter(c *C) {
29 // setup
30 x := cmdConsole{}
31
32 err := x.initConsole()
33 c.Assert(err, IsNil)
34
35 // from cmdline parser
36 c.Check(x.snappyCompleter("hw-"), DeepEquals, []string{"hw-assign", "hw-info", "hw-unassign"})
37
38 // extra consoleCommand
39 c.Check(x.snappyCompleter("he"), DeepEquals, []string{"help"})
40 c.Check(x.snappyCompleter("help"), DeepEquals, []string{"help"})
41}
42
43func (s *CmdTestSuite) TestDoHelpGeneric(c *C) {
44 stdout = bytes.NewBuffer(nil)
45
46 x := cmdConsole{}
47 x.doHelp("")
48 c.Assert(stdout.(*bytes.Buffer).String(), Matches, `(?sm).*Available commands:`)
49}
50
51func (s *CmdTestSuite) TestDoHelpSet(c *C) {
52 stdout = bytes.NewBuffer(nil)
53
54 x := cmdConsole{}
55 x.doHelp("set")
56 c.Assert(stdout.(*bytes.Buffer).String(), Matches, `(?sm).*Set properties of system or package`)
57}
058
=== modified file 'coreconfig/config.go'
--- coreconfig/config.go 2015-09-15 21:35:38 +0000
+++ coreconfig/config.go 2015-09-21 15:47:26 +0000
@@ -58,9 +58,15 @@
58 watchdogStartupPath = "/etc/default/watchdog"58 watchdogStartupPath = "/etc/default/watchdog"
59)59)
6060
61// ErrInvalidUnitStatus signals that a unit is not returning a status61var (
62// of "enabled" or "disabled".62 // ErrInvalidUnitStatus signals that a unit is not returning a status
63var ErrInvalidUnitStatus = errors.New("invalid unit status")63 // of "enabled" or "disabled".
64 ErrInvalidUnitStatus = errors.New("invalid unit status")
65
66 // ErrInvalidConfig is returned from Set when the value
67 // provided is not a valid configuration string.
68 ErrInvalidConfig = errors.New("invalid ubuntu-core configuration")
69)
6470
65type systemConfig struct {71type systemConfig struct {
66 Autopilot *bool `yaml:"autopilot,omitempty"`72 Autopilot *bool `yaml:"autopilot,omitempty"`
@@ -194,6 +200,9 @@
194 return "", err200 return "", err
195 }201 }
196 newConfig := configWrap.Config.UbuntuCore202 newConfig := configWrap.Config.UbuntuCore
203 if newConfig == nil {
204 return "", ErrInvalidConfig
205 }
197206
198 rNewConfig := reflect.ValueOf(newConfig).Elem()207 rNewConfig := reflect.ValueOf(newConfig).Elem()
199 rType := rNewConfig.Type()208 rType := rNewConfig.Type()
200209
=== modified file 'coreconfig/config_test.go'
--- coreconfig/config_test.go 2015-09-15 21:36:22 +0000
+++ coreconfig/config_test.go 2015-09-21 15:47:26 +0000
@@ -148,6 +148,18 @@
148 c.Assert(rawConfig, Equals, expected)148 c.Assert(rawConfig, Equals, expected)
149}149}
150150
151func (cts *ConfigTestSuite) TestSetBadValueDoesNotPanic(c *C) {
152 for _, s := range []string{
153 "",
154 "\n",
155 "config:\n",
156 "config:\n ubuntu-core:\n",
157 } {
158 _, err := Set(s)
159 c.Assert(err, Equals, ErrInvalidConfig)
160 }
161}
162
151// TestSetTimezone is a broad test, close enough to be an integration test.163// TestSetTimezone is a broad test, close enough to be an integration test.
152func (cts *ConfigTestSuite) TestSetTimezone(c *C) {164func (cts *ConfigTestSuite) TestSetTimezone(c *C) {
153 // TODO figure out if we care about exact output or just want valid yaml.165 // TODO figure out if we care about exact output or just want valid yaml.
154166
=== modified file 'debian/control'
--- debian/control 2015-09-14 19:04:47 +0000
+++ debian/control 2015-09-21 15:47:26 +0000
@@ -15,6 +15,7 @@
15 golang-go-flags-dev,15 golang-go-flags-dev,
16 golang-go.crypto-dev,16 golang-go.crypto-dev,
17 golang-goconfigparser-dev,17 golang-goconfigparser-dev,
18 golang-go-liner-dev,
18 golang-pb-dev,19 golang-pb-dev,
19 golang-uboot-go-dev,20 golang-uboot-go-dev,
20 golang-yaml.v2-dev,21 golang-yaml.v2-dev,
2122
=== modified file 'dependencies.tsv'
--- dependencies.tsv 2015-09-16 12:04:05 +0000
+++ dependencies.tsv 2015-09-21 15:47:26 +0000
@@ -6,6 +6,7 @@
6github.com/gosexy/gettext git 98b7b91596d20b96909e6b60d57411547dd9959c 2013-02-21T11:21:43Z6github.com/gosexy/gettext git 98b7b91596d20b96909e6b60d57411547dd9959c 2013-02-21T11:21:43Z
7github.com/jessevdk/go-flags git 1acbbaff2f347c412a0c7884873bd72cc9c1f5b4 2015-08-16T10:05:21Z7github.com/jessevdk/go-flags git 1acbbaff2f347c412a0c7884873bd72cc9c1f5b4 2015-08-16T10:05:21Z
8github.com/mvo5/goconfigparser git 26426272dda20cc76aa1fa44286dc743d2972fe8 2015-02-12T09:37:50Z8github.com/mvo5/goconfigparser git 26426272dda20cc76aa1fa44286dc743d2972fe8 2015-02-12T09:37:50Z
9github.com/peterh/liner git 1bb0d1c1a25ed393d8feb09bab039b2b1b1fbced 2015-04-02T04:04:07Z
9github.com/mvo5/uboot-go git 361f6ebcbb54f389d15dc9faefa000e996ba3e37 2015-07-22T06:53:46Z10github.com/mvo5/uboot-go git 361f6ebcbb54f389d15dc9faefa000e996ba3e37 2015-07-22T06:53:46Z
10golang.org/x/crypto git 60052bd85f2d91293457e8811b0cf26b773de469 2015-06-22T23:34:07Z11golang.org/x/crypto git 60052bd85f2d91293457e8811b0cf26b773de469 2015-06-22T23:34:07Z
11gopkg.in/check.v1 git 64131543e7896d5bcc6bd5a76287eb75ea96c673 2014-10-24T13:38:53Z12gopkg.in/check.v1 git 64131543e7896d5bcc6bd5a76287eb75ea96c673 2014-10-24T13:38:53Z

Subscribers

People subscribed via source and target branches

to all changes: