github.com/stackdocker/rkt@v0.10.1-0.20151109095037-1aa827478248/Documentation/hacking.md (about) 1 # Hacking Guide 2 3 ## Overview 4 5 This guide contains instructions for those looking to hack on rkt. 6 For more information on the rkt internals, see the [`devel`](devel/) documentation. 7 8 ## Building rkt 9 10 rkt should be able to be built on any modern Linux system. 11 For the most part the codebase is self-contained (e.g. all dependencies are vendored), but assembly of the stage1 requires some other tools to be installed on the system. 12 13 ### Build-time requirements 14 15 * Linux 3.8+ 16 * make 17 * gcc 18 * glibc development and static pieces (on Fedora/RHEL/Centos: glibc-devel and glibc-static packages, on Debian/Ubuntu libc6-dev package) 19 * cpio 20 * squashfs-tools 21 * realpath 22 * gpg 23 * autoconf 24 * Go 1.4+ 25 26 Once the requirements have been met you can build rkt by running the following commands: 27 28 ``` 29 git clone https://github.com/coreos/rkt.git 30 cd rkt 31 ./autogen.sh && ./configure && make 32 ``` 33 34 Build verbosity can be controlled with the V variable. 35 Set V to 0 to have a silent build. 36 Set V to either 1 or 2 to get short messages about what is being done (level 2 prints more of them). 37 Set V to 3 to get raw output. 38 Instead of a number, english words can be used. 39 `quiet` or `silent` for level 0, `info` for level 1, `all` for level 2 and `raw` for level 3. Example: 40 41 `make V=raw` 42 43 ### Run-time requirements 44 45 rkt is statically linked and does not require any dynamic libraries to be installed. However, it requires the following kernel features: 46 47 * `CONFIG_CGROUPS` 48 * `CONFIG_NAMESPACES` 49 * `CONFIG_UTS_NS` 50 * `CONFIG_IPC_NS` 51 * `CONFIG_PID_NS` 52 * `CONFIG_NET_NS` 53 54 Additionally, the following features are nice to have: 55 56 * `CONFIG_OVERLAY_FS` (to prepare the rootfs without tar) 57 58 ### With Docker 59 60 Alternatively, you can build rkt in a Docker container with the following command. 61 Replace $SRC with the absolute path to your rkt source code: 62 63 ``` 64 # docker run -v $SRC:/opt/rkt -i -t golang:1.4 /bin/bash -c "apt-get update && apt-get install -y coreutils cpio squashfs-tools realpath autoconf file && cd /opt/rkt && go get github.com/appc/spec/... && ./autogen.sh && ./configure && make" 65 ``` 66 67 ### Building systemd in stage1 from the sources 68 69 By default, rkt gets systemd from a CoreOS image to generate stage1. But it's also possible to build systemd from the sources. 70 After running `./autogen.sh` you can select the following options: 71 72 * `./configure --with-stage1-flavors=coreos,src,host,kvm`: choose which flavors to build (default: 'coreos,kvm') (kvm also uses systemd from CoreOS, the difference is in the execution engine, see next section) 73 * `./configure --with-stage1-default-flavor=coreos|src|host|kvm`: choose which built flavor should be the default (default: first from the flavors list) 74 * `./configure --with-stage1-systemd-version=version`: if 'src' flavor is built, choose the systemd branch or tag to build (default: 'v222') 75 * `./configure --with-stage1-systemd-src=git-path`: if 'src' flavor is built, systemd git repository's address (default: 'https://github.com/systemd/systemd.git') 76 77 Example: 78 79 ``` 80 ./autogen.sh && ./configure --with-stage1-flavors=src --with-stage1-systemd-version=master --with-stage1-systemd-src=$HOME/src/systemd && make 81 ``` 82 83 ### Building stage1 with kvm as execution engine 84 85 The stage1 kvm image is based on CoreOS, but with additional components for running containers on top of a hypervisor. 86 87 To build, use `--with-stage1-flavors=kvm` flag in `./configure` 88 89 This will generate stage1 with embedded kernel and kvmtool to start pod in virtual machine. 90 91 Additional build dependencies for the stage1 kvm follow. If building with docker, these must be added to the `apt-get install` command. 92 93 * wget 94 * xz-utils 95 * patch 96 * bc 97 98 ### Alternative stage1 paths 99 100 rkt is designed and intended to be modular, using a [staged architecture](devel/architecture.md). 101 102 `rkt run` determines the stage1 image it should use via its `-stage1-image` flag. 103 By default, if this flag is unset at runtime, rkt will default to the configure-time settings. It usually means that rkt will look for a file called `stage1-<default flavor>.aci` that is in the same directory as the rkt binary itself. 104 105 However, a default value can be set for this parameter at build time by setting the option `--with-stage1-default-location` when invoking `./configure` 106 This is useful for those packaging rkt for distribution who will provide the stage1 in a fixed/known location. 107 108 The option should be set to the fully qualified path at which rkt can find the stage1 image - for example: 109 110 ``` 111 ./autogen.sh && ./configure --with-stage1-default-location=/usr/lib/rkt/stage1.aci && make 112 ``` 113 114 rkt will then use this environment variable to set the default value for the `stage1-image` flag. 115 116 117 ## Managing Dependencies 118 119 rkt uses [`godep`](https://github.com/tools/godep) to manage third-party dependencies. 120 The build process is crafted to make this transparent to most users (i.e. if you're just building rkt from source, or modifying any of the codebase without changing dependencies, you should have no need to interact with godep). 121 But occasionally the need arises to either a) add a new dependency or b) update/remove an existing dependency. 122 At this point, the ramblings below from an experienced Godep victim^Wenthusiast might prove of use... 123 124 ### Update godep 125 126 Step zero is generally to ensure you have the **latest version** of `godep` available in your `PATH`. 127 128 ### Having the right directory layout (i.e. `GOPATH`) 129 130 To work with `godep`, you'll need to have the repository (i.e. `github.com/coreos/rkt`) checked out in a valid `GOPATH`. 131 If you use the [standard Go workflow](https://golang.org/doc/code.html#Organization), with every package in its proper place in a workspace, this should be no problem. 132 As an example, if one was obtaining the repository for the first time, one would do the following: 133 134 ``` 135 $ export GOPATH=/tmp/foo # or any directory you please 136 $ go get -d github.com/coreos/rkt/... # or 'git clone https://github.com/coreos/rkt $GOPATH/src/github.com/coreos/rkt' 137 $ cd $GOPATH/src/github.com/coreos/rkt 138 ``` 139 140 If, however, you instead prefer to manage your source code in directories like `~/src/rkt`, there's a problem: `godep` doesn't like symbolic links (which is what the rkt build process uses by default to create a self-contained GOPATH). 141 Hence, you'll need to work around this with bind mounts, with something like the following: 142 143 ``` 144 $ export GOPATH=/tmp/foo # or any directory you please 145 $ mkdir -p $GOPATH/src/github.com/coreos/rkt 146 # mount --bind ~/src/rkt $GOPATH/src/github.com/coreos/rkt 147 $ cd $GOPATH/src/github.com/coreos/rkt 148 ``` 149 150 One benefit of this approach over the single-workspace workflow is that checking out different versions of dependencies in the `GOPATH` (as we are about to do) is guarnteed to not affect any other packages in the `GOPATH`. 151 (Using [gvm](https://github.com/moovweb/gvm) or other such tomfoolery to manage `GOPATH`s is an exercise left for the reader.) 152 153 ### Restoring the current state of dependencies 154 155 Now that we have a functional `GOPATH`, use `godep` to restore the full set of vendored dependencies to their correct versions. 156 (What this command does is essentially just loop over the set of dependencies codified in `Godeps/Godeps.json`, using `go get` to retrieve and then `git checkout` (or equivalent) to set each to their correct revision.) 157 158 ``` 159 $ godep restore # might take a while if it's the first time... 160 ``` 161 162 At this stage, your path forks, depending on what exactly you want to do: add, update or remove a dependency. 163 But in _all three cases_, the procedure finishes with the [same save command](#saving-the-set-of-dependencies). 164 165 #### Add a new dependency 166 167 In this case you'll first need to retrieve the dependency you're working with into `GOPATH`. 168 As a simple example, assuming we're adding `github.com/fizz/buzz`: 169 170 ``` 171 $ go get -d github.com/fizz/buzz 172 ``` 173 174 Then add your new dependency into `godep`'s purview by simply importing the standard package name in one of your sources: 175 176 ``` 177 $ vim $GOPATH/src/github.com/coreos/rkt/some/file.go 178 ... 179 import "github.com/fizz/buzz" 180 ... 181 ``` 182 183 Now, GOTO [saving](#saving-the-set-of-dependencies) 184 185 #### Update an existing dependency 186 187 In this case, assuming we're updating `github.com/foo/bar`: 188 189 ``` 190 $ cd $GOPATH/src/github.com/foo/bar 191 $ git pull # or 'go get -d -u github.com/foo/bar/...' 192 $ git checkout $DESIRED_REVISION 193 $ cd $GOPATH/src/github.com/coreos/rkt 194 $ godep update github.com/foo/bar/... 195 ``` 196 197 Now, GOTO [saving](#saving-the-set-of-dependencies) 198 199 #### Removing an existing dependency 200 201 This is the simplest case of all: simply remove all references to a dependency from the source files. 202 203 Now, GOTO [saving](#saving-the-set-of-dependencies) 204 205 ### Saving the set of dependencies 206 207 Finally, here we are, the magic command, the holy grail, the ultimate conclusion of all `godep` operations. 208 Provided you have followed the preceding instructions, regardless of whether you are adding/removing/modifying dependencies, this command will cast the necessary spells to solve all of your dependency worries: 209 210 ``` 211 $ godep save -r ./... 212 ``` 213 214 ## Finishing up 215 216 At this point, you should be good to PR. 217 As well as a simple sanity check that the code actually builds and tests pass, here are some things to look out for: 218 - `git status Godeps/` should show only a minimal and relevant change (i.e. only the dependencies you actually intended to touch). 219 - `git diff Godeps/` should be free of any changes to import paths within the vendored dependencies 220 - `git diff` should show _all_ third-party import paths prefixed with `Godeps/_workspace` 221 222 If something looks awry, restart, pray to your preferred deity, and try again.