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.