-
Notifications
You must be signed in to change notification settings - Fork 0
/
refresh-bits
executable file
·338 lines (312 loc) · 11.6 KB
/
refresh-bits
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
#!/bin/sh
#: Name of the architecture to compile for, in uname -m style.
#: This is mapped to various GOARCH values later in the script.
#: If this is empty then architecture is probed, taking devtools_host into
#: account.
devtools_arch=
#: Hostname to connect to if the target device is not local.
#: This can be one of the snappy-* special-cased values (there's an expectation
#: that appropriate pre-made ssh config is available) or any valid hostname.
devtools_host=
#: SSH options to use.
#: Those option are optimized for non-interactive key authentication.
devtools_ssh_opts="-o BatchMode=yes"
devtools_ssh_opts="$devtools_ssh_opts -o UserKnownHostsFile=/dev/null"
devtools_ssh_opts="$devtools_ssh_opts -o CheckHostIP=no"
devtools_ssh_opts="$devtools_ssh_opts -o StrictHostKeyChecking=no"
devtools_ssh_opts="$devtools_ssh_opts -o LogLevel=ERROR"
devtools_ssh_opts="$devtools_ssh_opts -o IdentityFile=~/.ssh/id_rsa"
#: Boot and use a local virtual machine
#: no: no, ssh to a remote box or use this machine right here
#: yes: yes, boot a devtools_vm with run-devel-devtools_vm
devtools_vm=no
#: List of commands to execute (separated by spaces).
#: The commands are one of:
#: - snap build snap (command line user interface)
#: - snapd build snapd (snap daemon)
#: ...
devtools_cmds=""
#: Option passed to systemd-activate.
#: This is only used to pass environment required to use the staging server.
devtools_systemd_activate_opts=""
#: Option pass to the go build command.
#; Used to enable using test keys against the staging store.
devtools_go_build_tags=""
#: Prefix of all the locally compiled executables.
#: This is done so that snap/snapd don't clash with any directories.
#: It also helps to identify devtools if people report odd bugs.
CMD_PREFIX=devtools.
#: Just for inspection
devtools_version=2.0
show_help() {
echo "Usage: refresh-bits [OPTIONS] COMMAND..."
echo
echo "By default everything is done locally."
echo "You can use --vm or --host to change that."
echo
echo "Spin up an ephemeral virtual machine:"
echo " --vm=pc Modern Intel/AMD Computer (64 bit)"
echo " --vm=i386 Legacy Intel/AMD Computer (32 bit)"
echo
echo "Use a remote machine:"
echo " --host=HOST Connect to the given host"
echo
echo "Commands:"
echo " snap Compile and copy 'snap'"
echo " snap-exec Compile and copy 'snap-exec'"
echo " snapd Compile and copy 'snapd'"
echo " setup Stop 'snapd' running on the machine"
echo " restore Restore regular snapd running on the machine"
echo " inspect Check the status of snapd on the target machine"
echo " use-staging Use staging server when talking to Ubuntu store"
echo " run-snapd Run copied 'snapd' (blocking)"
echo
echo "NOTE: The following options require particular SSH config (see README.md)"
echo
echo "NOTE: Typical workflow looks like this:"
echo " console 1: use $EDITOR to hack on the code"
echo " console 2: run unit tests in a loop with entr(1)"
echo " console 3: run ./refresh-bits snap snapd setup run-snapd restore"
echo " console 4: use ssh to login to the target machine"
echo " console 5: (optionally) run run-devel-vm"
echo
echo "Move from console 1 through 2, 3 to 4 to experiment with snap and snapd."
echo "In console 3 you can see diagnostic messages from snapd."
echo
echo "Good luck, happy hacking!"
}
# Quickly show help if invoked without any arguments.
if [ "$1" = "" ]; then
show_help
exit
fi
# Parse commands and store everything. No actions are taken yet.
while [ "$1" != '' ]; do
case "$1" in
--help)
show_help
exit
;;
--version)
echo "devtools refresh-bits version $devtools_version"
exit
;;
--vm=*)
case "$(echo "$1" | cut -d= -f 2)" in
pc)
devtools_arch=x86_64
;;
i386)
devtools_arch=i386
;;
*)
echo "Unsupported virtual machine target"
exit 1
;;
esac
devtools_vm=yes
devtools_host=localhost
devtools_ssh_opts="$devtools_ssh_opts -o Port=8022"
shift
;;
--host=*)
devtools_host="$(echo "$1" | cut -d = -f 2)"
shift
;;
snap|snap-exec|snapd|setup|restore|inspect|run-snapd|use-staging)
devtools_cmds="$devtools_cmds $1"
shift
;;
*)
echo "Unknown command: $1"
exit 1
;;
esac
done
check_connectivity() {
# If we are operating on a remote machine check if we can connect
if [ -n "$devtools_host" ]; then
echo "Checking SSH connectivity..."
ssh $devtools_ssh_opts "$devtools_host" true
if [ "$?" -ne 0 ]; then
echo "Cannot connect to the selected remote device: $devtools_host"
echo
if [ "$devtools_vm" = yes ]; then
echo "You need to start the VM manually with:"
echo " ./run-devel-vm"
echo "You will also have to ensure appropriate SSH config is in place"
else
echo "Please ensure that the machine is up and running and that your credentials are okay."
fi
exit 1
fi
fi
}
probe_architecture() {
# If the architecture is not know then probe it now.
if [ -z "$devtools_arch" ]; then
if [ -n "$devtools_host" ]; then
echo "Checking architecture of the target device..."
devtools_arch="$(ssh $devtools_ssh_opts "$devtools_host" uname -m)"
else
devtools_arch="$(uname -m)"
fi
fi
}
setup_goarch() {
# Do simple sanity checking on the selected architecture
case "$devtools_arch" in
x86_64)
export GOARCH=amd64
;;
i686)
export GOARCH=i386
;;
armv6l)
echo "Unsupported architecture: $devtools_arch"
echo
echo "This architecture is not supported by snapd or by the snappy ecosystem."
echo "Please use a modern (ARMv7 or newer) device such as the Raspberry PI 2."
exit 1
;;
armv7l)
export GOARCH=arm
export GOARM=7
export CGO_ENABLED=1
export CC=arm-linux-gnueabihf-gcc
;;
aarch64)
export GOARCH=arm64
export CGO_ENABLED=1
export CC=aarch64-linux-gnu-gcc
;;
*)
echo "Unsupported architecture ($devtools_arch). Please patch this script"
exit 1
;;
esac
}
show_summary() {
# Print a quick summary to let the developer know what's going on
echo "== Summary =="
case "$devtools_arch" in
*)
if [ "$devtools_arch" != "$(uname -m)" ]; then
echo " - cross-compile binaries for $devtools_arch"
else
echo " - compile binaries for $devtools_arch"
fi
;;
esac
case "$devtools_vm" in
yes)
echo " - use an ephemeral virtual machine (using run-devel-vm)"
;;
no)
case "$devtools_host" in
'')
echo " - run everything locally"
;;
*)
echo " - ssh to '$devtools_host' and run remotely"
;;
esac
;;
esac
}
run_on_target() {
if [ -n "$devtools_host" ]; then
ssh $devtools_ssh_opts "$devtools_host" "$@"
else
"$@"
fi
}
run_commands() {
echo "== Executing Commands =="
while [ -n "$1" ]; do
case "$1" in
snap|snap-exec|snapd)
echo " - building $1"
go build $devtools_go_build_tags -o "$1.$GOARCH" "github.com/snapcore/snapd/cmd/$1" || exit 1
if [ -n "$devtools_host" ]; then
echo "Copying $1 to target device..."
scp $devtools_ssh_opts "$1.$GOARCH" "$devtools_host:${CMD_PREFIX}$1" || exit 1
fi
shift
;;
setup)
echo " - stopping existing snapd..."
run_on_target sudo systemctl stop snapd.socket
run_on_target sudo systemctl stop snapd.service
run_on_target sudo systemctl disable snapd.socket
run_on_target sudo systemctl disable snapd.service
shift
;;
inspect)
echo " - inspecting state (visually)"
run_on_target systemctl status --lines=0 snapd.socket || :
run_on_target systemctl status --lines=0 snapd.service || :
shift
;;
restore)
echo " - restarting regular snapd..."
run_on_target sudo systemctl enable snapd.service
run_on_target sudo systemctl enable snapd.socket
run_on_target sudo systemctl start snapd.socket
run_on_target sudo systemctl start snapd.service
shift
;;
use-staging)
echo " - switched to staging server"
devtools_systemd_activate_opts="--setenv=SNAPPY_USE_STAGING_STORE=1"
devtools_go_build_tags="-tags withtestkeys"
shift
;;
run-snapd)
echo " - running snapd"
echo " NOTE: this is a blocking operation."
echo " Use ctrl-C to stop snapd and process remaining commands"
echo
trap 'printf "\n - interrupted!\n"' INT
if [ -n "$devtools_host" ]; then
echo " Use 'sudo ./${CMD_PREFIX}snap' on another console to talk to this snapd"
( sleep 3s && run_on_target sudo chmod 666 /run/snapd*.socket ) &
run_on_target sudo -H $devtools_systemd_activate $devtools_systemd_activate_opts -l /run/snapd.socket -l /run/snapd-snap.socket ./${CMD_PREFIX}snapd
run_on_target sudo pkill -f ${CMD_PREFIX}snapd
else
echo " Use 'sudo ./snap.$GOARCH' on another console to talk to this snapd"
( sleep 3s && sudo chmod 666 /run/snapd*.socket ) &
sudo -H $devtools_systemd_activate $devtools_systemd_activate_opts -l /run/snapd.socket -l /run/snapd-snap.socket ./snapd.${GOARCH}
fi
trap - INT
shift
;;
esac
done
echo "== All commands processed =="
}
# Find systemd-activate
cmd1="find /lib/systemd -name systemd-activate"
cmd2="find /usr/lib/systemd -name systemd-activate"
cmd3="which systemd-socket-activate"
i=1
while [ $i -le 3 ]; do
devtools_systemd_activate=$(run_on_target $(eval echo -n \${cmd${i}}))
if [ -n "$devtools_systemd_activate" ]; then
break
fi
i=$((i+1))
done
if [ -z "$devtools_systemd_activate" ]; then
echo "NOTE: The target doesn't seem to have systemd installed."
echo "Currently snapd requires systemd (though we are working to remove"
echo "this requirement) and devtools is no different."
echo "Please work on supporting your init system by sending pull requests"
echo "or opening isssues on github.com/zyga/devtools"
exit 1
fi
check_connectivity
probe_architecture
setup_goarch
show_summary
run_commands $devtools_cmds