Merge ~morphis/snappy-hwe-snaps/+git/wifi-ap:improve-wizard into ~snappy-hwe-team/snappy-hwe-snaps/+git/wifi-ap:master
- Git
- lp:~morphis/snappy-hwe-snaps/+git/wifi-ap
- improve-wizard
- Merge into master
Status: | Merged |
---|---|
Approved by: | Simon Fels |
Approved revision: | 492e3263bfee589b41777790e700bf5f653b5077 |
Merged at revision: | 4d85a3cf2dcbc9fcb749320a45bf64549c3c7251 |
Proposed branch: | ~morphis/snappy-hwe-snaps/+git/wifi-ap:improve-wizard |
Merge into: | ~snappy-hwe-team/snappy-hwe-snaps/+git/wifi-ap:master |
Diff against target: |
274 lines (+89/-28) 5 files modified
bin/ap.sh (+16/-9) bin/helper.sh (+6/-0) cmd/client/cmd_config.go (+16/-9) cmd/client/cmd_wizard.go (+47/-10) snapcraft.yaml (+4/-0) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
System Enablement Bot | continuous-integration | Approve | |
Konrad Zapałowicz (community) | Approve | ||
Review via email: mp+308686@code.launchpad.net |
Commit message
Description of the change
Improve several things
* Better wording for the wizard
* Add support for disabling connection sharing
* A few script improvements
System Enablement Bot (system-enablement-ci-bot) wrote : | # |
System Enablement Bot (system-enablement-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:1ecb6c3ce8c
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
Matteo Croce (teknoraver) : | # |
System Enablement Bot (system-enablement-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:1c76b4ae3f5
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
System Enablement Bot (system-enablement-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:f3b6650a80d
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
Simon Fels (morphis) : | # |
System Enablement Bot (system-enablement-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:492e3263bfe
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
Preview Diff
1 | diff --git a/bin/ap.sh b/bin/ap.sh | |||
2 | index 6c26b30..89750fa 100755 | |||
3 | --- a/bin/ap.sh | |||
4 | +++ b/bin/ap.sh | |||
5 | @@ -38,9 +38,10 @@ if ! ifconfig $WIFI_INTERFACE ; then | |||
6 | 38 | exit 1 | 38 | exit 1 |
7 | 39 | fi | 39 | fi |
8 | 40 | 40 | ||
10 | 41 | shutdown() { | 41 | cleanup_on_exit() { |
11 | 42 | DNSMASQ_PID=$(cat $SNAP_DATA/dnsmasq.pid) | 42 | DNSMASQ_PID=$(cat $SNAP_DATA/dnsmasq.pid) |
13 | 43 | kill -TERM $DNSMASQ_PID | 43 | # If dnsmasq is already gone don't error out here |
14 | 44 | kill -TERM $DNSMASQ_PID || true | ||
15 | 44 | wait $DNSMASQ_PID | 45 | wait $DNSMASQ_PID |
16 | 45 | 46 | ||
17 | 46 | iface=$WIFI_INTERFACE | 47 | iface=$WIFI_INTERFACE |
18 | @@ -48,7 +49,7 @@ shutdown() { | |||
19 | 48 | iface=$DEFAULT_ACCESS_POINT_INTERFACE | 49 | iface=$DEFAULT_ACCESS_POINT_INTERFACE |
20 | 49 | fi | 50 | fi |
21 | 50 | 51 | ||
23 | 51 | if [ "$SHARE_NETWORK_INTERFACE" != "none" ] ; then | 52 | if [ $SHARE_DISABLED -eq 0 ] ; then |
24 | 52 | # flush forwarding rules out | 53 | # flush forwarding rules out |
25 | 53 | iptables --table nat --delete POSTROUTING --out-interface $SHARE_NETWORK_INTERFACE -j MASQUERADE | 54 | iptables --table nat --delete POSTROUTING --out-interface $SHARE_NETWORK_INTERFACE -j MASQUERADE |
26 | 54 | iptables --delete FORWARD --in-interface $iface -j ACCEPT | 55 | iptables --delete FORWARD --in-interface $iface -j ACCEPT |
27 | @@ -58,6 +59,13 @@ shutdown() { | |||
28 | 58 | if [ "$WIFI_INTERFACE_MODE" == "virtual" ] ; then | 59 | if [ "$WIFI_INTERFACE_MODE" == "virtual" ] ; then |
29 | 59 | $SNAP/bin/iw dev $iface del | 60 | $SNAP/bin/iw dev $iface del |
30 | 60 | fi | 61 | fi |
31 | 62 | |||
32 | 63 | if [ is_nm_running ] ; then | ||
33 | 64 | # Hand interface back to network-manager. This will also trigger the | ||
34 | 65 | # auto connection process inside network-manager to get connected | ||
35 | 66 | # with the previous network. | ||
36 | 67 | $SNAP/bin/nmcli d set $iface managed yes | ||
37 | 68 | fi | ||
38 | 61 | } | 69 | } |
39 | 62 | 70 | ||
40 | 63 | iface=$WIFI_INTERFACE | 71 | iface=$WIFI_INTERFACE |
41 | @@ -88,8 +96,7 @@ if [ "$WIFI_INTERFACE_MODE" = "direct" ] ; then | |||
42 | 88 | fi | 96 | fi |
43 | 89 | 97 | ||
44 | 90 | 98 | ||
47 | 91 | nm_status=`$SNAP/bin/nmcli -t -f RUNNING general` | 99 | if [ is_nm_running ] ; then |
46 | 92 | if [ "$nm_status" = "running" ] ; then | ||
48 | 93 | # Prevent network-manager from touching the interface we want to use. If | 100 | # Prevent network-manager from touching the interface we want to use. If |
49 | 94 | # network-manager was configured to use the interface its nothing we want | 101 | # network-manager was configured to use the interface its nothing we want |
50 | 95 | # to prevent here as this is how the user configured the system. | 102 | # to prevent here as this is how the user configured the system. |
51 | @@ -106,7 +113,7 @@ if [ $? -ne 0 ] ; then | |||
52 | 106 | $SNAP/bin/iw dev $iface del | 113 | $SNAP/bin/iw dev $iface del |
53 | 107 | fi | 114 | fi |
54 | 108 | 115 | ||
56 | 109 | if [ "$nm_status" = "running" ] ; then | 116 | if [ is_nm_running ] ; then |
57 | 110 | # Hand interface back to network-manager. This will also trigger the | 117 | # Hand interface back to network-manager. This will also trigger the |
58 | 111 | # auto connection process inside network-manager to get connected | 118 | # auto connection process inside network-manager to get connected |
59 | 112 | # with the previous network. | 119 | # with the previous network. |
60 | @@ -120,7 +127,7 @@ fi | |||
61 | 120 | ifconfig $iface $WIFI_ADDRESS netmask $WIFI_NETMASK | 127 | ifconfig $iface $WIFI_ADDRESS netmask $WIFI_NETMASK |
62 | 121 | sleep 2 | 128 | sleep 2 |
63 | 122 | 129 | ||
65 | 123 | if [ "$SHARE_NETWORK_INTERFACE" != "none" ] ; then | 130 | if [ $SHARE_DISABLED -eq 0 ] ; then |
66 | 124 | # Enable NAT to forward our network connection | 131 | # Enable NAT to forward our network connection |
67 | 125 | iptables --table nat --append POSTROUTING --out-interface $SHARE_NETWORK_INTERFACE -j MASQUERADE | 132 | iptables --table nat --append POSTROUTING --out-interface $SHARE_NETWORK_INTERFACE -j MASQUERADE |
68 | 126 | iptables --append FORWARD --in-interface $iface -j ACCEPT | 133 | iptables --append FORWARD --in-interface $iface -j ACCEPT |
69 | @@ -198,9 +205,9 @@ function exit_handler() { | |||
70 | 198 | # Wait until hostapd is correctly terminated before we continue | 205 | # Wait until hostapd is correctly terminated before we continue |
71 | 199 | # doing anything | 206 | # doing anything |
72 | 200 | wait $HOSTAPD_PID | 207 | wait $HOSTAPD_PID |
74 | 201 | shutdown | 208 | cleanup_on_exit |
75 | 202 | exit 0 | 209 | exit 0 |
76 | 203 | } | 210 | } |
77 | 204 | 211 | ||
78 | 205 | wait $HOSTAPD_PID | 212 | wait $HOSTAPD_PID |
79 | 206 | shutdown | ||
80 | 207 | \ No newline at end of file | 213 | \ No newline at end of file |
81 | 214 | cleanup_on_exit | ||
82 | diff --git a/bin/helper.sh b/bin/helper.sh | |||
83 | index df56715..5ad68f5 100644 | |||
84 | --- a/bin/helper.sh | |||
85 | +++ b/bin/helper.sh | |||
86 | @@ -50,3 +50,9 @@ generate_dnsmasq_config() { | |||
87 | 50 | EOF | 50 | EOF |
88 | 51 | } > $1 | 51 | } > $1 |
89 | 52 | } | 52 | } |
90 | 53 | |||
91 | 54 | is_nm_running() { | ||
92 | 55 | nm_status=`$SNAP/bin/nmcli -t -f RUNNING general` | ||
93 | 56 | [ "$nm_status" = "running" ] && return 1 | ||
94 | 57 | return 0 | ||
95 | 58 | } | ||
96 | diff --git a/cmd/client/cmd_config.go b/cmd/client/cmd_config.go | |||
97 | index c801b47..8a82f4a 100644 | |||
98 | --- a/cmd/client/cmd_config.go | |||
99 | +++ b/cmd/client/cmd_config.go | |||
100 | @@ -20,6 +20,7 @@ import ( | |||
101 | 20 | "encoding/json" | 20 | "encoding/json" |
102 | 21 | "fmt" | 21 | "fmt" |
103 | 22 | "os" | 22 | "os" |
104 | 23 | "sort" | ||
105 | 23 | ) | 24 | ) |
106 | 24 | 25 | ||
107 | 25 | type setCommand struct{} | 26 | type setCommand struct{} |
108 | @@ -44,21 +45,27 @@ func (cmd *setCommand) Execute(args []string) error { | |||
109 | 44 | type getCommand struct{} | 45 | type getCommand struct{} |
110 | 45 | 46 | ||
111 | 46 | func (cmd *getCommand) Execute(args []string) error { | 47 | func (cmd *getCommand) Execute(args []string) error { |
112 | 47 | if len(args) != 1 { | ||
113 | 48 | return fmt.Errorf("usage: %s get <key>\n", os.Args[0]) | ||
114 | 49 | } | ||
115 | 50 | |||
116 | 51 | response, err := sendHTTPRequest(getServiceConfigurationURI(), "GET", nil) | 48 | response, err := sendHTTPRequest(getServiceConfigurationURI(), "GET", nil) |
117 | 52 | if err != nil { | 49 | if err != nil { |
118 | 53 | return err | 50 | return err |
119 | 54 | } | 51 | } |
120 | 55 | 52 | ||
125 | 56 | wantedKey := args[0] | 53 | if len(args) == 1 { |
126 | 57 | 54 | wantedKey := args[0] | |
127 | 58 | if val, ok := response.Result[wantedKey]; ok { | 55 | if val, ok := response.Result[wantedKey]; ok { |
128 | 59 | fmt.Fprintf(os.Stdout, "%s\n", val) | 56 | fmt.Fprintf(os.Stdout, "%s\n", val) |
129 | 57 | } else { | ||
130 | 58 | return fmt.Errorf("Config item '%s' does not exist", wantedKey) | ||
131 | 59 | } | ||
132 | 60 | } else { | 60 | } else { |
134 | 61 | return fmt.Errorf("Config item '%s' does not exist", wantedKey) | 61 | sortedKeys := make([]string, 0, len(response.Result)) |
135 | 62 | for key, _ := range response.Result { | ||
136 | 63 | sortedKeys = append(sortedKeys, key) | ||
137 | 64 | } | ||
138 | 65 | sort.Strings(sortedKeys) | ||
139 | 66 | for n := range sortedKeys { | ||
140 | 67 | fmt.Fprintf(os.Stdout, "%s: %s\n", sortedKeys[n], response.Result[sortedKeys[n]]) | ||
141 | 68 | } | ||
142 | 62 | } | 69 | } |
143 | 63 | 70 | ||
144 | 64 | return nil | 71 | return nil |
145 | diff --git a/cmd/client/cmd_wizard.go b/cmd/client/cmd_wizard.go | |||
146 | index 0837135..5ba1357 100644 | |||
147 | --- a/cmd/client/cmd_wizard.go | |||
148 | +++ b/cmd/client/cmd_wizard.go | |||
149 | @@ -63,9 +63,19 @@ type wizardStep func(map[string]string, *bufio.Reader) error | |||
150 | 63 | var allSteps = [...]wizardStep{ | 63 | var allSteps = [...]wizardStep{ |
151 | 64 | // determine the WiFi interface | 64 | // determine the WiFi interface |
152 | 65 | func(configuration map[string]string, reader *bufio.Reader) error { | 65 | func(configuration map[string]string, reader *bufio.Reader) error { |
153 | 66 | fmt.Println("What is the name of the wireless interface you want to use?") | ||
154 | 67 | ifaces := findExistingInterfaces(true) | 66 | ifaces := findExistingInterfaces(true) |
156 | 68 | fmt.Print("Available interfaces are: " + strings.Join(ifaces, ", ") + ": ") | 67 | if len(ifaces) == 0 { |
157 | 68 | return fmt.Errorf("There are no valid wireless network interfaces available") | ||
158 | 69 | } else if len(ifaces) == 1 { | ||
159 | 70 | fmt.Println("Automatically selected only available wireless network interface " + ifaces[0]) | ||
160 | 71 | return nil | ||
161 | 72 | } | ||
162 | 73 | fmt.Print("Which wireless interface you want to use? ") | ||
163 | 74 | ifacesVerb := "are" | ||
164 | 75 | if len(ifaces) == 1 { | ||
165 | 76 | ifacesVerb = "is" | ||
166 | 77 | } | ||
167 | 78 | fmt.Printf("Available %s %s:", ifacesVerb, strings.Join(ifaces, ", ")) | ||
168 | 69 | iface := readUserInput(reader) | 79 | iface := readUserInput(reader) |
169 | 70 | if re := regexp.MustCompile("^[[:alnum:]]+$"); !re.MatchString(iface) { | 80 | if re := regexp.MustCompile("^[[:alnum:]]+$"); !re.MatchString(iface) { |
170 | 71 | return fmt.Errorf("Invalid interface name '%s' given", iface) | 81 | return fmt.Errorf("Invalid interface name '%s' given", iface) |
171 | @@ -77,7 +87,7 @@ var allSteps = [...]wizardStep{ | |||
172 | 77 | 87 | ||
173 | 78 | // Ask for WiFi ESSID | 88 | // Ask for WiFi ESSID |
174 | 79 | func(configuration map[string]string, reader *bufio.Reader) error { | 89 | func(configuration map[string]string, reader *bufio.Reader) error { |
176 | 80 | fmt.Print("Insert the ESSID of your access point: ") | 90 | fmt.Print("Which SSID you want to use for the access point: ") |
177 | 81 | iface := readUserInput(reader) | 91 | iface := readUserInput(reader) |
178 | 82 | if len(iface) == 0 || len(iface) > 31 { | 92 | if len(iface) == 0 || len(iface) > 31 { |
179 | 83 | return fmt.Errorf("ESSID length must be between 1 and 31 characters") | 93 | return fmt.Errorf("ESSID length must be between 1 and 31 characters") |
180 | @@ -89,7 +99,7 @@ var allSteps = [...]wizardStep{ | |||
181 | 89 | 99 | ||
182 | 90 | // Select WiFi encryption type | 100 | // Select WiFi encryption type |
183 | 91 | func(configuration map[string]string, reader *bufio.Reader) error { | 101 | func(configuration map[string]string, reader *bufio.Reader) error { |
185 | 92 | fmt.Print("Do you want to protect your network with a WPA2 password? (y/n) ") | 102 | fmt.Print("Do you want to protect your network with a WPA2 password instead of staying open for everyone? (y/n) ") |
186 | 93 | switch resp := strings.ToLower(readUserInput(reader)); resp { | 103 | switch resp := strings.ToLower(readUserInput(reader)); resp { |
187 | 94 | case "y": | 104 | case "y": |
188 | 95 | configuration["wifi.security"] = "wpa2" | 105 | configuration["wifi.security"] = "wpa2" |
189 | @@ -107,7 +117,7 @@ var allSteps = [...]wizardStep{ | |||
190 | 107 | if configuration["wifi.security"] == "open" { | 117 | if configuration["wifi.security"] == "open" { |
191 | 108 | return nil | 118 | return nil |
192 | 109 | } | 119 | } |
194 | 110 | fmt.Print("Insert your WPA2 passphrase: ") | 120 | fmt.Print("Please enter the WPA2 passphrase: ") |
195 | 111 | key := readUserInput(reader) | 121 | key := readUserInput(reader) |
196 | 112 | if len(key) < 8 || len(key) > 63 { | 122 | if len(key) < 8 || len(key) > 63 { |
197 | 113 | return fmt.Errorf("WPA2 passphrase must be between 8 and 63 characters") | 123 | return fmt.Errorf("WPA2 passphrase must be between 8 and 63 characters") |
198 | @@ -151,9 +161,10 @@ var allSteps = [...]wizardStep{ | |||
199 | 151 | } | 161 | } |
200 | 152 | 162 | ||
201 | 153 | fmt.Printf("How many host do you want your DHCP pool to hold to? (1-%d) ", maxpoolsize) | 163 | fmt.Printf("How many host do you want your DHCP pool to hold to? (1-%d) ", maxpoolsize) |
203 | 154 | inputhost, err := strconv.ParseUint(readUserInput(reader), 10, 8) | 164 | input := readUserInput(reader) |
204 | 165 | inputhost, err := strconv.ParseUint(input, 10, 8) | ||
205 | 155 | if err != nil { | 166 | if err != nil { |
207 | 156 | return err | 167 | return fmt.Errorf("Invalid answer: %s", input) |
208 | 157 | } | 168 | } |
209 | 158 | if byte(inputhost) > maxpoolsize { | 169 | if byte(inputhost) > maxpoolsize { |
210 | 159 | return fmt.Errorf("%d is bigger than the maximum pool size %d", inputhost, maxpoolsize) | 170 | return fmt.Errorf("%d is bigger than the maximum pool size %d", inputhost, maxpoolsize) |
211 | @@ -172,11 +183,38 @@ var allSteps = [...]wizardStep{ | |||
212 | 172 | return nil | 183 | return nil |
213 | 173 | }, | 184 | }, |
214 | 174 | 185 | ||
215 | 186 | // Enable or disable connection sharing | ||
216 | 187 | func(configuration map[string]string, reader *bufio.Reader) error { | ||
217 | 188 | fmt.Print("Do you want to enable connection sharing? (y/n) ") | ||
218 | 189 | switch resp := strings.ToLower(readUserInput(reader)); resp { | ||
219 | 190 | case "y": | ||
220 | 191 | configuration["share.disabled"] = "0" | ||
221 | 192 | case "n": | ||
222 | 193 | configuration["share.disabled"] = "1" | ||
223 | 194 | default: | ||
224 | 195 | return fmt.Errorf("Invalid answer: %s", resp) | ||
225 | 196 | } | ||
226 | 197 | |||
227 | 198 | return nil | ||
228 | 199 | }, | ||
229 | 200 | |||
230 | 175 | // Select the wired interface to share | 201 | // Select the wired interface to share |
231 | 176 | func(configuration map[string]string, reader *bufio.Reader) error { | 202 | func(configuration map[string]string, reader *bufio.Reader) error { |
233 | 177 | fmt.Println("What is the wired interface do you want to share?") | 203 | if configuration["share.disabled"] == "1" { |
234 | 204 | return nil | ||
235 | 205 | } | ||
236 | 178 | ifaces := findExistingInterfaces(false) | 206 | ifaces := findExistingInterfaces(false) |
238 | 179 | fmt.Print("Available interfaces are: " + strings.Join(ifaces, ", ") + ": ") | 207 | if len(ifaces) == 0 { |
239 | 208 | fmt.Println("No network interface available which's connection can be shared. Disabling connection sharing.") | ||
240 | 209 | configuration["share.disabled"] = "1" | ||
241 | 210 | return nil | ||
242 | 211 | } | ||
243 | 212 | ifacesVerb := "are" | ||
244 | 213 | if len(ifaces) == 1 { | ||
245 | 214 | ifacesVerb = "is" | ||
246 | 215 | } | ||
247 | 216 | fmt.Println("Which network interface you want to use for connection sharing?") | ||
248 | 217 | fmt.Printf("Available %s %s: ", ifacesVerb, strings.Join(ifaces, ", ")) | ||
249 | 180 | iface := readUserInput(reader) | 218 | iface := readUserInput(reader) |
250 | 181 | if re := regexp.MustCompile("^[[:alnum:]]+$"); !re.MatchString(iface) { | 219 | if re := regexp.MustCompile("^[[:alnum:]]+$"); !re.MatchString(iface) { |
251 | 182 | return fmt.Errorf("Invalid interface name '%s' given", iface) | 220 | return fmt.Errorf("Invalid interface name '%s' given", iface) |
252 | @@ -236,7 +274,6 @@ func (cmd *wizardCommand) Execute(args []string) error { | |||
253 | 236 | } | 274 | } |
254 | 237 | } | 275 | } |
255 | 238 | 276 | ||
256 | 239 | // fmt.Println("configuration: ", configuration) | ||
257 | 240 | return applyConfiguration(configuration) | 277 | return applyConfiguration(configuration) |
258 | 241 | } | 278 | } |
259 | 242 | 279 | ||
260 | diff --git a/snapcraft.yaml b/snapcraft.yaml | |||
261 | index c742c14..5252576 100644 | |||
262 | --- a/snapcraft.yaml | |||
263 | +++ b/snapcraft.yaml | |||
264 | @@ -23,6 +23,10 @@ apps: | |||
265 | 23 | command: bin/client config | 23 | command: bin/client config |
266 | 24 | plugs: | 24 | plugs: |
267 | 25 | - network | 25 | - network |
268 | 26 | setup-wizard: | ||
269 | 27 | command: bin/client wizard | ||
270 | 28 | plugs: | ||
271 | 29 | - network | ||
272 | 26 | management-service: | 30 | management-service: |
273 | 27 | command: bin/service | 31 | command: bin/service |
274 | 28 | daemon: simple | 32 | daemon: simple |
PASSED: Continuous integration, rev:f261fdee0fe 780f8065737654c 48f50926f5e074 /jenkins. canonical. com/system- enablement/ job/generic- build-snap/ 187/ /jenkins. canonical. com/system- enablement/ job/generic- update- snap-mp/ 89/console
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild: /jenkins. canonical. com/system- enablement/ job/generic- build-snap/ 187/rebuild
https:/