github.com/rkt/rkt@v1.30.1-0.20200224141603-171c416fac02/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  The easiest way to build rkt is by using the coreos.com/rkt/builder ACI image. See instructions for how to use it in the README at [github.com/rkt/rkt-builder][rkt-builder].
    11  
    12  Alternatively, you should be able build rkt on any modern Linux system with [Go](https://golang.org/) (1.5+) installed.
    13  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.
    14  Please see [the list of the build-time dependencies][build-time-dependencies].
    15  Once the dependencies have been satisfied you can build rkt with a default configuration by running the following commands:
    16  
    17  ```
    18  git clone https://github.com/rkt/rkt.git
    19  cd rkt
    20  ./autogen.sh && ./configure && make
    21  ```
    22  
    23  Build verbosity can be controlled with the V variable.
    24  Set V to 0 to have a silent build.
    25  Set V to either 1 or 2 to get short messages about what is being done (level 2 prints more of them).
    26  Set V to 3 to get raw output.
    27  Instead of a number, English words can be used: `quiet` or `silent` for level 0, `info` for level 1, `all` for level 2 and `raw` for level 3.
    28  For example, `make V=raw` is equivalent to `make V=3`.
    29  
    30  To be able to run rkt, please see [the list of the run-time dependencies][run-time-dependencies].
    31  
    32  ### Building rkt with Docker
    33  
    34  Alternatively, you can build rkt in a Docker container with the following command.
    35  Replace `$SRC` with the absolute path to your rkt source code:
    36  
    37  ```
    38  # docker run -v $SRC:/opt/rkt debian:sid /bin/bash -c "cd /opt/rkt && ./scripts/install-deps-debian-sid.sh && ./autogen.sh && ./configure && make"
    39  ```
    40  
    41  ### Building systemd in stage1 from source
    42  
    43  By default, rkt gets systemd from a CoreOS Container Linux image to generate stage1.
    44  It's also possible to build systemd from source.
    45  To do this, use the following `configure` parameters after running `./autogen.sh`:
    46  
    47  - `--with-stage1-flavors`
    48  - `--with-stage1-default-flavor` (optional)
    49  - `--with-stage1-systemd-version`
    50  - `--with-stage1-systemd-revision` (optional)
    51  - `--with-stage1-systemd-src`
    52  
    53  For more details, see [configure script parameters documentation][build-configure].
    54  Example:
    55  
    56  ```
    57  ./autogen.sh && ./configure --with-stage1-flavors=src --with-stage1-systemd-version=v231 --with-stage1-systemd-revision=master --with-stage1-systemd-src=$HOME/src/systemd && make
    58  ```
    59  
    60  ### Building stage1 with kvm as execution engine
    61  
    62  The stage1 kvm image is based on Container Linux, but with additional components for running containers on top of a hypervisor.
    63  
    64  To build this stage1 image, pass `kvm` to `--with-stage1-flavors` parameter in `./configure`
    65  
    66  This will generate a stage1 with an embedded kernel and kvmtool, which launches each pod in a separate virtual machine.
    67  
    68  Additional build dependencies for the stage1 kvm follow.
    69  If building with docker, these must be added to the `apt-get install` command.
    70  
    71  * wget
    72  * xz-utils
    73  * patch
    74  * bc
    75  * libssl-dev
    76  
    77  ### Alternative stage1 paths
    78  
    79  rkt is designed and intended to be modular, using a [staged architecture][architecture].
    80  
    81  `rkt run` determines the stage1 image it should use via its `--stage1-{url,path,name,hash,from-dir}` flags.
    82  If this flag is not given to rkt, the stage1 image will default to the settings taken from the configuration.
    83  If those are unset, rkt will fall back to the settings configured when rkt was built from source.
    84  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.
    85  
    86  However, a default value can be set for this parameter at build time by setting the option `--with-stage1-default-location` when invoking `./configure`.
    87  It can be set with the `paths` kind of configuration.
    88  For more details, see [configure script parameters documentation][build-configure] and [configuration documentation][configuration].
    89  
    90  rkt expects stage1 images to be signed except in the following cases:
    91  
    92  * it is the default stage1 image and it's in the same directory as the rkt binary
    93  * `--stage1-{name,hash}` is used and the image is already in the store
    94  * `--stage1-{url,path,from-dir}` is used and the image is in the default directory configured at build time
    95  
    96  ### Updating the coreos flavor stage1
    97  
    98  Follow the instructions on [Update coreos flavor stage1][update-coreos-stage1].
    99  
   100  ## Running tests
   101  
   102  The rkt repository includes both unit and functional tests.
   103  Follow the instructions in [Manually running the tests][manual-run-tests] for details on how to run the different tests.
   104  
   105  ## Managing dependencies
   106  
   107  rkt uses [`glide`][glide] and [`glide-vc`][glide-vc] to manage third-party dependencies.
   108  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 glide).
   109  But occasionally the need arises to either a) add a new dependency or b) update/remove an existing dependency.
   110  
   111  We might want to vendor an application for several reasons:
   112  
   113  - it will be used at build-time (like actool to build stage1 images)
   114  - it will be a part of a stage1 image (like CNI plugins for networking)
   115  - it will be used in functional tests (like ACE validator)
   116  
   117  ### Update glide/glide-vc
   118  
   119  Ensure you have the **latest version** of `glide` and `glide-vc` available in your `PATH`.
   120  
   121  #### Add a new dependency
   122  
   123  Use the glide tool to add a new dependency. In order to add a dependency to a package i.e. `github.com/fizz/buzz` for version `1.2.3`, execute:
   124  ```
   125  $ glide get github.com/fizz/buzz#v1.2.3
   126  $ ./scripts/glide-update.sh
   127  ```
   128  
   129  Note that although glide does support [versions and ranges][glide-versioning] currently it is preferred to pin to concrete versions as described above.
   130  
   131  *Note*: Do *not* use `go get` and `glide update` to add new dependencies. It will cause both `glide.lock` and `glide.yaml` files to diverge.
   132  
   133  #### Update existing dependencies
   134  
   135  Once in a while new versions of dependencies are available. Entries in the `glide.yaml` file specify the target version. To update a dependency, edit the appropriate entry and specify the updated target version.
   136  
   137  *Note*: Changing specific entries in `glide.yaml` does not imply that only those will be updated. Glide will pull potential updates for all dependencies.
   138  
   139  To update a vendored dependency to a newer version, first update its target version directly in `glade.yaml`. The glide update script will then take care of pulling all dependencies and refreshing any updated ones, according to version constraints specified in the YAML manifest.
   140  
   141  *Note*: Glide will pull all dependencies from all referenced repos potentially causing a lot of network traffic.
   142  
   143  Once done editing glide.yaml, execute the glide update script:
   144  ```
   145  $ ./scripts/glide-update.sh
   146  ```
   147  
   148  #### Resolving transitive dependency conflicts
   149  
   150  Glide currently has no deterministic mechanism to resolve transitive dependency conflicts. A transitive dependency conflict exists if package `A` depends on `B`, and a package `C` also depends on `B`, but on a different version.
   151  
   152  To resolve this conflict on package `C` specify the version directly in the `glide.yaml` file as described above.
   153  
   154  #### Removing an existing dependency
   155  
   156  Execute:
   157  ```
   158  $ glide rm github.com/fizz/buzz
   159  $ ./scripts/glide-update.sh
   160  ```
   161  
   162  ## Errors & Output
   163  
   164  rkt attempts to offer consistent and structured error output. To achieve this, we use a couple helper types which we'll describe below.
   165  
   166  ### Wrapping errors
   167  
   168  rkt uses the errwrap package to structure errors. This allows us to manage how we output errors. You can wrap errors by doing the following.
   169  
   170  ```
   171  err := funcReturningSomeError()
   172  errwrap.Wrap(errors.New("My new error"), err)
   173  ```
   174  
   175  ### Logging errors
   176  
   177  For writing to output rkt uses its own log package which is essentially a wrapper around the golang log package. This is used to write to both `stderr` and `stdout`. By doing this, rkt can easily change the way it formats its output.
   178  
   179  A few new methods are added to control the output of the wrapped errors. For example, the following outputs an error to `stderr`.
   180  
   181  ```
   182  log := rktlog.Logger(os.Stderr, "rkt", debug)
   183  
   184  log.PrintE("a message to accompany the error", err)
   185  ```
   186  
   187  There are similar functions named `FatalE`, `PanicE`. All the other methods from golang's log package are available.
   188  
   189  ### Writing to stdout
   190  
   191  In order to write to `stdout`, we also use the rkt log package. If not already set up in your package, one can be created as follows.
   192  
   193  ```
   194  stdout := rktlog.Logger(os.Stdout, "", false)
   195  ```
   196  
   197  Here, the prefix is an empty string and debug is set to `false`.
   198  
   199  ## Debugging
   200  
   201  Check out the [debugging guide](devel/debugging.md) for some common techniques that can be used to debug rkt.
   202  
   203  ## Finishing Up
   204  
   205  At this point, you should be good to submit a PR.
   206  As well as a simple sanity check that the code actually builds and tests pass, here are some things to look out for:
   207  - `git status Godeps/` should show only a minimal and relevant change (i.e. only the dependencies you actually intended to touch).
   208  - `git diff Godeps/` should be free of any changes to import paths within the vendored dependencies
   209  - `git diff` should show _all_ third-party import paths prefixed with `Godeps/_workspace`
   210  
   211  If something looks awry, restart, pray to your preferred deity, and try again.
   212  
   213  
   214  [architecture]: devel/architecture.md
   215  [build-configure]: build-configure.md
   216  [build-time-dependencies]: dependencies.md#build-time-dependencies
   217  [configuration]: configuration.md
   218  [glide]: https://glide.sh
   219  [glide-vc]: https://github.com/sgotti/glide-vc
   220  [glide-versioning]: https://glide.readthedocs.io/en/latest/versions/
   221  [go]: https://golang.org/
   222  [rkt-builder]: https://github.com/rkt/rkt-builder
   223  [run-time-dependencies]: dependencies.md#run-time-dependencies
   224  [update-coreos-stage1]: devel/update-coreos-stage1.md
   225  [manual-run-tests]: ../tests/README.md#manually-running-the-tests