1*105f6285SAndroid Build Coastguard Worker# hacksaw 2*105f6285SAndroid Build Coastguard Worker 3*105f6285SAndroid Build Coastguard Worker**HACK** in a **S**peedy **A**ccess **W**orkspace 4*105f6285SAndroid Build Coastguard Worker 5*105f6285SAndroid Build Coastguard Worker## What is Hacksaw? 6*105f6285SAndroid Build Coastguard Worker 7*105f6285SAndroid Build Coastguard WorkerIf you have a large multi-gigabyte codebase spread out through multiple git projects it can take a long time branch off a clean workspace. Hacksaw is a tool that 8*105f6285SAndroid Build Coastguard Workerlets you split off a clean workspace in seconds. It does so by only copying git projects that you 9*105f6285SAndroid Build Coastguard Workerexplicitly select to be edited. All other projects are read-only bind mounts. This lets you build without cloning the full codebase to a new location! 10*105f6285SAndroid Build Coastguard Worker 11*105f6285SAndroid Build Coastguard Worker## How much faster is it, really? 12*105f6285SAndroid Build Coastguard Worker 13*105f6285SAndroid Build Coastguard WorkerLets look at some performance numbers for creating a hacksaw workspace using as a codebase the AOSP master branch as of 2020-8-4. The machine used was a c2-standard-60 Google Cloud Platform VM with 60 vCPUs and 240 GiB of RAM. Each action was performed at least 10 times then averaged out. 14*105f6285SAndroid Build Coastguard Worker 15*105f6285SAndroid Build Coastguard Worker* Create a new Hacksaw workspace 16*105f6285SAndroid Build Coastguard Worker + Time: 0.4 sec 17*105f6285SAndroid Build Coastguard Worker + Disk usage: 7.9 MiB 18*105f6285SAndroid Build Coastguard Worker 19*105f6285SAndroid Build Coastguard Worker* Remove a Hacksaw workspace with no edits or build artifacts. 20*105f6285SAndroid Build Coastguard Worker + Time: 0.6 sec 21*105f6285SAndroid Build Coastguard Worker 22*105f6285SAndroid Build Coastguard Worker* Create a new Hacksaw workspace and edit build/make project. 23*105f6285SAndroid Build Coastguard Worker + Time: 0.6 sec 24*105f6285SAndroid Build Coastguard Worker + Disk usage: 18 MiB 25*105f6285SAndroid Build Coastguard Worker 26*105f6285SAndroid Build Coastguard Worker* Create a new Hacksaw workspace and edit frameworks/base project. 27*105f6285SAndroid Build Coastguard Worker + Time: 7.5 sec 28*105f6285SAndroid Build Coastguard Worker + Disk usage: 1.3 GiB 29*105f6285SAndroid Build Coastguard Worker 30*105f6285SAndroid Build Coastguard WorkerAs you can see, the time it takes to set up a new hacksaw workspace is proportional to 31*105f6285SAndroid Build Coastguard Workerthe git projects checked out for editing. Contrast that with how long it takes 32*105f6285SAndroid Build Coastguard Workerto create a workspace using a full repo sync with a local 33*105f6285SAndroid Build Coastguard Workermirror. 34*105f6285SAndroid Build Coastguard Worker 35*105f6285SAndroid Build Coastguard Worker* Create a new full repo workspace [using a fresh local mirror](https://source.android.com/setup/build/downloading#using-a-local-mirror) 36*105f6285SAndroid Build Coastguard Worker + Time: 12 min 32 sec 37*105f6285SAndroid Build Coastguard Worker + Disk usage: 88 GiB 38*105f6285SAndroid Build Coastguard Worker 39*105f6285SAndroid Build Coastguard Worker* Remove a full repo workspace with no build artifacts 40*105f6285SAndroid Build Coastguard Worker + Time: 28 seconds 41*105f6285SAndroid Build Coastguard Worker 42*105f6285SAndroid Build Coastguard Worker## Can you give me an example? 43*105f6285SAndroid Build Coastguard Worker 44*105f6285SAndroid Build Coastguard Worker``` 45*105f6285SAndroid Build Coastguard Worker$ mkdir ~/aosp 46*105f6285SAndroid Build Coastguard Worker$ cd ~/aosp 47*105f6285SAndroid Build Coastguard Worker$ repo init -u https://android.googlesource.com/platform/manifest 48*105f6285SAndroid Build Coastguard Worker... 49*105f6285SAndroid Build Coastguard Worker$ repo sync --quiet --current-branch --no-tags --no-clone-bundle --jobs=$(nproc) 50*105f6285SAndroid Build Coastguard Worker... 51*105f6285SAndroid Build Coastguard Worker$ hacksaw codebase add aosp ~/aosp 52*105f6285SAndroid Build Coastguard WorkerAdded codebase aosp 53*105f6285SAndroid Build Coastguard Worker$ hacksaw codebase default aosp 54*105f6285SAndroid Build Coastguard WorkerDefault codebase set to aosp 55*105f6285SAndroid Build Coastguard Worker$ hacksaw workspace new big-feature 56*105f6285SAndroid Build Coastguard WorkerComposing................................................................. 57*105f6285SAndroid Build Coastguard Worker.......................................................................... 58*105f6285SAndroid Build Coastguard Worker.......................................................................... 59*105f6285SAndroid Build Coastguard Worker.......................................................................... 60*105f6285SAndroid Build Coastguard Worker.......................................................................... 61*105f6285SAndroid Build Coastguard Worker.......................................................................... 62*105f6285SAndroid Build Coastguard Worker.......................................................................... 63*105f6285SAndroid Build Coastguard Worker.......................................................................... 64*105f6285SAndroid Build Coastguard Worker.......................................................................... 65*105f6285SAndroid Build Coastguard Worker.......................................................................... 66*105f6285SAndroid Build Coastguard Worker.......................................................................... 67*105f6285SAndroid Build Coastguard Worker........................................... 68*105f6285SAndroid Build Coastguard WorkerWorkspace composed 69*105f6285SAndroid Build Coastguard WorkerCreated big-feature at ~/hacksaw/big-feature 70*105f6285SAndroid Build Coastguard Worker$ hacksaw edit ~/hacksaw/big-feature/tools/treble 71*105f6285SAndroid Build Coastguard WorkerCreated branch big-feature on project ~/hacksaw/big-feature/tools/treble 72*105f6285SAndroid Build Coastguard Worker$ hacksaw workspace new quick-fix 73*105f6285SAndroid Build Coastguard WorkerComposing................................................................. 74*105f6285SAndroid Build Coastguard Worker.......................................................................... 75*105f6285SAndroid Build Coastguard Worker.......................................................................... 76*105f6285SAndroid Build Coastguard Worker.......................................................................... 77*105f6285SAndroid Build Coastguard Worker.......................................................................... 78*105f6285SAndroid Build Coastguard Worker.......................................................................... 79*105f6285SAndroid Build Coastguard Worker.......................................................................... 80*105f6285SAndroid Build Coastguard Worker.......................................................................... 81*105f6285SAndroid Build Coastguard Worker.......................................................................... 82*105f6285SAndroid Build Coastguard Worker.......................................................................... 83*105f6285SAndroid Build Coastguard Worker.......................................................................... 84*105f6285SAndroid Build Coastguard Worker........................................... 85*105f6285SAndroid Build Coastguard WorkerWorkspace composed 86*105f6285SAndroid Build Coastguard WorkerCreated big-feature at ~/hacksaw/quick-fix 87*105f6285SAndroid Build Coastguard Worker$ hacksaw edit ~/hacksaw/quick-fix/tools/treble 88*105f6285SAndroid Build Coastguard WorkerCreated branch quick-fix on project ~/hacksaw/quick-fix/tools/treble 89*105f6285SAndroid Build Coastguard Worker``` 90*105f6285SAndroid Build Coastguard Worker 91*105f6285SAndroid Build Coastguard Worker## How do I install it? 92*105f6285SAndroid Build Coastguard Worker 93*105f6285SAndroid Build Coastguard WorkerBuilding hacksaw requires [golang to be installed](https://golang.org/doc/install). 94*105f6285SAndroid Build Coastguard WorkerTo install the hacksaw client run the following: 95*105f6285SAndroid Build Coastguard Worker 96*105f6285SAndroid Build Coastguard Worker``` 97*105f6285SAndroid Build Coastguard Workergo get android.googlesource.com/platform/tools/treble.git/hacksaw/cmd/hacksaw 98*105f6285SAndroid Build Coastguard Worker``` 99*105f6285SAndroid Build Coastguard Worker 100*105f6285SAndroid Build Coastguard WorkerThis will install hacksaw to ~/go/bin/hacksaw. You may choose to copy that 101*105f6285SAndroid Build Coastguard Workerto a location in your path. For example: 102*105f6285SAndroid Build Coastguard Worker 103*105f6285SAndroid Build Coastguard Worker``` 104*105f6285SAndroid Build Coastguard Workersudo cp ~/go/bin/hacksaw /usr/local/bin 105*105f6285SAndroid Build Coastguard Workersudo chmod 755 /usr/local/bin/hacksaw 106*105f6285SAndroid Build Coastguard Worker``` 107*105f6285SAndroid Build Coastguard Worker 108*105f6285SAndroid Build Coastguard Worker## How do I make sure that creating a hacksaw workspace is fast? 109*105f6285SAndroid Build Coastguard Worker 110*105f6285SAndroid Build Coastguard WorkerHacksaw creates bind mounts for all git projects in a codebase. It then 111*105f6285SAndroid Build Coastguard Workercopies **everything** else. Make sure you remove all build artifacts from a 112*105f6285SAndroid Build Coastguard Workercodebase before create a workspace, otherwise it may spend a long time copying 113*105f6285SAndroid Build Coastguard Workerthem. 114*105f6285SAndroid Build Coastguard Worker 115*105f6285SAndroid Build Coastguard Worker## How do I run it with sudo? 116*105f6285SAndroid Build Coastguard Worker 117*105f6285SAndroid Build Coastguard WorkerCommands that mount and unmount will require sudo. That includes commands like 118*105f6285SAndroid Build Coastguard Worker 119*105f6285SAndroid Build Coastguard Worker* `hacksaw workspace new` 120*105f6285SAndroid Build Coastguard Worker* `hacksaw edit` 121*105f6285SAndroid Build Coastguard Worker* `hacksaw workspace remove` 122*105f6285SAndroid Build Coastguard Worker 123*105f6285SAndroid Build Coastguard WorkerOther commmands like `hacksaw workspace list` or `hacksaw add codebase` do not 124*105f6285SAndroid Build Coastguard Workermount or unmount so do not require sudo. 125*105f6285SAndroid Build Coastguard Worker 126*105f6285SAndroid Build Coastguard WorkerIf you would like to avoid using sudo you may install hacksawd as explained below. 127*105f6285SAndroid Build Coastguard Worker 128*105f6285SAndroid Build Coastguard Worker## How do I run it without sudo? 129*105f6285SAndroid Build Coastguard Worker 130*105f6285SAndroid Build Coastguard WorkerHacksawd is a privileged system daemon whose only job is to manage bind mounts. 131*105f6285SAndroid Build Coastguard WorkerThe provided install script will install to your system 132*105f6285SAndroid Build Coastguard Worker 133*105f6285SAndroid Build Coastguard Worker``` 134*105f6285SAndroid Build Coastguard Workergo get android.googlesource.com/platform/tools/treble.git/hacksaw/cmd/hacksawd 135*105f6285SAndroid Build Coastguard Workersudo cp ~/go/bin/hacksawd /usr/local/bin 136*105f6285SAndroid Build Coastguard Workersudo chmod 755 /usr/local/bin/hacksawd 137*105f6285SAndroid Build Coastguard Workersudo ~/go/src/android.googlesource.com/platform/tools/treble.git/hacksaw/scripts/install-service.sh 138*105f6285SAndroid Build Coastguard Worker``` 139*105f6285SAndroid Build Coastguard Worker 140*105f6285SAndroid Build Coastguard WorkerThe installation scripts creates a new "hacksaw" group and adds you to it. You 141*105f6285SAndroid Build Coastguard Workerwill need to log out and log back in for the group changes to take effect. After that you should be able to run any hacksaw command without sudo. 142*105f6285SAndroid Build Coastguard Worker 143*105f6285SAndroid Build Coastguard WorkerIf you wish to uninstall the service then run: 144*105f6285SAndroid Build Coastguard Worker 145*105f6285SAndroid Build Coastguard Worker``` 146*105f6285SAndroid Build Coastguard Workersudo ~/go/src/android.googlesource.com/platform/tools/treble.git/hacksaw/scripts/uninstall-service.sh 147*105f6285SAndroid Build Coastguard Workersudo rm /usr/local/bin/hacksawd 148*105f6285SAndroid Build Coastguard Worker``` 149*105f6285SAndroid Build Coastguard Worker## How do I sync? 150*105f6285SAndroid Build Coastguard Worker 151*105f6285SAndroid Build Coastguard WorkerYou sync your codebases using `repo sync`. All updates will be propagated to workspaces. 152*105f6285SAndroid Build Coastguard WorkerExcept for projects that you are currently editing. Those will require you to `git pull` 153*105f6285SAndroid Build Coastguard Workermanually in the workspace project. 154*105f6285SAndroid Build Coastguard Worker 155*105f6285SAndroid Build Coastguard Worker## How does hacksaw work? 156*105f6285SAndroid Build Coastguard Worker 157*105f6285SAndroid Build Coastguard WorkerHacksaw uses read-only bind mounts to create project references from 158*105f6285SAndroid Build Coastguard Workera workspace to a codebase. When you mark a project for editing then 159*105f6285SAndroid Build Coastguard Workerits read-only bind mount gets replaced by a writable Git worktree. 160*105f6285SAndroid Build Coastguard Worker 161*105f6285SAndroid Build Coastguard Worker 162*105f6285SAndroid Build Coastguard Worker 163*105f6285SAndroid Build Coastguard Worker 164*105f6285SAndroid Build Coastguard Worker## What are the known issues? 165*105f6285SAndroid Build Coastguard Worker 166*105f6285SAndroid Build Coastguard Worker* Some repo commands don't work yet. Namely: `repo start` and `repo upload`. 167*105f6285SAndroid Build Coastguard Worker So at the moment you can only upload to Gerrit [using git 168*105f6285SAndroid Build Coastguard Worker push](https://gerrit-review.googlesource.com/Documentation/user-upload.html#_git_push). 169*105f6285SAndroid Build Coastguard Worker* Failing to create a workspace is not rolled back. 170*105f6285SAndroid Build Coastguard Worker* Editing nested projects is not supported yet. So if you have a git project 171*105f6285SAndroid Build Coastguard Worker that contains other git projects you will get some unexpected behaviour. 172*105f6285SAndroid Build Coastguard Worker* Git submodules are not supported yet, but the tool is designed with 173*105f6285SAndroid Build Coastguard Worker future git submodule support in mind. 174*105f6285SAndroid Build Coastguard Worker* Syncing a codebase does update the existing projects in all attached 175*105f6285SAndroid Build Coastguard Worker workspaces but it does not remove or add new projects. Perhaps there 176*105f6285SAndroid Build Coastguard Worker should be a new "workspace sync" command for that? 177*105f6285SAndroid Build Coastguard Worker 178*105f6285SAndroid Build Coastguard Worker## Where can I get more help? 179*105f6285SAndroid Build Coastguard Worker 180*105f6285SAndroid Build Coastguard WorkerYou can ask [email protected] by [joining the group](https://groups.google.com/forum/#!forum/hacksaw-users).