├── .gitignore ├── NEWS ├── README.md ├── bootstrap ├── classic.sh ├── refresh-bits ├── reset-state ├── run-devel-vm └── ubuntu-image /.gitignore: -------------------------------------------------------------------------------- 1 | *.img 2 | *~ 3 | snap.* 4 | snappy.* 5 | snapd.* 6 | *.img 7 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | refresh-bits 2.0: 2 | - all new command line interface 3 | - much better usability and simplicity 4 | - support for classic, you can hack on your own machine with ease 5 | ubuntu-image 0.11: 6 | - Use the new 16 series that matches the 16.04 desktop release 7 | - Automatically install kpartx if missing 8 | ubuntu-image 0.10: 9 | - Show available device names when started with "?" 10 | ubuntu-image 0.9: 11 | - Refresh hashes for ubuntu-device-flash 12 | - Improve usability of refresh-bits 13 | ubuntu-image 0.8: 14 | - Mark dragon board as officially supported 15 | 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Snappy Development Tools 2 | 3 | This repository holds my personal snappy development tools. Improvements are 4 | welcome, just shoot merge requests at me. 5 | 6 | My work-flow involves using a checkout of http://github.com/snapcore/snapd 7 | in my ``$GOPATH``, building and testing various parts of snappy during daily 8 | development. 9 | 10 | ## Working with developer boards and VMs 11 | 12 | For on-device testing I use the ``ubuntu-image`` script to build development 13 | images. Once a device is "flashed" it can stay up indefinitely. Devices that 14 | don't have automatic update available need to be re-flashed periodically, as 15 | updates are rolled out. 16 | 17 | For on-VM testing I use ``ubuntu-image --developer-mode pc`` along with 18 | ``run-devel-vm pc``. The VM can be killed at any time, nothing that is changed 19 | in the VM is persistent. 20 | 21 | In both cases I use the ``refresh-bits`` script to push new, ``snap``, 22 | ``snapd`` and ``snappy`` (deprecated) binaries over. This requires a certain 23 | SSH setup: 24 | 25 | ## SSH configuration 26 | 27 | If you are going to use any remote machines please ensure that you can connect 28 | to them with SSH without a password prompt. In addition you should not need a 29 | password to use sudo. 30 | -------------------------------------------------------------------------------- /bootstrap: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # This is the bootstrap script. The universal tool to setup any host for 3 | # building snapd. This script is never complete. If you are reading it because 4 | # it failed on your distribution then I encourage you to patch it and share 5 | # your patch with the upstream developers. 6 | 7 | #: Identifier of the operating system as described by os-release(5) 8 | devtools_ID= 9 | 10 | #: Identifier of the operating system as described by os-release(5) 11 | devtools_ID_LIKE= 12 | 13 | #: Version of the operating system as described by os-release(5) 14 | devtools_VERSION_ID= 15 | 16 | #: Pretty name of the operating system as described by os-release(5) 17 | devtools_PRETTY_NAME= 18 | 19 | #: Default value of GOPATH that is set if there is no other value yet 20 | devtools_GOPATH='~/go' 21 | 22 | #: Name of the native packaging system (wrapper) of the host OS. 23 | #: Supported values are: apt yum dnf zypper pacman 24 | devtools_host_pkg_tool= 25 | 26 | #: List of package names that need to be installed with the native packaging 27 | # system of the host OS. 28 | devtools_host_pkg_list= 29 | 30 | #: Flag indicating if pre-built go release should be downloaded and installed. 31 | #: Set to "yes" to enable. 32 | devtools_prebuilt_go=no 33 | 34 | #: Flag indicating if ~/.profile was modified. 35 | devtools_profile_changed=no 36 | 37 | 38 | detect_os() { 39 | if [ -e /etc/os-release ]; then 40 | devtools_ID="$( . /etc/os-release && echo "${ID:-linux}" )" 41 | devtools_ID_LIKE="$( . /etc/os-release && echo "${ID_LIKE}" )" 42 | devtools_VERSION_ID="$( . /etc/os-release && echo "${VERSION_ID}" )" 43 | devtools_PRETTY_NAME="$( . /etc/os-release && echo "${PRETTY_NAME}" )" 44 | else 45 | echo "Unable to detect operating system type" 46 | echo "Please read this script and improve it!" 47 | exit 1 48 | fi 49 | } 50 | 51 | 52 | determine_requirements_like_debian() { 53 | devtools_host_pkg_tool=apt 54 | devtools_host_pkg_list="git bzr automake autoconf indent make gcc squashfs-tools golang-go" 55 | } 56 | 57 | determine_requirements_rhel() { 58 | case "$devtools_VERSION_ID" in 59 | 7.2) 60 | devtools_prebuilt_go=yes 61 | devtools_host_pkg_tool=yum 62 | devtools_host_pkg_list="git bzr automake autoconf indent make gcc squashfs-tools wget" 63 | ;; 64 | *) 65 | echo "Unsupported RHEL version: $devtools_VERSION_ID" 66 | echo "Please read this script and improve it!" 67 | exit 1 68 | ;; 69 | esac 70 | } 71 | 72 | determine_requirements_fedora() { 73 | case "$devtools_VERSION_ID" in 74 | 24) 75 | devtools_host_pkg_tool=dnf 76 | devtools_host_pkg_list="git bzr automake autoconf indent make gcc squashfs-tools golang" 77 | ;; 78 | *) 79 | echo "Unsupported Fedora version: $devtools_VERSION_ID" 80 | echo "Please read this script and improve it!" 81 | exit 1 82 | ;; 83 | esac 84 | } 85 | 86 | determine_requirements_opensuse() { 87 | case "$devtools_VERSION_ID" in 88 | 42.1) 89 | devtools_host_pkg_tool=zypper 90 | devtools_host_pkg_list="git bzr automake autoconf indent make gcc squashfs go" 91 | ;; 92 | *) 93 | echo "Unsupported openSUSE version: $devtools_VERSION_ID" 94 | echo "Please read this script and improve it!" 95 | exit 1 96 | ;; 97 | esac 98 | } 99 | 100 | determine_requirements_gentoo() { 101 | devtools_host_pkg_tool=emerge 102 | devtools_host_pkg_list="dev-vcs/git dev-vcs/bzr sys-devel/automake sys-devel/autoconf dev-util/indent sys-devel/make sys-devel/gcc sys-fs/squashfs-tools dev-lang/go" 103 | } 104 | 105 | determine_requirements_other() { 106 | if [ "${devtools_ID_LIKE}" = "debian" ]; then 107 | determine_requirements_like_debian 108 | else 109 | echo "Unsupported distribution: $devtools_ID" 110 | echo "Please read this script and improve it!" 111 | exit 1 112 | fi 113 | } 114 | 115 | determine_requirements() { 116 | case "$devtools_ID" in 117 | fedora) determine_requirements_fedora ;; 118 | gentoo) determine_requirements_gentoo ;; 119 | opensuse) determine_requirements_opensuse ;; 120 | rhel) determine_requirements_rhel ;; 121 | *) determine_requirements_other ;; 122 | esac 123 | } 124 | 125 | 126 | install_native_packages() { 127 | # Check if there is anything to do first 128 | devtools_install_needed=no 129 | case "$devtools_host_pkg_tool" in 130 | apt) 131 | for devtools_host_pkg in $devtools_host_pkg_list; do 132 | if ! dpkg --status "$devtools_host_pkg" | grep -F -q 'Status: install ok installed'; then 133 | devtools_install_needed=yes 134 | break 135 | fi 136 | done 137 | ;; 138 | emerge) 139 | set -x 140 | for devtools_host_pkg in $devtools_host_pkg_list; do 141 | if ! emerge --pretend --quiet "$devtools_host_pkg" | grep -v -F '[ebuild R ]'; then 142 | devtools_install_needed=yes 143 | break 144 | fi 145 | done 146 | set +x 147 | ;; 148 | yum|zypper|dnf) 149 | for devtools_host_pkg in $devtools_host_pkg_list; do 150 | if ! rpm -q --quiet "$devtools_host_pkg"; then 151 | devtools_install_needed=yes 152 | break 153 | fi 154 | done 155 | ;; 156 | *) 157 | echo "Unsupported native package manager: $devtools_host_pkg_tool" 158 | exit 1 159 | esac 160 | if [ "$devtools_install_needed" = no ]; then 161 | # If there is nothing to do, don't try to install packages in vein 162 | return 163 | fi 164 | case "$devtools_host_pkg_tool" in 165 | apt) 166 | devtools_host_pkg_install_cmd="apt install $devtools_host_pkg_list" 167 | ;; 168 | emerge) 169 | devtools_host_pkg_install_cmd="emerge $devtools_host_pkg_list" 170 | ;; 171 | yum) 172 | devtools_host_pkg_install_cmd="yum install $devtools_host_pkg_list" 173 | ;; 174 | dnf) 175 | devtools_host_pkg_install_cmd="dnf install $devtools_host_pkg_list" 176 | ;; 177 | zypper) 178 | devtools_host_pkg_install_cmd="zypper install $devtools_host_pkg_list" 179 | ;; 180 | *) 181 | echo "Unsupported native package manager: $devtools_host_pkg_tool" 182 | exit 1 183 | esac 184 | # Really install packages now 185 | echo "Installing required packages using native packaging system..." 186 | set -x 187 | sudo $devtools_host_pkg_install_cmd || exit 1 188 | set +x 189 | } 190 | 191 | 192 | install_prebuilt_go() { 193 | if [ "$devtools_prebuilt_go" != yes ]; then 194 | # Don't download and install pre-built go release unless required 195 | return 196 | fi 197 | # Which release to download? 198 | devtools_arch="$(uname -m)" 199 | case "$devtools_arch" in 200 | i386|i686) 201 | devtools_go_dist=go1.6.2.linux-386.tar.gz 202 | devtools_go_dist_sha512=36f31debe7797999ba023230a78668f1a4893b24dbf2af3f2ff361dec3b84557abeb9bdd6595b65ae852c3b353fccecc213a68da26da8a11742338677ca5555f 203 | ;; 204 | x86_64) 205 | devtools_go_dist=go1.6.2.linux-amd64.tar.gz 206 | devtools_go_dist_sha512=6c3102f74df0cc4c533eb7ffc99c364c9d238067dfa8626aac4e684a6a0a0bb079afc3bb98db16bd44fdde529c4fe60554d6d30272ca4bb365926646de0c4d3d 207 | ;; 208 | *) 209 | echo "Unsupported processor architecture: $devtools_arch" 210 | echo "There is no pre-built release of go that can be used on your processor" 211 | exit 1 212 | ;; 213 | esac 214 | if [ ! -d /usr/local/go ]; then 215 | # Download go... 216 | if [ ! -f $devtools_go_dist ]; then 217 | echo "Downloading pre-built go release..." 218 | set -x 219 | wget "https://storage.googleapis.com/golang/$devtools_go_dist" || exit 1 220 | set +x 221 | fi 222 | # ... then check it... 223 | if [ "$(sha512sum "$devtools_go_dist" | cut -d ' ' -f 1)" != "$devtools_go_dist_sha512" ]; then 224 | echo "Downloaded pre-built go release doesn't match expected sha512 checksum" 225 | echo "The file is: $devtools_go_dist" 226 | echo "The expected checksum was: $devtools_go_dist_sha512" 227 | echo 228 | echo "Please inspect and remove it then re-run this script." 229 | echo "If the problem persists please report this problem using:" 230 | echo "https://github.com/zyga/devtools/issues/new" 231 | exit 1 232 | fi 233 | # ... and install it to /usr/local 234 | echo "Installing pre-built go release..." 235 | set -x 236 | sudo tar -C /usr/local -xzf "$devtools_go_dist" || exit 1 237 | set +x 238 | fi 239 | # Add the new local installation to PATH 240 | if echo "$PATH" | grep -q /usr/local/go/bin; then 241 | # Don't modify $PATH unless required 242 | return 243 | fi 244 | if [ -f ~/.profile ] && grep -q '^# devtools: path$' ~/.profile; then 245 | # Don't add the same thing twice 246 | return 247 | fi 248 | echo "Adding locally-installed go to PATH" 249 | devtools_profile_changed=yes 250 | cat >> ~/.profile << __SNIPPET__ 251 | # Added by github.com/zyga/devtools (bootstrap.sh) 252 | # devtools: path 253 | export PATH="\$PATH:/usr/local/go/bin" 254 | __SNIPPET__ 255 | } 256 | 257 | 258 | setup_gopath() { 259 | if [ -n "$GOPATH" ]; then 260 | # Don't clobber $GOPATH if the user already has one 261 | return 262 | fi 263 | if [ -f ~/.profile ] && grep -E -q '^# devtools: gopath$' ~/.profile; then 264 | # Don't add the same thing twice 265 | return 266 | fi 267 | echo "Setting GOPATH to $devtools_GOPATH" 268 | devtools_profile_changed=yes 269 | cat >> ~/.profile << __SNIPPET__ 270 | # Added by github.com/zyga/devtools (bootstrap.sh) 271 | # devtools: gopath 272 | export GOPATH=$devtools_GOPATH 273 | __SNIPPET__ 274 | } 275 | 276 | 277 | notify_of_profile_changes() { 278 | if [ "$devtools_profile_changed" = yes ]; then 279 | echo "===========================================================" 280 | echo "NOTE: This script has modified your shell profile but those" 281 | echo "changes are not automatically applied to your running shell" 282 | echo 283 | echo "To be able to build snapd re-load your shell profile file" 284 | echo "Using the following command:" 285 | echo " . ~/.profile" 286 | fi 287 | } 288 | 289 | 290 | show_summary() { 291 | echo "===========================================================" 292 | echo "Operating system: $devtools_PRETTY_NAME" 293 | echo "Native package manager: $devtools_host_pkg_tool" 294 | echo "List of required packages: $devtools_host_pkg_list" 295 | echo "Install pre-built go release: $devtools_prebuilt_go" 296 | echo 297 | echo "You should be good to go now :-)" 298 | echo "Try running the refresh-bits script" 299 | echo " $ refresh-bits snap snapd" 300 | echo 301 | echo "Good luck!" 302 | echo 303 | } 304 | 305 | 306 | detect_os 307 | determine_requirements 308 | install_native_packages 309 | install_prebuilt_go 310 | setup_gopath 311 | notify_of_profile_changes 312 | show_summary 313 | -------------------------------------------------------------------------------- /classic.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Run this script on an all-snap device to get quick-n-dirty version of the classic dimension 3 | 4 | if [ "$(id -u)" -ne 0 ]; then 5 | echo "this script needs to run as root" 6 | exit 1 7 | fi 8 | case "$(uname -m)" in 9 | i686) 10 | arch=i386 11 | ;; 12 | x86_64) 13 | arch=amd64 14 | ;; 15 | armv7l) 16 | arch=armhf 17 | ;; 18 | aarch64) 19 | arch=arm64 20 | ;; 21 | *) 22 | echo "Unsupported architecture!" 23 | exit 1 24 | ;; 25 | esac 26 | 27 | if [ ! -f "xenial-base-$arch.tar.gz" ]; then 28 | echo "Downloading xenial chroot for $arch..." 29 | python3 -c "from urllib.request import urlretrieve; urlretrieve('http://cdimage.ubuntu.com/ubuntu-base/xenial/daily/current/xenial-base-$arch.tar.gz', 'xenial-base-$arch.tar.gz')" 30 | fi 31 | 32 | if [ ! -d xenial ]; then 33 | mkdir xenial 34 | echo "Uncompressing xenial chroot..." 35 | tar -zxf "xenial-base-$arch.tar.gz" -C xenial 36 | fi 37 | 38 | cleanup() { 39 | umount -l xenial/home 40 | umount -l xenial/sys 41 | umount -l xenial/dev/pts 42 | umount -l xenial/dev 43 | umount -l xenial/proc 44 | } 45 | 46 | trap "cleanup" EXIT 47 | mount --bind /proc xenial/proc 48 | mount --bind /dev xenial/dev 49 | mount --bind /sys xenial/sys 50 | mount --bind /home xenial/home 51 | mkdir -p xenial/dev/pts 52 | mount -t devpts none xenial/dev/pts 53 | 54 | cp /etc/resolv.conf xenial/etc 55 | 56 | chroot xenial/ 57 | -------------------------------------------------------------------------------- /refresh-bits: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | #: Name of the architecture to compile for, in uname -m style. 3 | #: This is mapped to various GOARCH values later in the script. 4 | #: If this is empty then architecture is probed, taking devtools_host into 5 | #: account. 6 | devtools_arch= 7 | 8 | #: Hostname to connect to if the target device is not local. 9 | #: This can be one of the snappy-* special-cased values (there's an expectation 10 | #: that appropriate pre-made ssh config is available) or any valid hostname. 11 | devtools_host= 12 | 13 | #: SSH options to use. 14 | #: Those option are optimized for non-interactive key authentication. 15 | devtools_ssh_opts="-o BatchMode=yes" 16 | devtools_ssh_opts="$devtools_ssh_opts -o UserKnownHostsFile=/dev/null" 17 | devtools_ssh_opts="$devtools_ssh_opts -o CheckHostIP=no" 18 | devtools_ssh_opts="$devtools_ssh_opts -o StrictHostKeyChecking=no" 19 | devtools_ssh_opts="$devtools_ssh_opts -o LogLevel=ERROR" 20 | devtools_ssh_opts="$devtools_ssh_opts -o IdentityFile=~/.ssh/id_rsa" 21 | 22 | #: Boot and use a local virtual machine 23 | #: no: no, ssh to a remote box or use this machine right here 24 | #: yes: yes, boot a devtools_vm with run-devel-devtools_vm 25 | devtools_vm=no 26 | 27 | #: List of commands to execute (separated by spaces). 28 | #: The commands are one of: 29 | #: - snap build snap (command line user interface) 30 | #: - snapd build snapd (snap daemon) 31 | #: ... 32 | devtools_cmds="" 33 | 34 | #: Option passed to systemd-activate. 35 | #: This is only used to pass environment required to use the staging server. 36 | devtools_systemd_activate_opts="" 37 | 38 | #: Option pass to the go build command. 39 | #; Used to enable using test keys against the staging store. 40 | devtools_go_build_tags="" 41 | 42 | #: Prefix of all the locally compiled executables. 43 | #: This is done so that snap/snapd don't clash with any directories. 44 | #: It also helps to identify devtools if people report odd bugs. 45 | CMD_PREFIX=devtools. 46 | 47 | #: Just for inspection 48 | devtools_version=2.0 49 | 50 | show_help() { 51 | echo "Usage: refresh-bits [OPTIONS] COMMAND..." 52 | echo 53 | echo "By default everything is done locally." 54 | echo "You can use --vm or --host to change that." 55 | echo 56 | echo "Spin up an ephemeral virtual machine:" 57 | echo " --vm=pc Modern Intel/AMD Computer (64 bit)" 58 | echo " --vm=i386 Legacy Intel/AMD Computer (32 bit)" 59 | echo 60 | echo "Use a remote machine:" 61 | echo " --host=HOST Connect to the given host" 62 | echo 63 | echo "Commands:" 64 | echo " snap Compile and copy 'snap'" 65 | echo " snap-exec Compile and copy 'snap-exec'" 66 | echo " snapd Compile and copy 'snapd'" 67 | echo " setup Stop 'snapd' running on the machine" 68 | echo " restore Restore regular snapd running on the machine" 69 | echo " inspect Check the status of snapd on the target machine" 70 | echo " use-staging Use staging server when talking to Ubuntu store" 71 | echo " run-snapd Run copied 'snapd' (blocking)" 72 | echo 73 | echo "NOTE: The following options require particular SSH config (see README.md)" 74 | echo 75 | echo "NOTE: Typical workflow looks like this:" 76 | echo " console 1: use $EDITOR to hack on the code" 77 | echo " console 2: run unit tests in a loop with entr(1)" 78 | echo " console 3: run ./refresh-bits snap snapd setup run-snapd restore" 79 | echo " console 4: use ssh to login to the target machine" 80 | echo " console 5: (optionally) run run-devel-vm" 81 | echo 82 | echo "Move from console 1 through 2, 3 to 4 to experiment with snap and snapd." 83 | echo "In console 3 you can see diagnostic messages from snapd." 84 | echo 85 | echo "Good luck, happy hacking!" 86 | } 87 | 88 | # Quickly show help if invoked without any arguments. 89 | if [ "$1" = "" ]; then 90 | show_help 91 | exit 92 | fi 93 | 94 | 95 | # Parse commands and store everything. No actions are taken yet. 96 | while [ "$1" != '' ]; do 97 | case "$1" in 98 | --help) 99 | show_help 100 | exit 101 | ;; 102 | --version) 103 | echo "devtools refresh-bits version $devtools_version" 104 | exit 105 | ;; 106 | --vm=*) 107 | case "$(echo "$1" | cut -d= -f 2)" in 108 | pc) 109 | devtools_arch=x86_64 110 | ;; 111 | i386) 112 | devtools_arch=i386 113 | ;; 114 | *) 115 | echo "Unsupported virtual machine target" 116 | exit 1 117 | ;; 118 | esac 119 | devtools_vm=yes 120 | devtools_host=localhost 121 | devtools_ssh_opts="$devtools_ssh_opts -o Port=8022" 122 | shift 123 | ;; 124 | --host=*) 125 | devtools_host="$(echo "$1" | cut -d = -f 2)" 126 | shift 127 | ;; 128 | snap|snap-exec|snapd|setup|restore|inspect|run-snapd|use-staging) 129 | devtools_cmds="$devtools_cmds $1" 130 | shift 131 | ;; 132 | *) 133 | echo "Unknown command: $1" 134 | exit 1 135 | ;; 136 | esac 137 | done 138 | 139 | check_connectivity() { 140 | # If we are operating on a remote machine check if we can connect 141 | if [ -n "$devtools_host" ]; then 142 | echo "Checking SSH connectivity..." 143 | ssh $devtools_ssh_opts "$devtools_host" true 144 | if [ "$?" -ne 0 ]; then 145 | echo "Cannot connect to the selected remote device: $devtools_host" 146 | echo 147 | if [ "$devtools_vm" = yes ]; then 148 | echo "You need to start the VM manually with:" 149 | echo " ./run-devel-vm" 150 | echo "You will also have to ensure appropriate SSH config is in place" 151 | else 152 | echo "Please ensure that the machine is up and running and that your credentials are okay." 153 | fi 154 | exit 1 155 | fi 156 | fi 157 | } 158 | 159 | probe_architecture() { 160 | # If the architecture is not know then probe it now. 161 | if [ -z "$devtools_arch" ]; then 162 | if [ -n "$devtools_host" ]; then 163 | echo "Checking architecture of the target device..." 164 | devtools_arch="$(ssh $devtools_ssh_opts "$devtools_host" uname -m)" 165 | else 166 | devtools_arch="$(uname -m)" 167 | fi 168 | fi 169 | } 170 | 171 | 172 | setup_goarch() { 173 | # Do simple sanity checking on the selected architecture 174 | case "$devtools_arch" in 175 | x86_64) 176 | export GOARCH=amd64 177 | ;; 178 | i686) 179 | export GOARCH=i386 180 | ;; 181 | armv6l) 182 | echo "Unsupported architecture: $devtools_arch" 183 | echo 184 | echo "This architecture is not supported by snapd or by the snappy ecosystem." 185 | echo "Please use a modern (ARMv7 or newer) device such as the Raspberry PI 2." 186 | exit 1 187 | ;; 188 | armv7l) 189 | export GOARCH=arm 190 | export GOARM=7 191 | export CGO_ENABLED=1 192 | export CC=arm-linux-gnueabihf-gcc 193 | ;; 194 | aarch64) 195 | export GOARCH=arm64 196 | export CGO_ENABLED=1 197 | export CC=aarch64-linux-gnu-gcc 198 | ;; 199 | *) 200 | echo "Unsupported architecture ($devtools_arch). Please patch this script" 201 | exit 1 202 | ;; 203 | esac 204 | } 205 | 206 | 207 | show_summary() { 208 | # Print a quick summary to let the developer know what's going on 209 | echo "== Summary ==" 210 | case "$devtools_arch" in 211 | *) 212 | if [ "$devtools_arch" != "$(uname -m)" ]; then 213 | echo " - cross-compile binaries for $devtools_arch" 214 | else 215 | echo " - compile binaries for $devtools_arch" 216 | fi 217 | ;; 218 | esac 219 | case "$devtools_vm" in 220 | yes) 221 | echo " - use an ephemeral virtual machine (using run-devel-vm)" 222 | ;; 223 | no) 224 | case "$devtools_host" in 225 | '') 226 | echo " - run everything locally" 227 | ;; 228 | *) 229 | echo " - ssh to '$devtools_host' and run remotely" 230 | ;; 231 | esac 232 | ;; 233 | esac 234 | } 235 | 236 | 237 | run_on_target() { 238 | if [ -n "$devtools_host" ]; then 239 | ssh $devtools_ssh_opts "$devtools_host" "$@" 240 | else 241 | "$@" 242 | fi 243 | } 244 | 245 | 246 | run_commands() { 247 | echo "== Executing Commands ==" 248 | while [ -n "$1" ]; do 249 | case "$1" in 250 | snap|snap-exec|snapd) 251 | echo " - building $1" 252 | go build $devtools_go_build_tags -o "$1.$GOARCH" "github.com/snapcore/snapd/cmd/$1" || exit 1 253 | if [ -n "$devtools_host" ]; then 254 | echo "Copying $1 to target device..." 255 | scp $devtools_ssh_opts "$1.$GOARCH" "$devtools_host:${CMD_PREFIX}$1" || exit 1 256 | fi 257 | shift 258 | ;; 259 | setup) 260 | echo " - stopping existing snapd..." 261 | run_on_target sudo systemctl stop snapd.socket 262 | run_on_target sudo systemctl stop snapd.service 263 | run_on_target sudo systemctl disable snapd.socket 264 | run_on_target sudo systemctl disable snapd.service 265 | shift 266 | ;; 267 | inspect) 268 | echo " - inspecting state (visually)" 269 | run_on_target systemctl status --lines=0 snapd.socket || : 270 | run_on_target systemctl status --lines=0 snapd.service || : 271 | shift 272 | ;; 273 | restore) 274 | echo " - restarting regular snapd..." 275 | run_on_target sudo systemctl enable snapd.service 276 | run_on_target sudo systemctl enable snapd.socket 277 | run_on_target sudo systemctl start snapd.socket 278 | run_on_target sudo systemctl start snapd.service 279 | shift 280 | ;; 281 | use-staging) 282 | echo " - switched to staging server" 283 | devtools_systemd_activate_opts="--setenv=SNAPPY_USE_STAGING_STORE=1" 284 | devtools_go_build_tags="-tags withtestkeys" 285 | shift 286 | ;; 287 | run-snapd) 288 | echo " - running snapd" 289 | echo " NOTE: this is a blocking operation." 290 | echo " Use ctrl-C to stop snapd and process remaining commands" 291 | echo 292 | trap 'printf "\n - interrupted!\n"' INT 293 | if [ -n "$devtools_host" ]; then 294 | echo " Use 'sudo ./${CMD_PREFIX}snap' on another console to talk to this snapd" 295 | ( sleep 3s && run_on_target sudo chmod 666 /run/snapd*.socket ) & 296 | run_on_target sudo -H $devtools_systemd_activate $devtools_systemd_activate_opts -l /run/snapd.socket -l /run/snapd-snap.socket ./${CMD_PREFIX}snapd 297 | run_on_target sudo pkill -f ${CMD_PREFIX}snapd 298 | else 299 | echo " Use 'sudo ./snap.$GOARCH' on another console to talk to this snapd" 300 | ( sleep 3s && sudo chmod 666 /run/snapd*.socket ) & 301 | sudo -H $devtools_systemd_activate $devtools_systemd_activate_opts -l /run/snapd.socket -l /run/snapd-snap.socket ./snapd.${GOARCH} 302 | fi 303 | trap - INT 304 | shift 305 | ;; 306 | esac 307 | done 308 | echo "== All commands processed ==" 309 | } 310 | 311 | # Find systemd-activate 312 | cmd1="find /lib/systemd -name systemd-activate" 313 | cmd2="find /usr/lib/systemd -name systemd-activate" 314 | cmd3="which systemd-socket-activate" 315 | 316 | i=1 317 | while [ $i -le 3 ]; do 318 | devtools_systemd_activate=$(run_on_target $(eval echo -n \${cmd${i}})) 319 | if [ -n "$devtools_systemd_activate" ]; then 320 | break 321 | fi 322 | i=$((i+1)) 323 | done 324 | 325 | if [ -z "$devtools_systemd_activate" ]; then 326 | echo "NOTE: The target doesn't seem to have systemd installed." 327 | echo "Currently snapd requires systemd (though we are working to remove" 328 | echo "this requirement) and devtools is no different." 329 | echo "Please work on supporting your init system by sending pull requests" 330 | echo "or opening isssues on github.com/zyga/devtools" 331 | exit 1 332 | fi 333 | 334 | check_connectivity 335 | probe_architecture 336 | setup_goarch 337 | show_summary 338 | run_commands $devtools_cmds 339 | -------------------------------------------------------------------------------- /reset-state: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if [ ! -e /var/lib/dpkg/status ]; then 3 | echo "This script only works on Ubuntu Classic" 4 | exit 1 5 | fi 6 | 7 | if [ "$(id -u)" != 0 ]; then 8 | echo "This script needs to be run as root" 9 | exit 1 10 | fi 11 | 12 | echo "This script will permanently destroy and reset all state in snapd" 13 | echo "You will loose all of your installed snaps" 14 | echo 15 | echo "Type: DESTROY to remove all of your snap state" 16 | echo 17 | read consent 18 | 19 | if [ "$consent" != "DESTROY" ]; then 20 | echo "No consent, aborting" 21 | exit 0 22 | fi 23 | echo 24 | echo "ABOUT TO DESTROY ALL OF STATE OF SNAPD" 25 | echo 26 | echo "Interrupt the script in 10 seconds to abort" 27 | sleep 10 || exit 28 | echo 29 | echo "DESTROYING ALL STATE OF SNAPD" 30 | 31 | if systemctl is-active --quiet snapd.service snapd.socket; then 32 | snapd_was_active=yes 33 | echo 34 | echo "Stoping snapd..." 35 | echo 36 | ( 37 | set -x 38 | systemctl stop snapd.socket snapd.service 39 | ) 40 | else 41 | echo "Skipping stopping snapd as systemctl reports it's inactive." 42 | fi 43 | 44 | echo 45 | echo "Unmounting all snaps..." 46 | echo 47 | ( 48 | set -x 49 | umount /var/lib/snapd/snaps/*.snap 50 | ) 51 | 52 | echo 53 | echo "Removing all support files and state..." 54 | echo 55 | ( 56 | set -x 57 | rm -rvf /var/lib/snapd/* 58 | ) 59 | 60 | echo 61 | echo "Removing generated systemd units..." 62 | echo 63 | ( 64 | set -x 65 | rm -vf /etc/systemd/system/snap-*.mount 66 | rm -vf /etc/systemd/system/snap-*.service 67 | rm -vf /etc/systemd/system/multi-user.target.wants/snap-*.mount 68 | ) 69 | 70 | echo 71 | echo "Removing generated executable wrappers..." 72 | echo 73 | ( 74 | set -x 75 | rm -vrf /snap/* 76 | ) 77 | 78 | if [ "$snapd_was_active" = "yes" ]; then 79 | echo 80 | echo "Starting snapd" 81 | ( 82 | set -x 83 | systemctl start snapd.socket 84 | ) 85 | fi 86 | -------------------------------------------------------------------------------- /run-devel-vm: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | version="0.2" 4 | visual=no 5 | # Handle command line arguments 6 | 7 | while [ -n "$1" ]; do 8 | case "$1" in 9 | --visual) 10 | visual=yes 11 | shift 12 | ;; 13 | --help|-h) 14 | echo "Usage: run-devel-vm [device name]" 15 | exit 0 16 | ;; 17 | --version) 18 | echo "run-devel-vm, version $version" 19 | exit 0 20 | ;; 21 | *) 22 | # Perhaps it is a device name? 23 | case $1 in 24 | pc|i386) 25 | device="$1" 26 | shift 27 | ;; 28 | pi2|bbb|dragon) 29 | echo "Running this device as a VM is not supported." 1>&2 30 | exit 1 31 | ;; 32 | *) 33 | echo "Unrecognized argument: $1" 1>&2 34 | exit 1 35 | ;; 36 | esac 37 | ;; 38 | esac 39 | done 40 | 41 | # Interactively ask about the device if necessary. 42 | 43 | while [ -z "$device" ]; do 44 | echo "Which device do you have?" 45 | echo 46 | echo "Supported guest (virtualized) devices:" 47 | echo " pc: Modern Intel/AMD Computer (64 bit)" 48 | echo " i386: Legacy Intel/AMD Computer (32 bit)" 49 | echo 50 | echo -n "device> " 51 | read device 52 | case "$device" in 53 | pc|i386) 54 | ;; 55 | pi2|bbb|dragon) 56 | device="" 57 | echo "Running this device as a VM is not supported." 58 | ;; 59 | *) 60 | echo "Unrecognized device name: $device" 61 | device="" 62 | ;; 63 | esac 64 | done 65 | 66 | # Build an image if necessary 67 | 68 | if [ ! -e $device-devel.img ]; then 69 | sudo ./ubuntu-image --developer-mode $device || exit $? 70 | fi 71 | 72 | # Find out which qemu executable to use 73 | 74 | case $device in 75 | pc) 76 | qemu="qemu-system-x86_64" 77 | ;; 78 | i386) 79 | qemu="qemu-system-i386" 80 | ;; 81 | esac 82 | 83 | qemu_options="-m 512 -snapshot -redir tcp:8022::22" 84 | case $visual in 85 | no) 86 | qemu_options="$qemu_options -nographic" 87 | ;; 88 | esac 89 | 90 | # Run qemu 91 | exec sudo "$qemu" $qemu_options "$device-devel.img" 92 | -------------------------------------------------------------------------------- /ubuntu-image: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | version="0.11" 4 | 5 | show_device_names() { 6 | echo "Devices supported by Canonical (official)" 7 | echo " pc: Modern Intel/AMD Computer (64 bit)" 8 | echo " i386: Legacy Intel/AMD Computer (32 bit)" 9 | echo " pi2: Raspberry Pi 2" 10 | echo " dragon: 410c DragonBoard" 11 | echo 12 | echo "Community devices" 13 | echo " bbb: BeagleBone Black" 14 | } 15 | 16 | # need sudo to check if we're in an LXC container 17 | if [ $(id -u) -ne "0" ]; then 18 | echo "Please run me with sudo" 19 | exit 20 | fi 21 | 22 | if grep -qa container=lxc /proc/1/environ; then 23 | echo "You're in a container, refusing to run." 24 | exit 25 | fi 26 | 27 | # Handle command line arguments 28 | 29 | while [ -n "$1" ]; do 30 | case "$1" in 31 | --help|-h) 32 | echo "Usage: ubuntu-image [--[no-]developer-mode] [device-name|?]" 33 | exit 0 34 | ;; 35 | --version) 36 | echo "ubuntu-image, version $version" 37 | exit 0 38 | ;; 39 | --developer-mode) 40 | image_kind=devel 41 | shift 42 | ;; 43 | --no-developer-mode) 44 | image_kind=vanilla 45 | shift 46 | ;; 47 | '?') 48 | echo "Recognized device names" 49 | echo 50 | show_device_names 51 | exit 52 | ;; 53 | *) 54 | # Perhaps it is a device name? 55 | case $1 in 56 | pc|i386|pi2|dragon|bbb) 57 | device="$1" 58 | shift 59 | ;; 60 | *) 61 | echo "Unrecognized argument: $1" 1>&2 62 | exit 1 63 | ;; 64 | esac 65 | ;; 66 | esac 67 | done 68 | 69 | # Add a notice about 16 series being under development 70 | echo "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" 71 | echo "X NOTE: Ubuntu 16 series is still under development! X" 72 | echo "X The exact layout of the kernel and gadget snaps will likely change. X" 73 | echo "X You may have to re-flash your device to receive further upgrades. X" 74 | echo "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" 75 | 76 | sleep 5s 77 | 78 | # Interactively ask about the device if necessary. 79 | 80 | while [ -z "$device" ]; do 81 | echo "Which device do you have?" 82 | echo 83 | show_device_names 84 | echo 85 | echo -n "device> " 86 | read device 87 | case "$device" in 88 | pc|i386|pi2|dragon|bbb) 89 | ;; 90 | *) 91 | echo "Unrecognized device name: $device" 92 | device="" 93 | ;; 94 | esac 95 | done 96 | 97 | # Interactively ask if developer mode should be enabled. 98 | 99 | while [ -z "$image_kind" ]; do 100 | echo "What kind of image do you want to build?" 101 | echo 102 | echo "devel: Developer image that contains your public SSH key" 103 | echo "vanilla: Pristine image intended for sharing or installation" 104 | echo 105 | echo -n "image kind> " 106 | read image_kind 107 | case "$image_kind" in 108 | devel) 109 | image_kind=devel 110 | ;; 111 | vanilla) 112 | image_kind=vanilla 113 | ;; 114 | *) 115 | echo "Unrecognized image kind: $image_kind" 116 | image_kind= 117 | ;; 118 | esac 119 | done 120 | 121 | # Re-affirm the user as to which device is selected 122 | 123 | echo "Selected device: $device" 124 | 125 | # Pick the right values for ubuntu-device-flash 126 | 127 | channel=edge 128 | os=ubuntu-core 129 | gadget_hash= 130 | gadget_url= 131 | kernel_hash= 132 | kernel_url= 133 | os_hash= 134 | os_url= 135 | udf_hash=a8acd7b871cb05d14a2e6e9ad780e6699225884e1b9536d2fa290164794d31b6050d1b4fc468a3d3acef5066e1e3f0eebc3359cc7e6c207d758edd1789c54638 136 | udf_url=https://people.canonical.com/~mvo/all-snaps/ubuntu-device-flash 137 | case $device in 138 | pc) 139 | kernel=canonical-pc-linux 140 | gadget=canonical-pc 141 | ;; 142 | i386) 143 | kernel=canonical-pc-linux 144 | gadget=canonical-i386 145 | ;; 146 | pi2) 147 | kernel=canonical-pi2-linux 148 | gadget=canonical-pi2 149 | ;; 150 | bbb) 151 | kernel=linux-armhf 152 | gadget=beagleblack 153 | ;; 154 | dragon) 155 | kernel=canonical-snapdragon-linux 156 | gadget=canonical-dragon 157 | ;; 158 | *) 159 | echo "BUG: no information how to build an image for device: $device" 160 | exit 2 161 | ;; 162 | esac 163 | 164 | cache_dir="${XDG_CACHE_HOME:-$HOME/.cache}/ubuntu-image" 165 | 166 | download() { 167 | blob_url="$1" 168 | blob_hash="$2" 169 | msg="$3" 170 | if [ -f "$cache_dir/blob.$blob_hash" ]; then 171 | cached_blob_hash=$(sha512sum < "$cache_dir/blob.$blob_hash" | cut -f 1 -d ' ') 172 | if [ "$cached_blob_hash" != "$blob_hash" ]; then 173 | echo "Removing corrupted copy of $(basename "$blob_url")" 174 | rm -f "$cache_dir/blob.$blob_hash" 175 | else 176 | return 177 | fi 178 | fi 179 | if [ -z "$msg" ]; then 180 | echo "Downloading $blob_url..." 181 | else 182 | echo "$msg" 183 | fi 184 | blob_download_fname=$(tempfile --prefix=blob-) 185 | trap "rm -f $blob_download_fname" EXIT 186 | if ! wget --quiet --user-agent="ubuntu-image/$version" --output-document="$blob_download_fname" "$blob_url"; then 187 | echo "Failed to download $blob_url" 188 | exit 1 189 | fi 190 | blob_download_hash=$(sha512sum < "$blob_download_fname" | cut -f 1 -d ' ') 191 | if [ "$blob_download_hash" != "$blob_hash" ]; then 192 | echo "Failed to verify integrity of $blob_url" 193 | exit 1 194 | fi 195 | mkdir -p "$cache_dir" 196 | mv --no-clobber "$blob_download_fname" "$cache_dir/blob.$blob_hash" 197 | } 198 | 199 | # Download and verify integrity of ubuntu-device-flash 200 | 201 | if [ -n "$udf_url" ]; then 202 | download "$udf_url" "$udf_hash" "Downloading ubuntu-device-flash..." 203 | udf="$cache_dir/blob.$udf_hash" 204 | chmod +x "$udf" 205 | fi 206 | 207 | # Download snaps that are not published in the store 208 | 209 | if [ -n "$os_url" ]; then 210 | download "$os_url" "$os_hash" "Downloading OS snap..." 211 | os="$cache_dir/blob.$os_hash" 212 | fi 213 | if [ -n "$kernel_url" ]; then 214 | download "$kernel_url" "$kernel_hash" "Downloading kernel snap..." 215 | kernel="$cache_dir/blob.$kernel_hash" 216 | fi 217 | if [ -n "$gadget_url" ]; then 218 | download "$gadget_url" "$gadget_hash" "Downloading gadget snap..." 219 | gadget="$cache_dir/blob.$gadget_hash" 220 | fi 221 | 222 | test -z "$os" && echo "BUG: no OS snap for device: $device" && exit 2 223 | test -z "$kernel" && echo "BUG: no kernel snap for device: $device" && exit 2 224 | test -z "$gadget" && echo "BUG: no gadget snap for device: $device" && exit 2 225 | 226 | # Check if required tools are present 227 | 228 | test -z $(which kpartx) && ( 229 | echo "Installing required dependency: kpartx" 230 | sudo apt-get install kpartx --yes 231 | ) 232 | 233 | # Run ubuntu device flash 234 | 235 | echo "Building image..." 236 | 237 | case "$image_kind" in 238 | vanilla) 239 | exec sudo "$udf" core 16 \ 240 | --channel "$channel" --kernel "$kernel" --os "$os" --gadget "$gadget" \ 241 | -o "$device.img" 242 | ;; 243 | devel) 244 | exec sudo "$udf" core 16 \ 245 | --channel "$channel" --kernel "$kernel" --os "$os" --gadget "$gadget" \ 246 | --developer-mode -o "${device}-devel.img" 247 | ;; 248 | *) 249 | echo "BUG: no information how to build image kind: $image_kind" && exit 2 250 | ;; 251 | esac 252 | --------------------------------------------------------------------------------