Full Code of appc/docker2aci for AI

master 248258bd708a cached
181 files
863.6 KB
246.8k tokens
1736 symbols
1 requests
Download .txt
Showing preview only (922K chars total). Download the full file or copy to clipboard to get everything.
Repository: appc/docker2aci
Branch: master
Commit: 248258bd708a
Files: 181
Total size: 863.6 KB

Directory structure:
gitextract_sbk4zkuw/

├── .gitignore
├── CHANGELOG.md
├── Documentation/
│   └── devel/
│       └── release.md
├── LICENSE
├── MAINTAINERS
├── README.md
├── build.sh
├── glide.yaml
├── lib/
│   ├── common/
│   │   ├── common.go
│   │   └── common_test.go
│   ├── conversion_store.go
│   ├── docker2aci.go
│   ├── internal/
│   │   ├── backend/
│   │   │   ├── file/
│   │   │   │   └── file.go
│   │   │   └── repository/
│   │   │       ├── repository.go
│   │   │       ├── repository1.go
│   │   │       └── repository2.go
│   │   ├── docker/
│   │   │   └── docker.go
│   │   ├── internal.go
│   │   ├── internal_test.go
│   │   ├── tarball/
│   │   │   ├── tarfile.go
│   │   │   └── walk.go
│   │   ├── types/
│   │   │   └── docker_types.go
│   │   ├── typesV2/
│   │   │   └── docker_types.go
│   │   └── util/
│   │       └── util.go
│   ├── tests/
│   │   ├── common.go
│   │   ├── server.go
│   │   └── v22_test.go
│   └── version.go
├── main.go
├── pkg/
│   └── log/
│       └── log.go
├── scripts/
│   ├── bump-release
│   └── glide-update
├── tests/
│   ├── README.md
│   ├── fixture-test-depsloop/
│   │   ├── check.sh
│   │   └── fixture-test-depsloop.docker
│   ├── fixture-test-invalidlayerid/
│   │   ├── check.sh
│   │   └── fixture-test-invalidlayerid.docker
│   ├── rkt-v1.1.0.md5sum
│   ├── test-basic/
│   │   ├── Dockerfile
│   │   └── check.sh
│   ├── test-pwl/
│   │   ├── Dockerfile
│   │   └── check.sh
│   ├── test-whiteouts/
│   │   ├── Dockerfile
│   │   └── check.sh
│   └── test.sh
└── vendor/
    ├── github.com/
    │   ├── appc/
    │   │   └── spec/
    │   │       ├── LICENSE
    │   │       ├── aci/
    │   │       │   ├── build.go
    │   │       │   ├── doc.go
    │   │       │   ├── file.go
    │   │       │   ├── layout.go
    │   │       │   └── writer.go
    │   │       ├── pkg/
    │   │       │   ├── acirenderer/
    │   │       │   │   ├── acirenderer.go
    │   │       │   │   └── resolve.go
    │   │       │   ├── device/
    │   │       │   │   ├── device_linux.go
    │   │       │   │   └── device_posix.go
    │   │       │   └── tarheader/
    │   │       │       ├── doc.go
    │   │       │       ├── pop_darwin.go
    │   │       │       ├── pop_linux.go
    │   │       │       ├── pop_posix.go
    │   │       │       └── tarheader.go
    │   │       └── schema/
    │   │           ├── common/
    │   │           │   └── common.go
    │   │           ├── doc.go
    │   │           ├── image.go
    │   │           ├── kind.go
    │   │           ├── pod.go
    │   │           ├── types/
    │   │           │   ├── acidentifier.go
    │   │           │   ├── ackind.go
    │   │           │   ├── acname.go
    │   │           │   ├── annotations.go
    │   │           │   ├── app.go
    │   │           │   ├── date.go
    │   │           │   ├── dependencies.go
    │   │           │   ├── doc.go
    │   │           │   ├── environment.go
    │   │           │   ├── errors.go
    │   │           │   ├── event_handler.go
    │   │           │   ├── exec.go
    │   │           │   ├── hash.go
    │   │           │   ├── isolator.go
    │   │           │   ├── isolator_linux_specific.go
    │   │           │   ├── isolator_resources.go
    │   │           │   ├── isolator_unix.go
    │   │           │   ├── labels.go
    │   │           │   ├── mountpoint.go
    │   │           │   ├── port.go
    │   │           │   ├── resource/
    │   │           │   │   ├── amount.go
    │   │           │   │   ├── math.go
    │   │           │   │   ├── quantity.go
    │   │           │   │   ├── scale_int.go
    │   │           │   │   └── suffix.go
    │   │           │   ├── semver.go
    │   │           │   ├── url.go
    │   │           │   ├── user_annotations.go
    │   │           │   ├── user_labels.go
    │   │           │   ├── uuid.go
    │   │           │   └── volume.go
    │   │           └── version.go
    │   ├── coreos/
    │   │   ├── go-semver/
    │   │   │   ├── LICENSE
    │   │   │   ├── example.go
    │   │   │   └── semver/
    │   │   │       ├── semver.go
    │   │   │       └── sort.go
    │   │   ├── ioprogress/
    │   │   │   ├── LICENSE
    │   │   │   ├── draw.go
    │   │   │   └── reader.go
    │   │   └── pkg/
    │   │       ├── LICENSE
    │   │       ├── NOTICE
    │   │       └── progressutil/
    │   │           ├── iocopy.go
    │   │           └── progressbar.go
    │   ├── docker/
    │   │   └── distribution/
    │   │       ├── LICENSE
    │   │       ├── blobs.go
    │   │       ├── digestset/
    │   │       │   └── set.go
    │   │       ├── doc.go
    │   │       ├── errors.go
    │   │       ├── manifests.go
    │   │       ├── reference/
    │   │       │   ├── helpers.go
    │   │       │   ├── normalize.go
    │   │       │   ├── reference.go
    │   │       │   └── regexp.go
    │   │       ├── registry.go
    │   │       └── tags.go
    │   ├── klauspost/
    │   │   ├── compress/
    │   │   │   ├── LICENSE
    │   │   │   └── flate/
    │   │   │       ├── copy.go
    │   │   │       ├── crc32_amd64.go
    │   │   │       ├── crc32_amd64.s
    │   │   │       ├── crc32_noasm.go
    │   │   │       ├── deflate.go
    │   │   │       ├── dict_decoder.go
    │   │   │       ├── gen.go
    │   │   │       ├── huffman_bit_writer.go
    │   │   │       ├── huffman_code.go
    │   │   │       ├── inflate.go
    │   │   │       ├── reverse_bits.go
    │   │   │       ├── snappy.go
    │   │   │       └── token.go
    │   │   ├── cpuid/
    │   │   │   ├── LICENSE
    │   │   │   ├── cpuid.go
    │   │   │   ├── cpuid_386.s
    │   │   │   ├── cpuid_amd64.s
    │   │   │   ├── detect_intel.go
    │   │   │   ├── detect_ref.go
    │   │   │   ├── generate.go
    │   │   │   └── private-gen.go
    │   │   ├── crc32/
    │   │   │   ├── LICENSE
    │   │   │   ├── crc32.go
    │   │   │   ├── crc32_amd64.go
    │   │   │   ├── crc32_amd64.s
    │   │   │   ├── crc32_amd64p32.go
    │   │   │   ├── crc32_amd64p32.s
    │   │   │   └── crc32_generic.go
    │   │   └── pgzip/
    │   │       ├── LICENSE
    │   │       ├── gunzip.go
    │   │       └── gzip.go
    │   ├── opencontainers/
    │   │   ├── go-digest/
    │   │   │   ├── LICENSE.code
    │   │   │   ├── LICENSE.docs
    │   │   │   ├── algorithm.go
    │   │   │   ├── digest.go
    │   │   │   ├── digester.go
    │   │   │   ├── doc.go
    │   │   │   └── verifiers.go
    │   │   └── image-spec/
    │   │       ├── LICENSE
    │   │       └── specs-go/
    │   │           ├── v1/
    │   │           │   ├── config.go
    │   │           │   ├── descriptor.go
    │   │           │   ├── manifest.go
    │   │           │   ├── manifest_list.go
    │   │           │   └── mediatype.go
    │   │           ├── version.go
    │   │           └── versioned.go
    │   └── spf13/
    │       └── pflag/
    │           ├── LICENSE
    │           └── flag.go
    ├── go4.org/
    │   ├── LICENSE
    │   └── errorutil/
    │       └── highlight.go
    ├── golang.org/
    │   └── x/
    │       └── crypto/
    │           ├── LICENSE
    │           ├── PATENTS
    │           └── ssh/
    │               └── terminal/
    │                   ├── terminal.go
    │                   ├── util.go
    │                   ├── util_bsd.go
    │                   ├── util_linux.go
    │                   └── util_windows.go
    └── gopkg.in/
        └── inf.v0/
            ├── LICENSE
            ├── dec.go
            └── rounder.go

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so

# Folders
_obj
_test

# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out

*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*

_testmain.go

*.exe
*.test
*.prof

bin/
gopath/

tests/distribution
tests/rendered-test-*
tests/rkt-uuid-test-*
tests/*.docker

*.swp
*.aci


================================================
FILE: CHANGELOG.md
================================================
## v0.17.2

This is a bugfix release to ensure compatibility with newer go-1.10 toolchain.

 - lib/internal: fix tar header format ([#260](https://github.com/appc/docker2aci/pull/260)).
 - tests: update script to run within gopath ([#261](https://github.com/appc/docker2aci/pull/261)).

## v0.17.1

This is a bugfix release that fixes pulling certain images from the Google Container Registry.

 - lib: add signed manifest media type ([#255](https://github.com/appc/docker2aci/pull/255)).

## v0.17.0

This is mostly a bugfix release that fixes a couple of panics and supports additional docker image syntax.

 - Avoid panicking on scratch images ([248](https://github.com/appc/docker2aci/pull/248)).
 - Bugfix/panic on invalid env entry ([#249](https://github.com/appc/docker2aci/pull/249)).
 - lib/common: update `ParseDockerURL` ([#250](https://github.com/appc/docker2aci/pull/250)).

## v0.16.0

This release adds a manifest hash annotation on converted images and introduces some API changes to allow for more granular control on registries and media types.

 - Annotate manifest hash ([#237](https://github.com/appc/docker2aci/pull/237)).
 - Allow selective disabling of registries and media types ([#239](https://github.com/appc/docker2aci/pull/239)).
 - Update appc/spec to 0.8.10 ([#242](https://github.com/appc/docker2aci/pull/242)).

## v0.15.0

This release improves translation of arch labels and image name annotations. It also changes the default output image filename.

 - Translate "os" and "arch" labels of image manifest ([#234](https://github.com/appc/docker2aci/pull/234)).
 - Minor style changes ([#230](https://github.com/appc/docker2aci/pull/230)).
 - Bump appc/spec library version to 0.8.9 ([#233](https://github.com/appc/docker2aci/pull/233)).
 - Image from file improvements; guesses at "originalname" and fixes for "--image"([#229](https://github.com/appc/docker2aci/pull/229)).

## v0.14.0

This release adds compatibility for OCI v1.0.0-rc2 types, introduces supports for converting image labels, and fixes some issues related to automatic fallback to registry API v1.

 - log: introduce Logger interface ([#218](https://github.com/appc/docker2aci/pull/218))
 - lib/internal: set UserLabels to be Docker image labels ([#223](https://github.com/appc/docker2aci/pull/223)).
 - fetch: annotate originally requested name ([#224](https://github.com/appc/docker2aci/pull/224)).
 - types: update OCI image-spec to rc2 ([#226](https://github.com/appc/docker2aci/pull/226)).
 - lib/internal: fix v2 registry check URL ([#220](https://github.com/appc/docker2aci/pull/220))
 - lib/internal: allow auto fallback from v2 API to v1 ([#222](https://github.com/appc/docker2aci/pull/222)).

## v0.13.0

This release adds support for converting local OCI bundles and fixes two security issues (CVE-2016-7569 and CVE-2016-8579). It also includes fixes for several image fetching and conversion bugs.

 - docker2aci: add support for converting OCI tarfiles ([#200](https://github.com/appc/docker2aci/pull/200)).
 - docker2aci: additional validation on malformed images ([#204](https://github.com/appc/docker2aci/pull/204)). Fixes (CVE-2016-7569 and CVE-2016-8579).
 - lib: Use the new media types for oci ([#213](https://github.com/appc/docker2aci/pull/213)).
 - backend/repository: assume no v2 on unexpected status ([#214](https://github.com/appc/docker2aci/pull/214)).
 - lib/internal: do not compare tag when pulling by digest ([#207](https://github.com/appc/docker2aci/pull/207)).
 - lib/internal: re-use uid value when gid is missing ([#206](https://github.com/appc/docker2aci/pull/206)).
 - lib/internal: add entrypoint/cmd annotations to v21 images ([#199](https://github.com/appc/docker2aci/pull/199)).

## v0.12.3

This is another bugfix release.

- lib/repository2: get the correct layer index ([#188](https://github.com/appc/docker2aci/pull/188)). This fixes layer ordering for the Docker API v2.1.
- lib/repository2: fix manifest v2.2 layer ordering ([#190](https://github.com/appc/docker2aci/pull/190)). This fixes layer ordering for the Docker API v2.2.

## v0.12.2

This is a bugfix release.

- lib/repository2: populate reverseLayers correctly ([#185](https://github.com/appc/docker2aci/pull/185)). It caused converted Image Manifests to have the wrong fields. Add a test to make sure this won't go unnoticed again.
- tests: remove redundant code and simplify ([#186](https://github.com/appc/docker2aci/pull/186)).

## v0.12.1

This release fixes a couple of bugs, adds image fetching tests, and replaces godep with glide for vendoring.

- Replace Godeps with glide ([#174](https://github.com/appc/docker2aci/pull/174)).
- Avoid O(N) and fix defer reader close ([#180](https://github.com/appc/docker2aci/pull/180)).
- Add golang tests to lib/test to test image fetching ([#181](https://github.com/appc/docker2aci/pull/181)).

## v0.12.0

v0.12.0 introduces support for the Docker v2.2 image format and OCI image format. It also fixes a bug that prevented pulling by digest to work.

- backend/repository2: don't ignore when there's an image digest ([#171](https://github.com/appc/docker2aci/pull/171)).
- lib/repository2: add support for docker v2.2 and OCI ([#176](https://github.com/appc/docker2aci/pull/176)).

## v0.11.1

v0.11.1 is a bugfix release.

- Fix parallel pull synchronisation ([#167](https://github.com/appc/docker2aci/pull/167), [#168](https://github.com/appc/docker2aci/pull/168)).

## v0.11.0

This release splits the `--insecure` flag in two, `--insecure-skip-verify` to skip TLS verification, and `--insecure-allow-http` to allow unencrypted connections when fetching images. It also includes a couple of bugfixes.

- Add missing message to channel on successful layer download ([#161](https://github.com/appc/docker2aci/pull/161)).
- Fix a panic when a layer being fetched encounters an error ([#162](https://github.com/appc/docker2aci/pull/162)).
- Split `--insecure` flag in two ([#163](https://github.com/appc/docker2aci/pull/163)).

## v0.10.0

This release includes two major performance optimizations: parallel layer pull and parallel ACI compression.

- Pull layers in parallel ([#158](https://github.com/appc/docker2aci/pull/158)).
- Use a parallel compression library ([#157](https://github.com/appc/docker2aci/pull/157)).
- Fix auth token parsing to handle services with spaces in their names ([#150](https://github.com/appc/docker2aci/pull/150)).

## v0.9.3

v0.9.3 is a minor bug fix release.

- Use the default transport when doing HTTP requests ([#147](https://github.com/appc/docker2aci/pull/147)). We were using an empty transport which didn't pass on the proxy configuration.

## v0.9.2

v0.9.2 is a minor release with a bug fix and a cleanup over the previous one.

- Use upstream docker functions to parse docker URLs and parse digest ([#140](https://github.com/appc/docker2aci/pull/140)).
- Change docker entrypoint/cmd annotations to json ([#142](https://github.com/appc/docker2aci/pull/142)).

## v0.9.1

v0.9.1 is mainly a bugfix and cleanup release.

- Remove redundant dependency fetching, we're vendoring them now ([#134](https://github.com/appc/docker2aci/pull/134)).
- Export ParseDockerURL which is used by rkt ([#135](https://github.com/appc/docker2aci/pull/135)).
- Export annotations so people can use them outside docker2aci ([#135](https://github.com/appc/docker2aci/pull/135)).
- Refactor the library so internal functions are in the "internal" package ([#135](https://github.com/appc/docker2aci/pull/135)).
- Document release process and add a bump-version script ([#137](https://github.com/appc/docker2aci/pull/137)).

## v0.9.0

v0.9.0 is the initial release of docker2aci.

docker2aci converts to ACI Docker images from a remote repository or from a local file generated with "docker save".

It supports v1 and v2 Docker registries, compression, and layer squashing.


================================================
FILE: Documentation/devel/release.md
================================================
# docker2aci release guide

How to perform a release of docker2aci.
This guide is probably unnecessarily verbose, so improvements welcomed.
Only parts of the procedure are automated; this is somewhat intentional (manual steps for sanity checking) but it can probably be further scripted, please help.

The following example assumes we're going from version 0.9.0 (`v0.9.0`) to 0.9.1 (`v0.9.1`).

Let's get started:

- Start at the relevant milestone on GitHub (e.g. https://github.com/appc/docker2aci/milestones/v0.9.1): ensure all referenced issues are closed (or moved elsewhere, if they're not done). Close the milestone.
- Branch from the latest master, make sure your git status is clean
- Ensure the build is clean!
  - `git clean -ffdx && ./build.sh && ./tests/test.sh` should work
  - Integration tests on CI should be green
- Update the [release notes](https://github.com/appc/docker2aci/blob/master/CHANGELOG.md).
  Try to capture most of the salient changes since the last release, but don't go into unnecessary detail (better to link/reference the documentation wherever possible).

The docker2aci version is [hardcoded in the repository](https://github.com/appc/docker2aci/blob/master/lib/version.go#L19), so the first thing to do is bump it:

- Run `scripts/bump-release v0.9.1`.
  This should generate two commits: a bump to the actual release (e.g. v0.9.1), and then a bump to the release+git (e.g. v0.9.1+git).
  The actual release version should only exist in a single commit!
- Sanity check what the script did with `git diff HEAD^^` or similar.
- If the script didn't work, yell at the author and/or fix it.
  It can almost certainly be improved.
- File a PR and get a review from another [MAINTAINER](https://github.com/appc/docker2aci/blob/master/MAINTAINERS).
  This is useful to a) sanity check the diff, and b) be very explicit/public that a release is happening
- Ensure the CI on the release PR is green!

After merging and going back to master branch, we check out the release version and tag it:

- `git checkout HEAD^` should work; sanity check lib/version.go (the `Version` variable) after doing this
- Add a signed tag: `git tag -s v0.9.1`.
- Build docker2aci
  - `sudo git clean -ffdx && ./build.sh`
  - Sanity check `bin/docker2aci -version`
- Push the tag to GitHub: `git push --tags`

Now we switch to the GitHub web UI to conduct the release:

- https://github.com/appc/docker2aci/releases/new
- For now, check "This is a pre-release"
- Tag "v0.9.1", release title "v0.9.1"
- Copy-paste the release notes you added earlier in [CHANGELOG.md](https://github.com/appc/docker2aci/blob/master/CHANGELOG.md)
- You can also add a little more detail and polish to the release notes here if you wish, as it is more targeted towards users (vs the changelog being more for developers); use your best judgement and see previous releases on GH for examples.
- Attach the release.
  This is a simple tarball:

```
	export NAME="docker2aci-v0.9.1"
	mkdir $NAME
	cp bin/docker2aci $NAME/
	sudo chown -R root:root $NAME/
	tar czvf $NAME.tar.gz --numeric-owner $NAME/
```

- Attach the release signature; your personal GPG is okay for now:

```
	gpg --detach-sign $NAME.tar.gz
```

- Publish the release!

- Clean your git tree: `sudo git clean -ffdx`.


================================================
FILE: LICENSE
================================================
Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "{}"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright {yyyy} {name of copyright owner}

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.



================================================
FILE: MAINTAINERS
================================================
Alban Crequy <alban@kinvolk.io> (@alban)
Iago López Galeiras <iago@kinvolk.io> (@iaguis)
Krzesimir Nowak <krzesimir@kinvolk.io> (@krnowak)


================================================
FILE: README.md
================================================
# docker2aci - Convert docker images to ACI

[![Build Status](https://semaphoreci.com/api/v1/projects/4472761c-2b88-41f2-b2de-bf0447a8a290/610597/badge.svg)](https://semaphoreci.com/appc/docker2aci)

docker2aci is a small library and CLI binary that converts Docker images to
[ACI][aci]. It takes as input either a file generated by "docker save" or a
Docker registry URL. It gets all the layers of a Docker image and squashes them
into an ACI image. Optionally, it can generate one ACI for each layer, setting
the correct dependencies.

All ACIs generated are compressed with gzip by default. Compression can be
disabled by specifying `--compression=none`.


## Build

Requirements: golang 1.6+

	git clone git://github.com/appc/docker2aci
	cd docker2aci
	./build.sh

## Volumes

Docker Volumes get converted to mountPoints in the [Image Manifest
Schema][imageschema]. Since mountPoints need a name and Docker Volumes don't,
docker2aci generates a name by appending the path to `volume-` replacing
non-alphanumeric characters with dashes. That is, if a Volume has `/var/tmp`
as path, the resulting mountPoint name will be `volume-var-tmp`.

When the docker2aci CLI binary converts a Docker Volume to a mountPoint it will
print its name, path and whether it is read-only or not.

## Ports

Docker Ports get converted to ports in the [Image Manifest
Schema][imageschema]. The resulting port name will be the port number and the
protocol separated by a dash. For example: `6379-tcp`.

## CLI examples

```
$ docker2aci docker://busybox
Downloading sha256:55dc925c23d: [==============================] 674 KB/674 KB
Downloading sha256:a3ed95caeb0: [==============================] 32 B/32 B

Generated ACI(s):
library-busybox-latest.aci
$ actool --debug validate library-busybox-latest.aci
library-busybox-latest.aci: valid app container image
```

```
$ /docker2aci --nosquash docker://quay.io/coreos/etcd:latest
Downloading sha256:f05e5379dcb: [==============================] 3.98 MB/3.98 MB
Downloading sha256:af1897d2d32: [==============================] 3.5 MB/3.5 MB
Downloading sha256:a3ed95caeb0: [==============================] 32 B/32 B
Downloading sha256:a3ed95caeb0: [==============================] 32 B/32 B

Converted ports:
        name: "2379-tcp", protocol: "tcp", port: 2379, count: 1, socketActivated: false
        name: "2380-tcp", protocol: "tcp", port: 2380, count: 1, socketActivated: false
        name: "4001-tcp", protocol: "tcp", port: 4001, count: 1, socketActivated: false
        name: "7001-tcp", protocol: "tcp", port: 7001, count: 1, socketActivated: false

Generated ACI(s):
coreos-etcd-d21dd9a5886270b7c2c379c02fc548e0696b139c43bb12fdb2d9b63409717485-latest-linux-amd64-3.aci
coreos-etcd-620329641f386e62c7b0e0fa60a9acef100e71058124ddc7f1969557c72b2458-latest-linux-amd64-2.aci
coreos-etcd-9cd3f08f7ccfaad24c73757a5b4f79601f2790726d6ccdd556a82e5c9c5ddbfa-latest-linux-amd64-1.aci
coreos-etcd-9cd3f08f7ccfaad24c73757a5b4f79601f2790726d6ccdd556a82e5c9c5ddbfa-latest-linux-amd64-0.aci
```

```
$ docker save -o ubuntu.docker ubuntu
$ docker2aci ubuntu.docker
Extracting 706766fe1019
Extracting a62a42e77c9c
Extracting 2c014f14d3d9
Extracting b7cf8f0d9e82

Generated ACI(s):
ubuntu-latest.aci
$ actool --debug validate ubuntu-latest.aci
ubuntu-latest.aci: valid app container image
```

```
$ docker2aci docker://redis
Downloading sha256:c666c10c893: [==============================] 37.2 MB/37.2 MB
Downloading sha256:a3ed95caeb0: [==============================] 32 B/32 B
Downloading sha256:d6f52360d0a: [==============================] 1.69 KB/1.69 KB
Downloading sha256:8c3a687fd4c: [==============================] 5.93 MB/5.93 MB
Downloading sha256:15554e0e598: [==============================] 109 KB/109 KB 
Downloading sha256:3286d490a29: [==============================] 611 KB/611 KB 
Downloading sha256:a3ed95caeb0: [==============================] 32 B/32 B
Downloading sha256:a3ed95caeb0: [==============================] 32 B/32 B
Downloading sha256:a3ed95caeb0: [==============================] 32 B/32 B
Downloading sha256:a3d89b95a63: [==============================] 3.04 MB/3.04 MB
Downloading sha256:1c4db557158: [==============================] 98 B/98 B
Downloading sha256:a3ed95caeb0: [==============================] 32 B/32 B
Downloading sha256:a3ed95caeb0: [==============================] 32 B/32 B
Downloading sha256:a1a961e320b: [==============================] 196 B/196 B
Downloading sha256:a3ed95caeb0: [==============================] 32 B/32 B
Downloading sha256:a3ed95caeb0: [==============================] 32 B/32 B
Downloading sha256:a3ed95caeb0: [==============================] 32 B/32 B

Converted volumes:
        name: "volume-data", path: "/data", readOnly: false

Converted ports:
        name: "6379-tcp", protocol: "tcp", port: 6379, count: 1, socketActivated: false

Generated ACI(s):
library-redis-latest.aci
$ actool --debug validate library-redis-latest.aci
library-redis-latest.aci: valid app container image
```

[aci]: https://github.com/appc/spec/blob/master/SPEC.md#app-container-image
[imageschema]: https://github.com/appc/spec/blob/master/spec/aci.md#image-manifest-schema


================================================
FILE: build.sh
================================================
#!/usr/bin/env bash
set -e

# Gets the directory that this script is stored in.
# https://stackoverflow.com/questions/59895/can-a-bash-script-tell-what-directory-its-stored-in
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

ORG_PATH="github.com/appc"
REPO_PATH="${ORG_PATH}/docker2aci"
VERSION=$(git describe --dirty --always)
GLDFLAGS="-X ${REPO_PATH}/lib.Version=${VERSION}"

if [ ! -h ${DIR}/gopath/src/${REPO_PATH} ]; then
  mkdir -p ${DIR}/gopath/src/${ORG_PATH}
  cd ${DIR} && ln -s ../../../.. gopath/src/${REPO_PATH} || exit 255
fi

export GO15VENDOREXPERIMENT=1
export GOBIN=${DIR}/bin
export GOPATH=${DIR}/gopath
export GOOS GOARCH

eval $(go env)

if [ "${GOOS}" = "freebsd" ]; then
    # /usr/bin/cc is clang on freebsd, but we need to tell it to go to
    # make it generate proper flavour of code that doesn't emit
    # warnings.
    export CC=clang
fi

echo "Building docker2aci..."
go build -o ${GOBIN}/docker2aci -ldflags "${GLDFLAGS}" ${REPO_PATH}


================================================
FILE: glide.yaml
================================================
package: github.com/appc/docker2aci
import:
- package: github.com/appc/spec
  version: 0.8.10
  subpackages:
  - aci
  - pkg/acirenderer
  - schema
  - schema/types
- package: github.com/coreos/ioprogress
  version: 4637e494fd9b23c5565ee193e89f91fdc1639bc0
- package: github.com/coreos/pkg
  version: 2.0.0
  subpackages:
  - progressutil
- package: github.com/docker/distribution
  version: 5db89f0ca68677abc5eefce8f2a0a772c98ba52d
  subpackages:
  - reference
- package: github.com/klauspost/pgzip
  version: 1.0.0
- package: github.com/opencontainers/image-spec
  version: v1.0.0-rc2
  subpackages:
  - specs-go
- package: github.com/opencontainers/go-digest
  version: 21dfd564fd89c944783d00d069f33e3e7123c448


================================================
FILE: lib/common/common.go
================================================
// Copyright 2016 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package common provides misc types and variables.
package common

import (
	"fmt"
	"regexp"

	"github.com/appc/docker2aci/lib/internal/docker"
	"github.com/docker/distribution/reference"

	spec "github.com/opencontainers/image-spec/specs-go/v1"
)

type Compression int

const (
	NoCompression = iota
	GzipCompression
)

var (
	validId = regexp.MustCompile(`^(\w+:)?([A-Fa-f0-9]+)$`)
)

const (
	// AppcDockerOriginalName is the unmodified name this image was originally
	// referenced by for fetching, e.g. something like "nginx:tag" or
	// "quay.io/user/image:latest" This is identical in most cases to
	// 'registryurl/repository:tag' but may differ for the default Dockerhub
	// registry or if the tag was inferred as latest.
	AppcDockerOriginalName  = "appc.io/docker/originalname"
	AppcDockerRegistryURL   = "appc.io/docker/registryurl"
	AppcDockerRepository    = "appc.io/docker/repository"
	AppcDockerTag           = "appc.io/docker/tag"
	AppcDockerImageID       = "appc.io/docker/imageid"
	AppcDockerParentImageID = "appc.io/docker/parentimageid"
	AppcDockerEntrypoint    = "appc.io/docker/entrypoint"
	AppcDockerCmd           = "appc.io/docker/cmd"
	AppcDockerManifestHash  = "appc.io/docker/manifesthash"
)

const defaultTag = "latest"

// ParsedDockerURL represents a parsed Docker URL.
type ParsedDockerURL struct {
	OriginalName string
	IndexURL     string
	ImageName    string
	Tag          string
	Digest       string
}

type ErrSeveralImages struct {
	Msg    string
	Images []string
}

// InsecureConfig represents the different insecure options available
type InsecureConfig struct {
	SkipVerify bool
	AllowHTTP  bool
}

func (e *ErrSeveralImages) Error() string {
	return e.Msg
}

// ParseDockerURL takes a Docker URL and returns a ParsedDockerURL with its
// index URL, image name, and tag.
func ParseDockerURL(arg string) (*ParsedDockerURL, error) {
	r, err := reference.ParseNormalizedNamed(arg)
	if err != nil {
		return nil, err
	}

	var tag, digest string
	switch x := r.(type) {
	case reference.Canonical:
		digest = x.Digest().String()
	case reference.NamedTagged:
		tag = x.Tag()
	default:
		tag = defaultTag
	}

	indexURL, remoteName := docker.SplitReposName(reference.FamiliarName(r))

	return &ParsedDockerURL{
		OriginalName: arg,
		IndexURL:     indexURL,
		ImageName:    remoteName,
		Tag:          tag,
		Digest:       digest,
	}, nil
}

// ValidateLayerId validates a layer ID
func ValidateLayerId(id string) error {
	if ok := validId.MatchString(id); !ok {
		return fmt.Errorf("invalid layer ID %q", id)
	}
	return nil
}

/*
 * Media Type Selectors Section
 */

const (
	MediaTypeDockerV21Manifest       = "application/vnd.docker.distribution.manifest.v1+json"
	MediaTypeDockerV21SignedManifest = "application/vnd.docker.distribution.manifest.v1+prettyjws"
	MediaTypeDockerV21ManifestLayer  = "application/vnd.docker.container.image.rootfs.diff+x-gtar"

	MediaTypeDockerV22Manifest     = "application/vnd.docker.distribution.manifest.v2+json"
	MediaTypeDockerV22ManifestList = "application/vnd.docker.distribution.manifest.list.v2+json"
	MediaTypeDockerV22Config       = "application/vnd.docker.container.image.v1+json"
	MediaTypeDockerV22RootFS       = "application/vnd.docker.image.rootfs.diff.tar.gzip"

	MediaTypeOCIV1Manifest     = spec.MediaTypeImageManifest
	MediaTypeOCIV1ManifestList = spec.MediaTypeImageManifestList
	MediaTypeOCIV1Config       = spec.MediaTypeImageConfig
	MediaTypeOCIV1Layer        = spec.MediaTypeImageLayer
)

// MediaTypeOption represents the media types for a given docker image (or oci)
// spec.
type MediaTypeOption int

const (
	MediaTypeOptionDockerV21 = iota
	MediaTypeOptionDockerV22
	MediaTypeOptionOCIV1Pre
)

// MediaTypeSet represents a set of media types which docker2aci is to use when
// fetchimg images. As an example if a MediaTypeSet is equal to
// {MediaTypeOptionDockerV22, MediaTypeOptionOCIV1Pre}, then when an image pull
// is made V2.1 images will not be fetched. This doesn't apply to V1 pulls. As
// an edge case if a MedaTypeSet is nil or empty, that means that _every_ type
// of media type is enabled. This type is intended to be a set, and putting
// duplicates in this set is generally unadvised.
type MediaTypeSet []MediaTypeOption

func (m MediaTypeSet) ManifestMediaTypes() []string {
	if len(m) == 0 {
		return []string{
			MediaTypeDockerV21Manifest,
			MediaTypeDockerV21SignedManifest,
			MediaTypeDockerV22Manifest,
			MediaTypeOCIV1Manifest,
		}
	}
	ret := []string{}
	for _, option := range m {
		switch option {
		case MediaTypeOptionDockerV21:
			ret = append(ret, MediaTypeDockerV21Manifest)
			ret = append(ret, MediaTypeDockerV21SignedManifest)
		case MediaTypeOptionDockerV22:
			ret = append(ret, MediaTypeDockerV22Manifest)
		case MediaTypeOptionOCIV1Pre:
			ret = append(ret, MediaTypeOCIV1Manifest)
		}
	}
	return ret
}

func (m MediaTypeSet) ConfigMediaTypes() []string {
	if len(m) == 0 {
		return []string{
			MediaTypeDockerV22Config,
			MediaTypeOCIV1Config,
		}
	}
	ret := []string{}
	for _, option := range m {
		switch option {
		case MediaTypeOptionDockerV21:
		case MediaTypeOptionDockerV22:
			ret = append(ret, MediaTypeDockerV22Config)
		case MediaTypeOptionOCIV1Pre:
			ret = append(ret, MediaTypeOCIV1Config)
		}
	}
	return ret
}

func (m MediaTypeSet) LayerMediaTypes() []string {
	if len(m) == 0 {
		return []string{
			MediaTypeDockerV22RootFS,
			MediaTypeOCIV1Layer,
		}
	}
	ret := []string{}
	for _, option := range m {
		switch option {
		case MediaTypeOptionDockerV21:
		case MediaTypeOptionDockerV22:
			ret = append(ret, MediaTypeDockerV22RootFS)
		case MediaTypeOptionOCIV1Pre:
			ret = append(ret, MediaTypeOCIV1Layer)
		}
	}
	return ret
}

// RegistryOption represents a type of a registry, based on the version of the
// docker http API.
type RegistryOption int

const (
	RegistryOptionV1 = iota
	RegistryOptionV2
)

// RegistryOptionSet represents a set of registry types which docker2aci is to
// use when fetching images. As an example if a RegistryOptionSet is equal to
// {RegistryOptionV2}, then v1 pulls are disabled. As an edge case if a
// RegistryOptionSet is nil or empty, that means that _every_ type of registry
// is enabled. This type is intended to be a set, and putting duplicates in this
// set is generally unadvised.
type RegistryOptionSet []RegistryOption

func (r RegistryOptionSet) AllowsV1() bool {
	if len(r) == 0 {
		return true
	}
	for _, o := range r {
		if o == RegistryOptionV1 {
			return true
		}
	}
	return false
}

func (r RegistryOptionSet) AllowsV2() bool {
	if len(r) == 0 {
		return true
	}
	for _, o := range r {
		if o == RegistryOptionV2 {
			return true
		}
	}
	return false
}


================================================
FILE: lib/common/common_test.go
================================================
// Copyright 2017 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package common

import (
	_ "crypto/sha256"
	"reflect"
	"testing"
)

func TestMediaTypeSet(t *testing.T) {
	tests := []struct {
		ms                    MediaTypeSet
		expectedManifestTypes []string
		expectedConfigTypes   []string
		expectedLayerTypes    []string
	}{
		{
			MediaTypeSet{MediaTypeOptionDockerV21},
			[]string{MediaTypeDockerV21Manifest, MediaTypeDockerV21SignedManifest},
			[]string{},
			[]string{},
		},
		{
			MediaTypeSet{MediaTypeOptionDockerV22},
			[]string{MediaTypeDockerV22Manifest},
			[]string{MediaTypeDockerV22Config},
			[]string{MediaTypeDockerV22RootFS},
		},
		{
			MediaTypeSet{MediaTypeOptionOCIV1Pre},
			[]string{MediaTypeOCIV1Manifest},
			[]string{MediaTypeOCIV1Config},
			[]string{MediaTypeOCIV1Layer},
		},
		{
			MediaTypeSet{},
			[]string{MediaTypeDockerV21Manifest, MediaTypeDockerV21SignedManifest, MediaTypeDockerV22Manifest, MediaTypeOCIV1Manifest},
			[]string{MediaTypeDockerV22Config, MediaTypeOCIV1Config},
			[]string{MediaTypeDockerV22RootFS, MediaTypeOCIV1Layer},
		},
		{
			MediaTypeSet{MediaTypeOptionDockerV21, MediaTypeOptionDockerV22, MediaTypeOptionOCIV1Pre},
			[]string{MediaTypeDockerV21Manifest, MediaTypeDockerV21SignedManifest, MediaTypeDockerV22Manifest, MediaTypeOCIV1Manifest},
			[]string{MediaTypeDockerV22Config, MediaTypeOCIV1Config},
			[]string{MediaTypeDockerV22RootFS, MediaTypeOCIV1Layer},
		},
		{
			MediaTypeSet{MediaTypeOptionDockerV21, MediaTypeOptionOCIV1Pre},
			[]string{MediaTypeDockerV21Manifest, MediaTypeDockerV21SignedManifest, MediaTypeOCIV1Manifest},
			[]string{MediaTypeOCIV1Config},
			[]string{MediaTypeOCIV1Layer},
		},
	}

	for _, test := range tests {
		if !isEqual(test.expectedManifestTypes, test.ms.ManifestMediaTypes()) {
			t.Errorf("expected manifest media types didn't match what was returned:\n%v\n%v", test.expectedManifestTypes, test.ms.ManifestMediaTypes())
		}
		if !isEqual(test.expectedConfigTypes, test.ms.ConfigMediaTypes()) {
			t.Errorf("expected config media types didn't match what was returned:\n%v\n%v", test.expectedConfigTypes, test.ms.ConfigMediaTypes())
		}
		if !isEqual(test.expectedLayerTypes, test.ms.LayerMediaTypes()) {
			t.Errorf("expected layer media types didn't match what was returned:\n%v\n%v", test.expectedLayerTypes, test.ms.LayerMediaTypes())
		}
	}
}

func TestRegistryOptionSet(t *testing.T) {
	tests := []struct {
		rs       RegistryOptionSet
		allowsV1 bool
		allowsV2 bool
	}{
		{
			RegistryOptionSet{RegistryOptionV1}, true, false,
		},
		{
			RegistryOptionSet{RegistryOptionV2}, false, true,
		},
		{
			RegistryOptionSet{RegistryOptionV1, RegistryOptionV2}, true, true,
		},
		{
			RegistryOptionSet{}, true, true,
		},
	}
	for _, test := range tests {
		if test.allowsV1 != test.rs.AllowsV1() {
			t.Errorf("doesn't allow V1 when it should")
		}
		if test.allowsV2 != test.rs.AllowsV2() {
			t.Errorf("doesn't allow V1 when it should")
		}
	}
}

func isEqual(val1, val2 []string) bool {
	if len(val1) != len(val2) {
		return false
	}
loop1:
	for _, thing1 := range val1 {
		for _, thing2 := range val2 {
			if thing1 == thing2 {
				continue loop1
			}
		}
		return false
	}
	return true
}

func TestParseDockerURL(t *testing.T) {
	tests := []struct {
		input    string
		expected *ParsedDockerURL
	}{
		{
			"busybox",
			&ParsedDockerURL{
				OriginalName: "busybox",
				IndexURL:     "registry-1.docker.io",
				ImageName:    "library/busybox",
				Tag:          "latest",
				Digest:       "",
			},
		},
		{
			"library/busybox",
			&ParsedDockerURL{
				OriginalName: "library/busybox",
				IndexURL:     "registry-1.docker.io",
				ImageName:    "library/busybox",
				Tag:          "latest",
				Digest:       "",
			},
		},
		{
			"docker.io/library/busybox:1",
			&ParsedDockerURL{
				OriginalName: "docker.io/library/busybox:1",
				IndexURL:     "registry-1.docker.io",
				ImageName:    "library/busybox",
				Tag:          "1",
				Digest:       "",
			},
		},
		{
			"docker.io/library/busybox",
			&ParsedDockerURL{
				OriginalName: "docker.io/library/busybox",
				IndexURL:     "registry-1.docker.io",
				ImageName:    "library/busybox",
				Tag:          "latest",
				Digest:       "",
			},
		},
		{
			"gcr.io/google-samples/node-hello:1.0",
			&ParsedDockerURL{
				OriginalName: "gcr.io/google-samples/node-hello:1.0",
				IndexURL:     "gcr.io",
				ImageName:    "google-samples/node-hello",
				Tag:          "1.0",
				Digest:       "",
			},
		},
		{
			"alpine@sha256:ea0d1389812f43e474c50155ec4914e1b48792d420820c15cab28c0794034950",
			&ParsedDockerURL{
				OriginalName: "alpine@sha256:ea0d1389812f43e474c50155ec4914e1b48792d420820c15cab28c0794034950",
				IndexURL:     "registry-1.docker.io",
				ImageName:    "library/alpine",
				Tag:          "",
				Digest:       "sha256:ea0d1389812f43e474c50155ec4914e1b48792d420820c15cab28c0794034950",
			},
		},
	}
	for _, test := range tests {
		parsed, err := ParseDockerURL(test.input)
		if err != nil && test.expected != nil {
			t.Errorf("error when parsing %q: %v\nexpected: %+v", test.input, err, test.expected)
		} else if err == nil && test.expected == nil {
			t.Errorf("expected %q to result in error\n", test.input)
		} else if !reflect.DeepEqual(test.expected, parsed) {
			t.Errorf("expected and parsed `&ParsedDockerURL{}` differ:\nexpected: %+v\nparsed:   %+v\n", test.expected, parsed)
		}
	}
}


================================================
FILE: lib/conversion_store.go
================================================
// Copyright 2015 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package docker2aci

import (
	"crypto/sha512"
	"fmt"
	"hash"
	"io"
	"io/ioutil"
	"os"

	"github.com/appc/spec/aci"
	"github.com/appc/spec/schema"
	"github.com/appc/spec/schema/types"
)

const (
	hashPrefix = "sha512-"
)

type aciInfo struct {
	path          string
	key           string
	ImageManifest *schema.ImageManifest
}

// conversionStore is an simple implementation of the acirenderer.ACIRegistry
// interface. It stores the Docker layers converted to ACI so we can take
// advantage of acirenderer to generate a squashed ACI Image.
type conversionStore struct {
	acis map[string]*aciInfo
}

func newConversionStore() *conversionStore {
	return &conversionStore{acis: make(map[string]*aciInfo)}
}

func (ms *conversionStore) WriteACI(path string) (string, error) {
	f, err := os.Open(path)
	if err != nil {
		return "", err
	}
	defer f.Close()

	cr, err := aci.NewCompressedReader(f)
	if err != nil {
		return "", err
	}
	defer cr.Close()

	h := sha512.New()
	r := io.TeeReader(cr, h)

	// read the file so we can get the hash
	if _, err := io.Copy(ioutil.Discard, r); err != nil {
		return "", fmt.Errorf("error reading ACI: %v", err)
	}

	im, err := aci.ManifestFromImage(f)
	if err != nil {
		return "", err
	}

	key := ms.HashToKey(h)
	ms.acis[key] = &aciInfo{path: path, key: key, ImageManifest: im}
	return key, nil
}

func (ms *conversionStore) GetImageManifest(key string) (*schema.ImageManifest, error) {
	aci, ok := ms.acis[key]
	if !ok {
		return nil, fmt.Errorf("aci with key: %s not found", key)
	}
	return aci.ImageManifest, nil
}

func (ms *conversionStore) GetACI(name types.ACIdentifier, labels types.Labels) (string, error) {
	for _, aci := range ms.acis {
		// we implement this function to comply with the interface so don't
		// bother implementing a proper label check
		if aci.ImageManifest.Name.String() == name.String() {
			return aci.key, nil
		}
	}
	return "", fmt.Errorf("aci not found")
}

func (ms *conversionStore) ReadStream(key string) (io.ReadCloser, error) {
	img, ok := ms.acis[key]
	if !ok {
		return nil, fmt.Errorf("stream for key: %s not found", key)
	}
	f, err := os.Open(img.path)
	if err != nil {
		return nil, fmt.Errorf("error opening aci: %s", img.path)
	}

	tr, err := aci.NewCompressedReader(f)
	if err != nil {
		return nil, err
	}

	return tr, nil
}

func (ms *conversionStore) ResolveKey(key string) (string, error) {
	return key, nil
}

func (ms *conversionStore) HashToKey(h hash.Hash) string {
	s := h.Sum(nil)
	return fmt.Sprintf("%s%x", hashPrefix, s)
}


================================================
FILE: lib/docker2aci.go
================================================
// Copyright 2015 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package docker2aci implements a simple library for converting docker images to
// App Container Images (ACIs).
package docker2aci

import (
	"archive/tar"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"

	"github.com/appc/docker2aci/lib/common"
	"github.com/appc/docker2aci/lib/internal"
	"github.com/appc/docker2aci/lib/internal/backend/file"
	"github.com/appc/docker2aci/lib/internal/backend/repository"
	"github.com/appc/docker2aci/lib/internal/docker"
	"github.com/appc/docker2aci/lib/internal/tarball"
	"github.com/appc/docker2aci/lib/internal/util"
	"github.com/appc/docker2aci/pkg/log"
	"github.com/appc/spec/pkg/acirenderer"
	"github.com/appc/spec/schema"
	appctypes "github.com/appc/spec/schema/types"
	gzip "github.com/klauspost/pgzip"
)

// CommonConfig represents the shared configuration options for converting
// Docker images.
type CommonConfig struct {
	Squash                bool               // squash the layers in one file
	OutputDir             string             // where to put the resulting ACI
	TmpDir                string             // directory to use for temporary files
	Compression           common.Compression // which compression to use for the resulting file(s)
	CurrentManifestHashes []string           // any manifest hashes the caller already has

	Info  log.Logger
	Debug log.Logger
}

func (c *CommonConfig) initLogger() {
	if c.Info == nil {
		c.Info = log.NewStdLogger(os.Stderr)
	}

	if c.Debug == nil {
		c.Debug = log.NewNopLogger()
	}
}

// RemoteConfig represents the remote repository specific configuration for
// converting Docker images.
type RemoteConfig struct {
	CommonConfig
	Username        string                // username to use if the image to convert needs authentication
	Password        string                // password to use if the image to convert needs authentication
	Insecure        common.InsecureConfig // Insecure options
	MediaTypes      common.MediaTypeSet
	RegistryOptions common.RegistryOptionSet
}

// FileConfig represents the saved file specific configuration for converting
// Docker images.
type FileConfig struct {
	CommonConfig
	DockerURL string // select an image if there are several images/tags in the file, Syntax: "{docker registry URL}/{image name}:{tag}"
}

// ConvertRemoteRepo generates ACI images from docker registry URLs.  It takes
// as input a dockerURL of the form:
//
//     {registry URL}/{repository}:{reference[tag|digest]}
//
// It then gets all the layers of the requested image and converts each of
// them to ACI.
// It returns the list of generated ACI paths.
func ConvertRemoteRepo(dockerURL string, config RemoteConfig) ([]string, error) {
	config.initLogger()

	return (&converter{
		backend: repository.NewRepositoryBackend(
			config.Username,
			config.Password,
			config.Insecure,
			config.Debug,
			config.MediaTypes,
			config.RegistryOptions,
		),
		dockerURL: dockerURL,
		config:    config.CommonConfig,
	}).convert()
}

// ConvertSavedFile generates ACI images from a file generated with "docker
// save".  If there are several images/tags in the file, a particular image can
// be chosen via FileConfig.DockerURL.
//
// It returns the list of generated ACI paths.
func ConvertSavedFile(dockerSavedFile string, config FileConfig) ([]string, error) {
	config.initLogger()

	f, err := os.Open(dockerSavedFile)
	if err != nil {
		return nil, fmt.Errorf("error opening file: %v", err)
	}
	defer f.Close()

	return (&converter{
		backend:   file.NewFileBackend(f, config.Debug, config.Info),
		dockerURL: config.DockerURL,
		config:    config.CommonConfig,
	}).convert()
}

// GetIndexName returns the docker index server from a docker URL.
func GetIndexName(dockerURL string) string {
	index, _ := docker.SplitReposName(dockerURL)
	return index
}

// GetDockercfgAuth reads a ~/.dockercfg file and returns the username and password
// of the given docker index server.
func GetDockercfgAuth(indexServer string) (string, string, error) {
	return docker.GetAuthInfo(indexServer)
}

type converter struct {
	backend   internal.Docker2ACIBackend
	dockerURL string
	config    CommonConfig
}

func (c *converter) convert() ([]string, error) {
	c.config.Debug.Println("Getting image info...")
	ancestry, manhash, parsedDockerURL, err := c.backend.GetImageInfo(c.dockerURL)
	if err != nil {
		return nil, err
	}
	if len(ancestry) == 0 {
		return nil, fmt.Errorf("backend image had no useful layers: not creating ACI")
	}
	for _, h := range c.config.CurrentManifestHashes {
		if manhash == h {
			return nil, nil
		}
	}

	layersOutputDir := c.config.OutputDir
	if c.config.Squash {
		layersOutputDir, err = ioutil.TempDir(c.config.TmpDir, "docker2aci-")
		if err != nil {
			return nil, fmt.Errorf("error creating dir: %v", err)
		}
		defer os.RemoveAll(layersOutputDir)
	}

	conversionStore := newConversionStore()

	// only compress individual layers if we're not squashing
	layerCompression := c.config.Compression
	if c.config.Squash {
		layerCompression = common.NoCompression
	}

	aciLayerPaths, aciManifests, err := c.backend.BuildACI(ancestry, manhash, parsedDockerURL, layersOutputDir, c.config.TmpDir, layerCompression)
	if err != nil {
		return nil, err
	}

	var images acirenderer.Images
	for i, aciLayerPath := range aciLayerPaths {
		key, err := conversionStore.WriteACI(aciLayerPath)
		if err != nil {
			return nil, fmt.Errorf("error inserting in the conversion store: %v", err)
		}

		images = append(images, acirenderer.Image{Im: aciManifests[i], Key: key, Level: uint16(len(aciLayerPaths) - 1 - i)})
	}

	// acirenderer expects images in order from upper to base layer
	images = util.ReverseImages(images)
	if c.config.Squash {
		squashedImagePath, err := squashLayers(images, conversionStore, *parsedDockerURL, c.config.OutputDir, c.config.Compression, c.config.Debug)
		if err != nil {
			return nil, fmt.Errorf("error squashing image: %v", err)
		}
		aciLayerPaths = []string{squashedImagePath}
	}

	return aciLayerPaths, nil
}

// squashLayers receives a list of ACI layer file names ordered from base image
// to application image and squashes them into one ACI
func squashLayers(images []acirenderer.Image, aciRegistry acirenderer.ACIRegistry, parsedDockerURL common.ParsedDockerURL, outputDir string, compression common.Compression, debug log.Logger) (path string, err error) {
	debug.Println("Squashing layers...")
	debug.Println("Rendering ACI...")
	renderedACI, err := acirenderer.GetRenderedACIFromList(images, aciRegistry)
	if err != nil {
		return "", fmt.Errorf("error rendering squashed image: %v", err)
	}
	manifests, err := getManifests(renderedACI, aciRegistry)
	if err != nil {
		return "", fmt.Errorf("error getting manifests: %v", err)
	}

	squashedFilename := getSquashedFilename(parsedDockerURL)
	squashedImagePath := filepath.Join(outputDir, squashedFilename)

	squashedTempFile, err := ioutil.TempFile(outputDir, "docker2aci-squashedFile-")
	if err != nil {
		return "", err
	}
	defer func() {
		if err == nil {
			err = squashedTempFile.Close()
		} else {
			// remove temp file on error
			// we ignore its error to not mask the real error
			os.Remove(squashedTempFile.Name())
		}
	}()

	debug.Println("Writing squashed ACI...")
	if err := writeSquashedImage(squashedTempFile, renderedACI, aciRegistry, manifests, compression); err != nil {
		return "", fmt.Errorf("error writing squashed image: %v", err)
	}

	debug.Println("Validating squashed ACI...")
	if err := internal.ValidateACI(squashedTempFile.Name()); err != nil {
		return "", fmt.Errorf("error validating image: %v", err)
	}

	if err := os.Rename(squashedTempFile.Name(), squashedImagePath); err != nil {
		return "", err
	}

	debug.Println("ACI squashed!")
	return squashedImagePath, nil
}

func getSquashedFilename(parsedDockerURL common.ParsedDockerURL) string {
	squashedFilename := strings.Replace(parsedDockerURL.ImageName, "/", "-", -1)
	if parsedDockerURL.Tag != "" {
		squashedFilename += "-" + parsedDockerURL.Tag
	}
	squashedFilename += ".aci"

	return squashedFilename
}

func getManifests(renderedACI acirenderer.RenderedACI, aciRegistry acirenderer.ACIRegistry) ([]schema.ImageManifest, error) {
	var manifests []schema.ImageManifest

	for _, aci := range renderedACI {
		im, err := aciRegistry.GetImageManifest(aci.Key)
		if err != nil {
			return nil, err
		}
		manifests = append(manifests, *im)
	}

	return manifests, nil
}

func writeSquashedImage(outputFile *os.File, renderedACI acirenderer.RenderedACI, aciProvider acirenderer.ACIProvider, manifests []schema.ImageManifest, compression common.Compression) error {
	var tarWriterTarget io.WriteCloser = outputFile

	switch compression {
	case common.NoCompression:
	case common.GzipCompression:
		tarWriterTarget = gzip.NewWriter(outputFile)
		defer tarWriterTarget.Close()
	default:
		return fmt.Errorf("unexpected compression enum value: %d", compression)
	}

	outputWriter := tar.NewWriter(tarWriterTarget)
	defer outputWriter.Close()

	finalManifest := mergeManifests(manifests)

	if err := internal.WriteManifest(outputWriter, finalManifest); err != nil {
		return err
	}

	if err := internal.WriteRootfsDir(outputWriter); err != nil {
		return err
	}

	type hardLinkEntry struct {
		firstLinkCleanName string
		firstLinkHeader    tar.Header
		keepOriginal       bool
		walked             bool
	}
	// map aciFileKey -> cleanTarget -> hardLinkEntry
	hardLinks := make(map[string]map[string]hardLinkEntry)

	// first pass: read all the entries and build the hardLinks map in memory
	// but don't write on disk
	for _, aciFile := range renderedACI {
		rs, err := aciProvider.ReadStream(aciFile.Key)
		if err != nil {
			return err
		}
		defer rs.Close()

		hardLinks[aciFile.Key] = map[string]hardLinkEntry{}

		squashWalker := func(t *tarball.TarFile) error {
			cleanName := filepath.Clean(t.Name())
			// the rootfs and the squashed manifest are added separately
			if cleanName == "manifest" || cleanName == "rootfs" {
				return nil
			}
			_, keep := aciFile.FileMap[cleanName]
			if keep && t.Header.Typeflag == tar.TypeLink {
				cleanTarget := filepath.Clean(t.Linkname())
				if _, ok := hardLinks[aciFile.Key][cleanTarget]; !ok {
					_, keepOriginal := aciFile.FileMap[cleanTarget]
					hardLinks[aciFile.Key][cleanTarget] = hardLinkEntry{cleanName, *t.Header, keepOriginal, false}
				}
			}
			return nil
		}

		tr := tar.NewReader(rs)
		if err := tarball.Walk(*tr, squashWalker); err != nil {
			return err
		}
	}

	// second pass: write on disk
	for _, aciFile := range renderedACI {
		rs, err := aciProvider.ReadStream(aciFile.Key)
		if err != nil {
			return err
		}
		defer rs.Close()

		squashWalker := func(t *tarball.TarFile) error {
			cleanName := filepath.Clean(t.Name())
			// the rootfs and the squashed manifest are added separately
			if cleanName == "manifest" || cleanName == "rootfs" {
				return nil
			}
			_, keep := aciFile.FileMap[cleanName]

			if link, ok := hardLinks[aciFile.Key][cleanName]; ok {
				if keep != link.keepOriginal {
					return fmt.Errorf("logic error: should we keep file %q?", cleanName)
				}
				if keep {
					if err := outputWriter.WriteHeader(t.Header); err != nil {
						return fmt.Errorf("error writing header: %v", err)
					}
					if _, err := io.Copy(outputWriter, t.TarStream); err != nil {
						return fmt.Errorf("error copying file into the tar out: %v", err)
					}
				} else {
					// The current file does not remain but there is a hard link pointing to
					// it. Write the current file but with the filename of the first hard link
					// pointing to it. That first hard link will not be written later, see
					// variable "alreadyWritten".
					link.firstLinkHeader.Size = t.Header.Size
					link.firstLinkHeader.Typeflag = t.Header.Typeflag
					link.firstLinkHeader.Linkname = ""

					if err := outputWriter.WriteHeader(&link.firstLinkHeader); err != nil {
						return fmt.Errorf("error writing header: %v", err)
					}
					if _, err := io.Copy(outputWriter, t.TarStream); err != nil {
						return fmt.Errorf("error copying file into the tar out: %v", err)
					}
				}
			} else if keep {
				alreadyWritten := false
				if t.Header.Typeflag == tar.TypeLink {
					cleanTarget := filepath.Clean(t.Linkname())
					if link, ok := hardLinks[aciFile.Key][cleanTarget]; ok {
						if !link.keepOriginal {
							if link.walked {
								t.Header.Linkname = link.firstLinkCleanName
							} else {
								alreadyWritten = true
							}
						}
						link.walked = true
						hardLinks[aciFile.Key][cleanTarget] = link
					}
				}

				if !alreadyWritten {
					if err := outputWriter.WriteHeader(t.Header); err != nil {
						return fmt.Errorf("error writing header: %v", err)
					}
					if _, err := io.Copy(outputWriter, t.TarStream); err != nil {
						return fmt.Errorf("error copying file into the tar out: %v", err)
					}
				}
			}
			return nil
		}

		tr := tar.NewReader(rs)
		if err := tarball.Walk(*tr, squashWalker); err != nil {
			return err
		}
	}

	return nil
}

func mergeManifests(manifests []schema.ImageManifest) schema.ImageManifest {
	// FIXME(iaguis) we take app layer's manifest as the final manifest for now
	manifest := manifests[0]

	manifest.Dependencies = nil

	layerIndex := -1
	for i, l := range manifest.Labels {
		if l.Name.String() == "layer" {
			layerIndex = i
		}
	}

	if layerIndex != -1 {
		manifest.Labels = append(manifest.Labels[:layerIndex], manifest.Labels[layerIndex+1:]...)
	}

	nameWithoutLayerID := appctypes.MustACIdentifier(stripLayerID(manifest.Name.String()))

	manifest.Name = *nameWithoutLayerID

	// once the image is squashed, we don't need a pathWhitelist
	manifest.PathWhitelist = nil

	return manifest
}

// striplayerID strips the layer ID from an app name:
//
// myregistry.com/organization/app-name-85738f8f9a7f1b04b5329c590ebcb9e425925c6d0984089c43a022de4f19c281
// myregistry.com/organization/app-name
func stripLayerID(layerName string) string {
	n := strings.LastIndex(layerName, "-")
	return layerName[:n]
}


================================================
FILE: lib/internal/backend/file/file.go
================================================
// Copyright 2015 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package file is an implementation of Docker2ACIBackend for files saved via
// "docker save".
//
// Note: this package is an implementation detail and shouldn't be used outside
// of docker2aci.
package file

import (
	"archive/tar"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"strings"

	"github.com/appc/docker2aci/lib/common"
	"github.com/appc/docker2aci/lib/internal"
	"github.com/appc/docker2aci/lib/internal/tarball"
	"github.com/appc/docker2aci/lib/internal/types"
	"github.com/appc/docker2aci/lib/internal/typesV2"
	"github.com/appc/docker2aci/pkg/log"
	"github.com/appc/spec/schema"
	spec "github.com/opencontainers/image-spec/specs-go/v1"
)

type FileBackend struct {
	file        *os.File
	debug, info log.Logger
}

func NewFileBackend(file *os.File, debug, info log.Logger) *FileBackend {
	return &FileBackend{
		file:  file,
		debug: debug,
		info:  info,
	}
}

// GetImageInfo, given the url for a docker image, will return the
// following:
// - []string: an ordered list of all layer hashes
// - string: a unique identifier for this image, like a hash of the manifest
// - *common.ParsedDockerURL: a parsed docker URL
// - error: an error if one occurred
func (lb *FileBackend) GetImageInfo(dockerURL string) ([]string, string, *common.ParsedDockerURL, error) {
	// a missing Docker URL could mean that the file only contains one
	// image so it's okay for dockerURL to be blank
	var parsedDockerURL *common.ParsedDockerURL
	if dockerURL != "" {
		var err error
		parsedDockerURL, err = common.ParseDockerURL(dockerURL)
		if err != nil {
			return nil, "", nil, fmt.Errorf("image provided couldnot be parsed: %v", err)
		}
	}

	var ancestry []string
	// default file name is the tar name stripped
	name := strings.Split(filepath.Base(lb.file.Name()), ".")[0]
	appImageID, ancestry, parsedDockerURL, err := getImageID(lb.file, parsedDockerURL, name, lb.debug)
	if err != nil {
		return nil, "", nil, err
	}

	if len(ancestry) == 0 {
		ancestry, err = getAncestry(lb.file, appImageID, lb.debug)
		if err != nil {
			return nil, "", nil, fmt.Errorf("error getting ancestry: %v", err)
		}
	} else {
		// for oci the first image is the config
		ancestry = append([]string{appImageID}, ancestry...)
	}

	return ancestry, appImageID, parsedDockerURL, nil
}

func (lb *FileBackend) BuildACI(layerIDs []string, manhash string, dockerURL *common.ParsedDockerURL, outputDir string, tmpBaseDir string, compression common.Compression) ([]string, []*schema.ImageManifest, error) {
	if strings.Contains(layerIDs[0], ":") {
		return lb.BuildACIV22(layerIDs, manhash, dockerURL, outputDir, tmpBaseDir, compression)
	}
	var aciLayerPaths []string
	var aciManifests []*schema.ImageManifest
	var curPwl []string

	tmpDir, err := ioutil.TempDir(tmpBaseDir, "docker2aci-")
	if err != nil {
		return nil, nil, fmt.Errorf("error creating dir: %v", err)
	}
	defer os.RemoveAll(tmpDir)

	for i := len(layerIDs) - 1; i >= 0; i-- {
		if err := common.ValidateLayerId(layerIDs[i]); err != nil {
			return nil, nil, err
		}
		j, err := getJson(lb.file, layerIDs[i])
		if err != nil {
			return nil, nil, fmt.Errorf("error getting layer json: %v", err)
		}

		layerData := types.DockerImageData{}
		if err := json.Unmarshal(j, &layerData); err != nil {
			return nil, nil, fmt.Errorf("error unmarshaling layer data: %v", err)
		}

		tmpLayerPath := path.Join(tmpDir, layerIDs[i])
		tmpLayerPath += ".tar"

		layerTarPath := path.Join(layerIDs[i], "layer.tar")
		layerFile, err := extractEmbeddedLayer(lb.file, layerTarPath, tmpLayerPath, lb.info)
		if err != nil {
			return nil, nil, fmt.Errorf("error getting layer from file: %v", err)
		}
		defer layerFile.Close()

		lb.debug.Println("Generating layer ACI...")
		aciPath, manifest, err := internal.GenerateACI(i, manhash, layerData, dockerURL, outputDir, layerFile, curPwl, compression, lb.debug)
		if err != nil {
			return nil, nil, fmt.Errorf("error generating ACI: %v", err)
		}

		aciLayerPaths = append(aciLayerPaths, aciPath)
		aciManifests = append(aciManifests, manifest)
		curPwl = manifest.PathWhitelist
	}

	return aciLayerPaths, aciManifests, nil
}

func (lb *FileBackend) BuildACIV22(layerIDs []string, manhash string, dockerURL *common.ParsedDockerURL, outputDir string, tmpBaseDir string, compression common.Compression) ([]string, []*schema.ImageManifest, error) {
	if len(layerIDs) < 2 {
		return nil, nil, fmt.Errorf("insufficient layers for oci image")
	}
	var aciLayerPaths []string
	var aciManifests []*schema.ImageManifest
	var curPwl []string

	imageID := layerIDs[0]
	layerIDs = layerIDs[1:]

	j, err := getJsonV22(lb.file, imageID)
	if err != nil {
		return nil, nil, fmt.Errorf("error getting layer from file: %v", err)
	}
	imageConfig := typesV2.ImageConfig{}
	if err := json.Unmarshal(j, &imageConfig); err != nil {
		return nil, nil, fmt.Errorf("error unmarshaling image data: %v", err)
	}

	tmpDir, err := ioutil.TempDir(tmpBaseDir, "docker2aci-")
	if err != nil {
		return nil, nil, fmt.Errorf("error creating dir: %v", err)
	}
	defer os.RemoveAll(tmpDir)
	for i := len(layerIDs) - 1; i >= 0; i-- {
		parts := strings.Split(layerIDs[i], ":")
		tmpLayerPath := path.Join(tmpDir, parts[1])
		tmpLayerPath += ".tar"
		layerTarPath := path.Join(append([]string{"blobs"}, parts...)...)
		layerFile, err := extractEmbeddedLayer(lb.file, layerTarPath, tmpLayerPath, lb.info)
		if err != nil {
			return nil, nil, fmt.Errorf("error getting layer from file: %v", err)
		}
		defer layerFile.Close()
		lb.debug.Println("Generating layer ACI...")
		var aciPath string
		var manifest *schema.ImageManifest
		if i != 0 {
			aciPath, manifest, err = internal.GenerateACI22LowerLayer(dockerURL, parts[1], outputDir, layerFile, curPwl, compression)
		} else {
			aciPath, manifest, err = internal.GenerateACI22TopLayer(dockerURL, manhash, &imageConfig, parts[1], outputDir, layerFile, curPwl, compression, aciManifests, lb.debug)
		}
		if err != nil {
			return nil, nil, fmt.Errorf("error generating ACI: %v", err)
		}

		aciLayerPaths = append(aciLayerPaths, aciPath)
		aciManifests = append(aciManifests, manifest)
		curPwl = manifest.PathWhitelist
	}

	return aciLayerPaths, aciManifests, nil
}

func getImageID(file *os.File, dockerURL *common.ParsedDockerURL, name string, debug log.Logger) (string, []string, *common.ParsedDockerURL, error) {
	debug.Println("getting image id...")
	type tags map[string]string
	type apps map[string]tags

	_, err := file.Seek(0, 0)
	if err != nil {
		return "", nil, nil, fmt.Errorf("error seeking file: %v", err)
	}

	tag := "latest"
	if dockerURL != nil {
		tag = dockerURL.Tag
	}

	var imageID string
	var ancestry []string
	var appName string
	reposWalker := func(t *tarball.TarFile) error {
		clean := filepath.Clean(t.Name())
		if clean == "repositories" {
			repob, err := ioutil.ReadAll(t.TarStream)
			if err != nil {
				return fmt.Errorf("error reading repositories file: %v", err)
			}

			var unparsedRepositories apps
			if err := json.Unmarshal(repob, &unparsedRepositories); err != nil {
				return fmt.Errorf("error unmarshaling repositories file")
			}

			repositories := make(apps, 0)
			// Normalize repository keys since the image potentially passed in is
			// normalized
			for key, val := range unparsedRepositories {
				parsed, err := common.ParseDockerURL(key)
				if err != nil {
					return fmt.Errorf("error parsing key %q in repositories: %v", key, err)
				}
				repositories[parsed.ImageName] = val
			}

			if dockerURL == nil {
				n := len(repositories)
				switch {
				case n == 1:
					for key, _ := range repositories {
						appName = key
					}
				case n > 1:
					var appNames []string
					for key, _ := range repositories {
						appNames = append(appNames, key)
					}
					return &common.ErrSeveralImages{
						Msg:    "several images found",
						Images: appNames,
					}
				default:
					return fmt.Errorf("no images found")
				}
			} else {
				appName = dockerURL.ImageName
			}

			app, ok := repositories[appName]
			if !ok {
				return fmt.Errorf("app %q not found", appName)
			}

			_, ok = app[tag]
			if !ok {
				if len(app) == 1 {
					for key, _ := range app {
						tag = key
					}
				} else {
					return fmt.Errorf("tag %q not found", tag)
				}
			}

			if dockerURL == nil {
				dockerURL = &common.ParsedDockerURL{
					OriginalName: "",
					IndexURL:     "",
					Tag:          tag,
					ImageName:    appName,
				}
			}

			imageID = string(app[tag])
		}

		if clean == "refs/"+tag {
			refb, err := ioutil.ReadAll(t.TarStream)
			if err != nil {
				return fmt.Errorf("error reading ref descriptor for tag %s: %v", tag, err)
			}

			if dockerURL == nil {
				dockerURL = &common.ParsedDockerURL{
					IndexURL:  "",
					Tag:       tag,
					ImageName: name,
				}
			}

			var ref spec.Descriptor
			if err := json.Unmarshal(refb, &ref); err != nil {
				return fmt.Errorf("error unmarshaling ref descriptor for tag %s", tag)
			}
			imageID, ancestry, err = getDataFromManifest(file, ref.Digest)
			if err != nil {
				return err
			}
			return io.EOF
		}
		return nil
	}

	tr := tar.NewReader(file)
	if err := tarball.Walk(*tr, reposWalker); err != nil && err != io.EOF {
		return "", nil, nil, err
	}

	if imageID == "" {
		return "", nil, nil, fmt.Errorf("Could not find image")
	}

	return imageID, ancestry, dockerURL, nil
}

func getDataFromManifest(file *os.File, manifestID string) (string, []string, error) {
	_, err := file.Seek(0, 0)
	if err != nil {
		return "", nil, fmt.Errorf("error seeking file: %v", err)
	}

	parts := append([]string{"blobs"}, strings.Split(manifestID, ":")...)
	jsonPath := path.Join(parts...)

	var imageID string
	var ancestry []string
	reposWalker := func(t *tarball.TarFile) error {
		clean := filepath.Clean(t.Name())
		if clean == jsonPath {

			manb, err := ioutil.ReadAll(t.TarStream)
			if err != nil {
				return fmt.Errorf("error reading image manifest: %v", err)
			}

			var manifest typesV2.ImageManifest
			if err := json.Unmarshal(manb, &manifest); err != nil {
				return fmt.Errorf("error unmarshaling image manifest")
			}
			if manifest.Config == nil {
				return fmt.Errorf("manifest does not contain a config")
			}
			imageID = manifest.Config.Digest
			// put them in reverse order
			for i := len(manifest.Layers) - 1; i >= 0; i-- {
				ancestry = append(ancestry, manifest.Layers[i].Digest)
			}
		}
		return nil
	}

	tr := tar.NewReader(file)
	if err := tarball.Walk(*tr, reposWalker); err != nil {
		return "", nil, err
	}

	return imageID, ancestry, nil
}

func getJson(file *os.File, layerID string) ([]byte, error) {
	jsonPath := path.Join(layerID, "json")
	return getTarFileBytes(file, jsonPath)
}

func getJsonV22(file *os.File, layerID string) ([]byte, error) {
	parts := append([]string{"blobs"}, strings.Split(layerID, ":")...)
	jsonPath := path.Join(parts...)
	return getTarFileBytes(file, jsonPath)
}

func getTarFileBytes(file *os.File, path string) ([]byte, error) {
	_, err := file.Seek(0, 0)
	if err != nil {
		return nil, fmt.Errorf("error seeking file: %v", err)
	}

	var fileBytes []byte
	fileWalker := func(t *tarball.TarFile) error {
		if filepath.Clean(t.Name()) == path {
			fileBytes, err = ioutil.ReadAll(t.TarStream)
			if err != nil {
				return err
			}
		}

		return nil
	}

	tr := tar.NewReader(file)
	if err := tarball.Walk(*tr, fileWalker); err != nil {
		return nil, err
	}

	if fileBytes == nil {
		return nil, fmt.Errorf("file %q not found", path)
	}

	return fileBytes, nil
}

func extractEmbeddedLayer(file *os.File, layerTarPath string, outputPath string, info log.Logger) (*os.File, error) {
	info.Println("Extracting ", layerTarPath)
	_, err := file.Seek(0, 0)
	if err != nil {
		return nil, fmt.Errorf("error seeking file: %v", err)
	}

	var layerFile *os.File
	fileWalker := func(t *tarball.TarFile) error {
		if filepath.Clean(t.Name()) == layerTarPath {
			layerFile, err = os.Create(outputPath)
			if err != nil {
				return fmt.Errorf("error creating layer: %v", err)
			}

			_, err = io.Copy(layerFile, t.TarStream)
			if err != nil {
				return fmt.Errorf("error getting layer: %v", err)
			}
		}

		return nil
	}

	tr := tar.NewReader(file)
	if err := tarball.Walk(*tr, fileWalker); err != nil {
		return nil, err
	}

	if layerFile == nil {
		return nil, fmt.Errorf("file %q not found", layerTarPath)
	}

	return layerFile, nil
}

// getAncestry computes an image ancestry, returning an ordered list
// of dependencies starting from the topmost image to the base.
// It checks for dependency loops via duplicate detection in the image
// chain and errors out in such cases.
func getAncestry(file *os.File, imgID string, debug log.Logger) ([]string, error) {
	var ancestry []string
	deps := make(map[string]bool)

	curImgID := imgID

	var err error
	for curImgID != "" {
		if deps[curImgID] {
			return nil, fmt.Errorf("dependency loop detected at image %q", curImgID)
		}
		deps[curImgID] = true
		ancestry = append(ancestry, curImgID)
		debug.Printf("Getting ancestry for layer %q", curImgID)
		curImgID, err = getParent(file, curImgID, debug)
		if err != nil {
			return nil, err
		}
	}
	return ancestry, nil
}

func getParent(file *os.File, imgID string, debug log.Logger) (string, error) {
	var parent string

	_, err := file.Seek(0, 0)
	if err != nil {
		return "", fmt.Errorf("error seeking file: %v", err)
	}

	jsonPath := filepath.Join(imgID, "json")
	parentWalker := func(t *tarball.TarFile) error {
		if filepath.Clean(t.Name()) == jsonPath {
			jsonb, err := ioutil.ReadAll(t.TarStream)
			if err != nil {
				return fmt.Errorf("error reading layer json: %v", err)
			}

			var dockerData types.DockerImageData
			if err := json.Unmarshal(jsonb, &dockerData); err != nil {
				return fmt.Errorf("error unmarshaling layer data: %v", err)
			}

			parent = dockerData.Parent
		}

		return nil
	}

	tr := tar.NewReader(file)
	if err := tarball.Walk(*tr, parentWalker); err != nil {
		return "", err
	}

	debug.Printf("Layer %q depends on layer %q", imgID, parent)
	return parent, nil
}


================================================
FILE: lib/internal/backend/repository/repository.go
================================================
// Copyright 2015 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package repository is an implementation of Docker2ACIBackend for Docker
// remote registries.
//
// Note: this package is an implementation detail and shouldn't be used outside
// of docker2aci.
package repository

import (
	"fmt"
	"net/http"
	"net/url"

	"github.com/appc/docker2aci/lib/common"
	"github.com/appc/docker2aci/lib/internal/typesV2"
	"github.com/appc/docker2aci/lib/internal/util"
	"github.com/appc/docker2aci/pkg/log"
	"github.com/appc/spec/schema"
)

type registryVersion int

const (
	registryV1 registryVersion = iota
	registryV2
)

type httpStatusErr struct {
	StatusCode int
	URL        *url.URL
}

func (e httpStatusErr) Error() string {
	return fmt.Sprintf("Unexpected HTTP code: %d, URL: %s", e.StatusCode, e.URL.String())
}

func isErrHTTP404(err error) bool {
	if httperr, ok := err.(*httpStatusErr); ok && httperr.StatusCode == http.StatusNotFound {
		return true
	}
	return false
}

type RepositoryBackend struct {
	repoData          *RepoData
	username          string
	password          string
	insecure          common.InsecureConfig
	hostsV1fallback   bool
	hostsV2Support    map[string]bool
	hostsV2AuthTokens map[string]map[string]string
	schema            string
	imageManifests    map[common.ParsedDockerURL]v2Manifest
	imageV2Manifests  map[common.ParsedDockerURL]*typesV2.ImageManifest
	imageConfigs      map[common.ParsedDockerURL]*typesV2.ImageConfig
	layersIndex       map[string]int
	mediaTypes        common.MediaTypeSet
	registryOptions   common.RegistryOptionSet

	debug log.Logger
}

func NewRepositoryBackend(username, password string, insecure common.InsecureConfig, debug log.Logger, mediaTypes common.MediaTypeSet, registryOptions common.RegistryOptionSet) *RepositoryBackend {
	return &RepositoryBackend{
		username:          username,
		password:          password,
		insecure:          insecure,
		hostsV1fallback:   false,
		hostsV2Support:    make(map[string]bool),
		hostsV2AuthTokens: make(map[string]map[string]string),
		imageManifests:    make(map[common.ParsedDockerURL]v2Manifest),
		imageV2Manifests:  make(map[common.ParsedDockerURL]*typesV2.ImageManifest),
		imageConfigs:      make(map[common.ParsedDockerURL]*typesV2.ImageConfig),
		layersIndex:       make(map[string]int),
		mediaTypes:        mediaTypes,
		registryOptions:   registryOptions,
		debug:             debug,
	}
}

// GetImageInfo, given the url for a docker image, will return the
// following:
// - []string: an ordered list of all layer hashes
// - string: a unique identifier for this image, like a hash of the manifest
// - *common.ParsedDockerURL: a parsed docker URL
// - error: an error if one occurred
func (rb *RepositoryBackend) GetImageInfo(url string) ([]string, string, *common.ParsedDockerURL, error) {
	dockerURL, err := common.ParseDockerURL(url)
	if err != nil {
		return nil, "", nil, err
	}

	var supportsV2, supportsV1, ok bool
	var URLSchema string

	if supportsV2, ok = rb.hostsV2Support[dockerURL.IndexURL]; !ok {
		var err error
		URLSchema, supportsV2, err = rb.supportsRegistry(dockerURL.IndexURL, registryV2)
		if err != nil {
			return nil, "", nil, err
		}
		rb.schema = URLSchema + "://"
		rb.hostsV2Support[dockerURL.IndexURL] = supportsV2
	}

	// try v2
	if supportsV2 && rb.registryOptions.AllowsV2() {
		layers, manhash, dockerURL, err := rb.getImageInfoV2(dockerURL)
		if !isErrHTTP404(err) {
			return layers, manhash, dockerURL, err
		}
		// fallback on 404 failure
		rb.hostsV1fallback = true
		// unless we can't fallback
		if !rb.registryOptions.AllowsV1() {
			return nil, "", nil, err
		}
	}

	if !rb.registryOptions.AllowsV1() {
		return nil, "", nil, fmt.Errorf("no remaining enabled registry options")
	}

	URLSchema, supportsV1, err = rb.supportsRegistry(dockerURL.IndexURL, registryV1)
	if err != nil {
		return nil, "", nil, err
	}
	if !supportsV1 && rb.hostsV1fallback {
		return nil, "", nil, fmt.Errorf("attempted fallback to API v1 but not supported")
	}
	if !supportsV1 && !supportsV2 {
		return nil, "", nil, fmt.Errorf("registry doesn't support API v2 nor v1")
	}
	rb.schema = URLSchema + "://"
	// try v1, hard fail on failure
	return rb.getImageInfoV1(dockerURL)
}

func (rb *RepositoryBackend) BuildACI(layerIDs []string, manhash string, dockerURL *common.ParsedDockerURL, outputDir string, tmpBaseDir string, compression common.Compression) ([]string, []*schema.ImageManifest, error) {
	if rb.hostsV1fallback || !rb.hostsV2Support[dockerURL.IndexURL] {
		return rb.buildACIV1(layerIDs, manhash, dockerURL, outputDir, tmpBaseDir, compression)
	} else {
		return rb.buildACIV2(layerIDs, manhash, dockerURL, outputDir, tmpBaseDir, compression)
	}
}

// checkRegistryStatus determines registry API version compatibility according to spec:
// https://docs.docker.com/registry/spec/api/#/api-version-check
func checkRegistryStatus(statusCode int, hdr http.Header, version registryVersion) (bool, error) {
	switch statusCode {
	case http.StatusOK, http.StatusUnauthorized:
		ok := true
		if version == registryV2 {
			// According to v2 spec, registries SHOULD set this header value
			// and clients MAY fallback to v1 if missing, as done here.
			ok = hdr.Get("Docker-Distribution-API-Version") == "registry/2.0"
		}
		return ok, nil
	}
	return false, nil
}

func (rb *RepositoryBackend) supportsRegistry(indexURL string, version registryVersion) (schema string, ok bool, err error) {
	var URLPath string
	switch version {
	case registryV1:
		URLPath = "v1/_ping"
	case registryV2:
		URLPath = "v2/"
	}

	fetch := func(schema string) (res *http.Response, err error) {
		u := url.URL{Scheme: schema, Host: indexURL, Path: URLPath}
		req, err := http.NewRequest("GET", u.String(), nil)
		if err != nil {
			return nil, err
		}

		rb.setBasicAuth(req)

		client := util.GetTLSClient(rb.insecure.SkipVerify)
		res, err = client.Do(req)
		return
	}

	schema = "https"
	res, err := fetch(schema)
	if err == nil {
		ok, err = checkRegistryStatus(res.StatusCode, res.Header, version)
		defer res.Body.Close()
	}
	if err != nil || !ok {
		if rb.insecure.AllowHTTP {
			schema = "http"
			res, err = fetch(schema)
			if err == nil {
				ok, err = checkRegistryStatus(res.StatusCode, res.Header, version)
				defer res.Body.Close()
			}
		}
		return schema, ok, err
	}

	return schema, ok, err
}


================================================
FILE: lib/internal/backend/repository/repository1.go
================================================
// Copyright 2015 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package repository

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"path"
	"strconv"
	"strings"
	"time"

	"github.com/appc/docker2aci/lib/common"
	"github.com/appc/docker2aci/lib/internal"
	"github.com/appc/docker2aci/lib/internal/types"
	"github.com/appc/docker2aci/lib/internal/util"
	"github.com/appc/spec/schema"
	"github.com/coreos/ioprogress"
)

type RepoData struct {
	Tokens    []string
	Endpoints []string
	Cookie    []string
}

func (rb *RepositoryBackend) getImageInfoV1(dockerURL *common.ParsedDockerURL) ([]string, string, *common.ParsedDockerURL, error) {
	repoData, err := rb.getRepoDataV1(dockerURL.IndexURL, dockerURL.ImageName)
	if err != nil {
		return nil, "", nil, fmt.Errorf("error getting repository data: %v", err)
	}

	// TODO(iaguis) check more endpoints
	appImageID, err := rb.getImageIDFromTagV1(repoData.Endpoints[0], dockerURL.ImageName, dockerURL.Tag, repoData)
	if err != nil {
		return nil, "", nil, fmt.Errorf("error getting ImageID from tag %s: %v", dockerURL.Tag, err)
	}

	ancestry, err := rb.getAncestryV1(appImageID, repoData.Endpoints[0], repoData)
	if err != nil {
		return nil, "", nil, err
	}

	rb.repoData = repoData

	return ancestry, appImageID, dockerURL, nil
}

func (rb *RepositoryBackend) buildACIV1(layerIDs []string, manhash string, dockerURL *common.ParsedDockerURL, outputDir string, tmpBaseDir string, compression common.Compression) ([]string, []*schema.ImageManifest, error) {
	layerFiles := make([]*os.File, len(layerIDs))
	layerDatas := make([]types.DockerImageData, len(layerIDs))

	tmpParentDir, err := ioutil.TempDir(tmpBaseDir, "docker2aci-")
	if err != nil {
		return nil, nil, err
	}
	defer os.RemoveAll(tmpParentDir)

	var doneChannels []chan error
	for i, layerID := range layerIDs {
		if err := common.ValidateLayerId(layerID); err != nil {
			return nil, nil, err
		}
		doneChan := make(chan error)
		doneChannels = append(doneChannels, doneChan)
		// https://github.com/golang/go/wiki/CommonMistakes
		i := i // golang--
		layerID := layerID
		go func() {
			tmpDir, err := ioutil.TempDir(tmpParentDir, "")
			if err != nil {
				doneChan <- fmt.Errorf("error creating dir: %v", err)
				return
			}

			j, size, err := rb.getJsonV1(layerID, rb.repoData.Endpoints[0], rb.repoData)
			if err != nil {
				doneChan <- fmt.Errorf("error getting image json: %v", err)
				return
			}

			layerDatas[i] = types.DockerImageData{}
			if err := json.Unmarshal(j, &layerDatas[i]); err != nil {
				doneChan <- fmt.Errorf("error unmarshaling layer data: %v", err)
				return
			}

			layerFiles[i], err = rb.getLayerV1(layerID, rb.repoData.Endpoints[0], rb.repoData, size, tmpDir)
			if err != nil {
				doneChan <- fmt.Errorf("error getting the remote layer: %v", err)
				return
			}
			doneChan <- nil
		}()
	}
	for _, doneChan := range doneChannels {
		err := <-doneChan
		if err != nil {
			return nil, nil, err
		}
	}
	var aciLayerPaths []string
	var aciManifests []*schema.ImageManifest
	var curPwl []string

	for i := len(layerIDs) - 1; i >= 0; i-- {
		rb.debug.Println("Generating layer ACI...")
		aciPath, manifest, err := internal.GenerateACI(i, manhash, layerDatas[i], dockerURL, outputDir, layerFiles[i], curPwl, compression, rb.debug)
		if err != nil {
			return nil, nil, fmt.Errorf("error generating ACI: %v", err)
		}
		aciLayerPaths = append(aciLayerPaths, aciPath)
		aciManifests = append(aciManifests, manifest)
		curPwl = manifest.PathWhitelist

		layerFiles[i].Close()
	}

	return aciLayerPaths, aciManifests, nil
}

func (rb *RepositoryBackend) getRepoDataV1(indexURL string, remote string) (*RepoData, error) {
	client := util.GetTLSClient(rb.insecure.SkipVerify)
	repositoryURL := rb.schema + path.Join(indexURL, "v1", "repositories", remote, "images")

	req, err := http.NewRequest("GET", repositoryURL, nil)
	if err != nil {
		return nil, err
	}

	if rb.username != "" && rb.password != "" {
		req.SetBasicAuth(rb.username, rb.password)
	}

	req.Header.Set("X-Docker-Token", "true")

	res, err := client.Do(req)
	if err != nil {
		return nil, err
	}
	defer res.Body.Close()

	if res.StatusCode != 200 {
		return nil, &httpStatusErr{res.StatusCode, req.URL}
	}

	var tokens []string
	if res.Header.Get("X-Docker-Token") != "" {
		tokens = res.Header["X-Docker-Token"]
	}

	var cookies []string
	if res.Header.Get("Set-Cookie") != "" {
		cookies = res.Header["Set-Cookie"]
	}

	var endpoints []string
	if res.Header.Get("X-Docker-Endpoints") != "" {
		endpoints = makeEndpointsListV1(res.Header["X-Docker-Endpoints"])
	} else {
		// Assume same endpoint
		endpoints = append(endpoints, indexURL)
	}

	return &RepoData{
		Endpoints: endpoints,
		Tokens:    tokens,
		Cookie:    cookies,
	}, nil
}

func (rb *RepositoryBackend) getImageIDFromTagV1(registry string, appName string, tag string, repoData *RepoData) (string, error) {
	client := util.GetTLSClient(rb.insecure.SkipVerify)
	// we get all the tags instead of directly getting the imageID of the
	// requested one (.../tags/TAG) because even though it's specified in the
	// Docker API, some registries (e.g. Google Container Registry) don't
	// implement it.
	req, err := http.NewRequest("GET", rb.schema+path.Join(registry, "repositories", appName, "tags"), nil)
	if err != nil {
		return "", fmt.Errorf("failed to get Image ID: %s, URL: %s", err, req.URL)
	}

	setAuthTokenV1(req, repoData.Tokens)
	setCookieV1(req, repoData.Cookie)
	res, err := client.Do(req)
	if err != nil {
		return "", fmt.Errorf("failed to get Image ID: %s, URL: %s", err, req.URL)
	}
	defer res.Body.Close()

	if res.StatusCode != 200 {
		return "", &httpStatusErr{res.StatusCode, req.URL}
	}

	j, err := ioutil.ReadAll(res.Body)

	if err != nil {
		return "", err
	}

	var tags map[string]string

	if err := json.Unmarshal(j, &tags); err != nil {
		return "", fmt.Errorf("error unmarshaling: %v", err)
	}

	imageID, ok := tags[tag]
	if !ok {
		return "", fmt.Errorf("tag %s not found", tag)
	}

	return imageID, nil
}

func (rb *RepositoryBackend) getAncestryV1(imgID, registry string, repoData *RepoData) ([]string, error) {
	client := util.GetTLSClient(rb.insecure.SkipVerify)
	req, err := http.NewRequest("GET", rb.schema+path.Join(registry, "images", imgID, "ancestry"), nil)
	if err != nil {
		return nil, err
	}

	setAuthTokenV1(req, repoData.Tokens)
	setCookieV1(req, repoData.Cookie)
	res, err := client.Do(req)
	if err != nil {
		return nil, err
	}
	defer res.Body.Close()

	if res.StatusCode != 200 {
		return nil, &httpStatusErr{res.StatusCode, req.URL}
	}

	var ancestry []string

	j, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return nil, fmt.Errorf("Failed to read downloaded json: %s (%s)", err, j)
	}

	if err := json.Unmarshal(j, &ancestry); err != nil {
		return nil, fmt.Errorf("error unmarshaling: %v", err)
	}

	return ancestry, nil
}

func (rb *RepositoryBackend) getJsonV1(imgID, registry string, repoData *RepoData) ([]byte, int64, error) {
	client := util.GetTLSClient(rb.insecure.SkipVerify)
	req, err := http.NewRequest("GET", rb.schema+path.Join(registry, "images", imgID, "json"), nil)
	if err != nil {
		return nil, -1, err
	}
	setAuthTokenV1(req, repoData.Tokens)
	setCookieV1(req, repoData.Cookie)
	res, err := client.Do(req)
	if err != nil {
		return nil, -1, err
	}
	defer res.Body.Close()

	if res.StatusCode != 200 {
		return nil, -1, &httpStatusErr{res.StatusCode, req.URL}
	}

	imageSize := int64(-1)

	if hdr := res.Header.Get("X-Docker-Size"); hdr != "" {
		imageSize, err = strconv.ParseInt(hdr, 10, 64)
		if err != nil {
			return nil, -1, err
		}
	}

	b, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return nil, -1, fmt.Errorf("failed to read downloaded json: %v (%s)", err, b)
	}

	return b, imageSize, nil
}

func (rb *RepositoryBackend) getLayerV1(imgID, registry string, repoData *RepoData, imgSize int64, tmpDir string) (*os.File, error) {
	client := util.GetTLSClient(rb.insecure.SkipVerify)
	req, err := http.NewRequest("GET", rb.schema+path.Join(registry, "images", imgID, "layer"), nil)
	if err != nil {
		return nil, err
	}

	setAuthTokenV1(req, repoData.Tokens)
	setCookieV1(req, repoData.Cookie)

	res, err := client.Do(req)
	if err != nil {
		return nil, err
	}
	defer res.Body.Close()

	if res.StatusCode != 200 {
		res.Body.Close()
		return nil, &httpStatusErr{res.StatusCode, req.URL}
	}

	// if we didn't receive the size via X-Docker-Size when we retrieved the
	// layer's json, try Content-Length
	if imgSize == -1 {
		if hdr := res.Header.Get("Content-Length"); hdr != "" {
			imgSize, err = strconv.ParseInt(hdr, 10, 64)
			if err != nil {
				return nil, err
			}
		}
	}

	prefix := "Downloading " + imgID[:12]
	fmtBytesSize := 18
	barSize := int64(80 - len(prefix) - fmtBytesSize)
	bar := ioprogress.DrawTextFormatBarForW(barSize, os.Stderr)
	fmtfunc := func(progress, total int64) string {
		return fmt.Sprintf(
			"%s: %s %s",
			prefix,
			bar(progress, total),
			ioprogress.DrawTextFormatBytes(progress, total),
		)
	}

	progressReader := &ioprogress.Reader{
		Reader:       res.Body,
		Size:         imgSize,
		DrawFunc:     ioprogress.DrawTerminalf(os.Stderr, fmtfunc),
		DrawInterval: 500 * time.Millisecond,
	}

	layerFile, err := ioutil.TempFile(tmpDir, "dockerlayer-")
	if err != nil {
		return nil, err
	}

	_, err = io.Copy(layerFile, progressReader)
	if err != nil {
		return nil, err
	}

	if err := layerFile.Sync(); err != nil {
		return nil, err
	}

	return layerFile, nil
}

func setAuthTokenV1(req *http.Request, token []string) {
	if req.Header.Get("Authorization") == "" {
		req.Header.Set("Authorization", "Token "+strings.Join(token, ","))
	}
}

func setCookieV1(req *http.Request, cookie []string) {
	if req.Header.Get("Cookie") == "" {
		req.Header.Set("Cookie", strings.Join(cookie, ""))
	}
}

func makeEndpointsListV1(headers []string) []string {
	var endpoints []string

	for _, ep := range headers {
		endpointsList := strings.Split(ep, ",")
		for _, endpointEl := range endpointsList {
			endpoints = append(
				endpoints,
				path.Join(strings.TrimSpace(endpointEl), "v1"))
		}
	}

	return endpoints
}


================================================
FILE: lib/internal/backend/repository/repository2.go
================================================
// Copyright 2016 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package repository

import (
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"path"
	"strconv"
	"strings"
	"sync"
	"time"

	"github.com/appc/docker2aci/lib/common"
	"github.com/appc/docker2aci/lib/internal"
	"github.com/appc/docker2aci/lib/internal/types"
	"github.com/appc/docker2aci/lib/internal/typesV2"
	"github.com/appc/docker2aci/lib/internal/util"
	"github.com/appc/spec/schema"
	"github.com/coreos/pkg/progressutil"
	godigest "github.com/opencontainers/go-digest"
)

const (
	defaultIndexURL = "registry-1.docker.io"
)

// A manifest conforming to the docker v2.1 spec
type v2Manifest struct {
	Name     string `json:"name"`
	Tag      string `json:"tag"`
	FSLayers []struct {
		BlobSum string `json:"blobSum"`
	} `json:"fsLayers"`
	History []struct {
		V1Compatibility string `json:"v1Compatibility"`
	} `json:"history"`
	Signature []byte `json:"signature"`
}

func (rb *RepositoryBackend) getImageInfoV2(dockerURL *common.ParsedDockerURL) ([]string, string, *common.ParsedDockerURL, error) {
	layers, manhash, err := rb.getManifestV2(dockerURL)
	if err != nil {
		return nil, "", nil, err
	}

	return layers, manhash, dockerURL, nil
}

func (rb *RepositoryBackend) buildACIV2(layerIDs []string, manhash string, dockerURL *common.ParsedDockerURL, outputDir string, tmpBaseDir string, compression common.Compression) ([]string, []*schema.ImageManifest, error) {
	_, isVersion22 := rb.imageV2Manifests[*dockerURL]
	if isVersion22 {
		return rb.buildACIV22(layerIDs, manhash, dockerURL, outputDir, tmpBaseDir, compression)
	}
	return rb.buildACIV21(layerIDs, manhash, dockerURL, outputDir, tmpBaseDir, compression)
}

func (rb *RepositoryBackend) buildACIV21(layerIDs []string, manhash string, dockerURL *common.ParsedDockerURL, outputDir string, tmpBaseDir string, compression common.Compression) ([]string, []*schema.ImageManifest, error) {
	layerFiles := make([]*os.File, len(layerIDs))
	layerDatas := make([]types.DockerImageData, len(layerIDs))

	tmpParentDir, err := ioutil.TempDir(tmpBaseDir, "docker2aci-")
	if err != nil {
		return nil, nil, err
	}
	defer os.RemoveAll(tmpParentDir)

	copier := progressutil.NewCopyProgressPrinter()

	var errChannels []chan error
	closers := make([]io.ReadCloser, len(layerIDs))
	var wg sync.WaitGroup
	for i, layerID := range layerIDs {
		if err := common.ValidateLayerId(layerID); err != nil {
			return nil, nil, err
		}
		wg.Add(1)
		errChan := make(chan error, 1)
		errChannels = append(errChannels, errChan)
		// https://github.com/golang/go/wiki/CommonMistakes
		i := i // golang--
		layerID := layerID
		go func() {
			defer wg.Done()

			manifest := rb.imageManifests[*dockerURL]

			layerIndex, ok := rb.layersIndex[layerID]
			if !ok {
				errChan <- fmt.Errorf("layer not found in manifest: %s", layerID)
				return
			}

			if len(manifest.History) <= layerIndex {
				errChan <- fmt.Errorf("history not found for layer %s", layerID)
				return
			}

			layerDatas[i] = types.DockerImageData{}
			if err := json.Unmarshal([]byte(manifest.History[layerIndex].V1Compatibility), &layerDatas[i]); err != nil {
				errChan <- fmt.Errorf("error unmarshaling layer data: %v", err)
				return
			}

			tmpDir, err := ioutil.TempDir(tmpParentDir, "")
			if err != nil {
				errChan <- fmt.Errorf("error creating dir: %v", err)
				return
			}

			layerFiles[i], closers[i], err = rb.getLayerV2(layerID, dockerURL, tmpDir, copier)
			if err != nil {
				errChan <- fmt.Errorf("error getting the remote layer: %v", err)
				return
			}
			errChan <- nil
		}()
	}
	// Need to wait for all of the readers to be added to the copier (which happens during rb.getLayerV2)
	wg.Wait()
	err = copier.PrintAndWait(os.Stderr, 500*time.Millisecond, nil)
	if err != nil {
		return nil, nil, err
	}
	for _, closer := range closers {
		if closer != nil {
			closer.Close()
		}
	}
	for _, errChan := range errChannels {
		err := <-errChan
		if err != nil {
			return nil, nil, err
		}
	}
	for _, layerFile := range layerFiles {
		err := layerFile.Sync()
		if err != nil {
			return nil, nil, err
		}
	}
	var aciLayerPaths []string
	var aciManifests []*schema.ImageManifest
	var curPwl []string
	for i := len(layerIDs) - 1; i >= 0; i-- {
		rb.debug.Println("Generating layer ACI...")
		aciPath, aciManifest, err := internal.GenerateACI(i, manhash, layerDatas[i], dockerURL, outputDir, layerFiles[i], curPwl, compression, rb.debug)
		if err != nil {
			return nil, nil, fmt.Errorf("error generating ACI: %v", err)
		}
		aciLayerPaths = append(aciLayerPaths, aciPath)
		aciManifests = append(aciManifests, aciManifest)
		curPwl = aciManifest.PathWhitelist

		layerFiles[i].Close()
	}

	return aciLayerPaths, aciManifests, nil
}

type layer struct {
	index  int
	file   *os.File
	closer io.Closer
	err    error
}

func (rb *RepositoryBackend) buildACIV22(layerIDs []string, manhash string, dockerURL *common.ParsedDockerURL, outputDir string, tmpBaseDir string, compression common.Compression) ([]string, []*schema.ImageManifest, error) {
	layerFiles := make([]*os.File, len(layerIDs))

	tmpParentDir, err := ioutil.TempDir(tmpBaseDir, "docker2aci-")
	if err != nil {
		return nil, nil, err
	}
	defer os.RemoveAll(tmpParentDir)

	copier := progressutil.NewCopyProgressPrinter()

	resultChan := make(chan layer, len(layerIDs))
	for i, layerID := range layerIDs {
		if err := common.ValidateLayerId(layerID); err != nil {
			return nil, nil, err
		}
		// https://github.com/golang/go/wiki/CommonMistakes
		i := i // golang--
		layerID := layerID
		go func() {
			tmpDir, err := ioutil.TempDir(tmpParentDir, "")
			if err != nil {
				resultChan <- layer{
					index: i,
					err:   fmt.Errorf("error creating dir: %v", err),
				}
				return
			}

			layerFile, closer, err := rb.getLayerV2(layerID, dockerURL, tmpDir, copier)
			if err != nil {
				resultChan <- layer{
					index: i,
					err:   fmt.Errorf("error getting the remote layer: %v", err),
				}
				return
			}
			resultChan <- layer{
				index:  i,
				file:   layerFile,
				closer: closer,
				err:    nil,
			}
		}()
	}
	var errs []error
	for i := 0; i < len(layerIDs); i++ {
		res := <-resultChan
		if res.closer != nil {
			defer res.closer.Close()
		}
		if res.file != nil {
			defer res.file.Close()
		}
		if res.err != nil {
			errs = append(errs, res.err)
		}
		layerFiles[res.index] = res.file
	}
	if len(errs) > 0 {
		return nil, nil, errs[0]
	}
	err = copier.PrintAndWait(os.Stderr, 500*time.Millisecond, nil)
	if err != nil {
		return nil, nil, err
	}
	for _, layerFile := range layerFiles {
		err := layerFile.Sync()
		if err != nil {
			return nil, nil, err
		}
	}
	var aciLayerPaths []string
	var aciManifests []*schema.ImageManifest
	var curPwl []string
	var i int
	for i = 0; i < len(layerIDs)-1; i++ {
		rb.debug.Println("Generating layer ACI...")
		aciPath, aciManifest, err := internal.GenerateACI22LowerLayer(dockerURL, layerIDs[i], outputDir, layerFiles[i], curPwl, compression)
		if err != nil {
			return nil, nil, fmt.Errorf("error generating ACI: %v", err)
		}
		aciLayerPaths = append(aciLayerPaths, aciPath)
		aciManifests = append(aciManifests, aciManifest)
		curPwl = aciManifest.PathWhitelist
	}
	rb.debug.Println("Generating layer ACI...")
	aciPath, aciManifest, err := internal.GenerateACI22TopLayer(dockerURL, manhash, rb.imageConfigs[*dockerURL], layerIDs[i], outputDir, layerFiles[i], curPwl, compression, aciManifests, rb.debug)
	if err != nil {
		return nil, nil, fmt.Errorf("error generating ACI: %v", err)
	}
	aciLayerPaths = append(aciLayerPaths, aciPath)
	aciManifests = append(aciManifests, aciManifest)

	return aciLayerPaths, aciManifests, nil
}

func (rb *RepositoryBackend) getManifestV2(dockerURL *common.ParsedDockerURL) ([]string, string, error) {
	var reference string
	if dockerURL.Digest != "" {
		reference = dockerURL.Digest
	} else {
		reference = dockerURL.Tag
	}
	url := rb.schema + path.Join(dockerURL.IndexURL, "v2", dockerURL.ImageName, "manifests", reference)

	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return nil, "", err
	}

	rb.setBasicAuth(req)

	res, err := rb.makeRequest(req, dockerURL.ImageName, rb.mediaTypes.ManifestMediaTypes())
	if err != nil {
		return nil, "", err
	}
	defer res.Body.Close()

	if res.StatusCode != http.StatusOK {
		return nil, "", &httpStatusErr{res.StatusCode, req.URL}
	}

	switch res.Header.Get("content-type") {
	case common.MediaTypeDockerV22Manifest, common.MediaTypeOCIV1Manifest:
		return rb.getManifestV22(dockerURL, res)
	case common.MediaTypeDockerV21Manifest:
		return rb.getManifestV21(dockerURL, res)
	}
	return rb.getManifestV21(dockerURL, res)
}

func (rb *RepositoryBackend) getManifestV21(dockerURL *common.ParsedDockerURL, res *http.Response) ([]string, string, error) {
	manblob, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return nil, "", err
	}

	manifest := &v2Manifest{}

	err = json.Unmarshal(manblob, manifest)
	if err != nil {
		return nil, "", err
	}

	manhash := godigest.FromBytes(manblob)

	if manifest.Name != dockerURL.ImageName {
		return nil, "", fmt.Errorf("name doesn't match what was requested, expected: %s, downloaded: %s", dockerURL.ImageName, manifest.Name)
	}

	if dockerURL.Tag != "" && manifest.Tag != dockerURL.Tag {
		return nil, "", fmt.Errorf("tag doesn't match what was requested, expected: %s, downloaded: %s", dockerURL.Tag, manifest.Tag)
	}

	if err := fixManifestLayers(manifest); err != nil {
		return nil, "", err
	}

	//TODO: verify signature here

	layers := make([]string, len(manifest.FSLayers))

	for i, layer := range manifest.FSLayers {
		if _, ok := rb.layersIndex[layer.BlobSum]; !ok {
			rb.layersIndex[layer.BlobSum] = i
		}
		layers[i] = layer.BlobSum
	}

	rb.imageManifests[*dockerURL] = *manifest

	return layers, string(manhash), nil
}

func (rb *RepositoryBackend) getManifestV22(dockerURL *common.ParsedDockerURL, res *http.Response) ([]string, string, error) {
	manblob, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return nil, "", err
	}

	manifest := &typesV2.ImageManifest{}

	err = json.Unmarshal(manblob, manifest)
	if err != nil {
		return nil, "", err
	}

	manhash := godigest.FromBytes(manblob)

	//TODO: verify signature here

	layers := make([]string, len(manifest.Layers))

	for i, layer := range manifest.Layers {
		layers[i] = layer.Digest
	}

	err = rb.getConfigV22(dockerURL, manifest.Config.Digest)
	if err != nil {
		return nil, "", err
	}

	rb.imageV2Manifests[*dockerURL] = manifest

	return layers, string(manhash), nil
}

func (rb *RepositoryBackend) getConfigV22(dockerURL *common.ParsedDockerURL, configDigest string) error {
	url := rb.schema + path.Join(dockerURL.IndexURL, "v2", dockerURL.ImageName, "blobs", configDigest)
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return err
	}

	rb.setBasicAuth(req)

	res, err := rb.makeRequest(req, dockerURL.ImageName, rb.mediaTypes.ConfigMediaTypes())
	if err != nil {
		return err
	}
	defer res.Body.Close()

	confblob, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return err
	}
	config := &typesV2.ImageConfig{}
	err = json.Unmarshal(confblob, config)
	if err != nil {
		return err
	}
	rb.imageConfigs[*dockerURL] = config
	return nil
}

func fixManifestLayers(manifest *v2Manifest) error {
	type imageV1 struct {
		ID     string
		Parent string
	}
	imgs := make([]*imageV1, len(manifest.FSLayers))
	for i := range manifest.FSLayers {
		img := &imageV1{}

		if err := json.Unmarshal([]byte(manifest.History[i].V1Compatibility), img); err != nil {
			return err
		}

		imgs[i] = img
		if err := common.ValidateLayerId(img.ID); err != nil {
			return err
		}
	}

	if imgs[len(imgs)-1].Parent != "" {
		return errors.New("Invalid parent ID in the base layer of the image.")
	}

	// check general duplicates to error instead of a deadlock
	idmap := make(map[string]struct{})

	var lastID string
	for _, img := range imgs {
		// skip IDs that appear after each other, we handle those later
		if _, exists := idmap[img.ID]; img.ID != lastID && exists {
			return fmt.Errorf("ID %+v appears multiple times in manifest", img.ID)
		}
		lastID = img.ID
		idmap[lastID] = struct{}{}
	}

	// backwards loop so that we keep the remaining indexes after removing items
	for i := len(imgs) - 2; i >= 0; i-- {
		if imgs[i].ID == imgs[i+1].ID { // repeated ID. remove and continue
			manifest.FSLayers = append(manifest.FSLayers[:i], manifest.FSLayers[i+1:]...)
			manifest.History = append(manifest.History[:i], manifest.History[i+1:]...)
		} else if imgs[i].Parent != imgs[i+1].ID {
			return fmt.Errorf("Invalid parent ID. Expected %v, got %v.", imgs[i+1].ID, imgs[i].Parent)
		}
	}

	return nil
}

func (rb *RepositoryBackend) getLayerV2(layerID string, dockerURL *common.ParsedDockerURL, tmpDir string, copier *progressutil.CopyProgressPrinter) (*os.File, io.ReadCloser, error) {
	var (
		err error
		res *http.Response
		url = rb.schema + path.Join(dockerURL.IndexURL, "v2", dockerURL.ImageName, "blobs", layerID)
	)
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return nil, nil, err
	}

	rb.setBasicAuth(req)

	res, err = rb.makeRequest(req, dockerURL.ImageName, rb.mediaTypes.LayerMediaTypes())
	if err != nil {
		return nil, nil, err
	}

	defer func() {
		if err != nil && res != nil {
			res.Body.Close()
		}
	}()

	if res.StatusCode == http.StatusTemporaryRedirect || res.StatusCode == http.StatusFound {
		location := res.Header.Get("Location")
		if location != "" {
			req, err = http.NewRequest("GET", location, nil)
			if err != nil {
				return nil, nil, err
			}
			res.Body.Close()
			res = nil
			res, err = rb.makeRequest(req, dockerURL.ImageName, rb.mediaTypes.LayerMediaTypes())
			if err != nil {
				return nil, nil, err
			}
		}
	}

	if res.StatusCode != http.StatusOK {
		return nil, nil, &httpStatusErr{res.StatusCode, req.URL}
	}

	var in io.Reader
	in = res.Body

	var size int64

	if hdr := res.Header.Get("Content-Length"); hdr != "" {
		size, err = strconv.ParseInt(hdr, 10, 64)
		if err != nil {
			return nil, nil, err
		}
	}

	name := "Downloading " + layerID[:18]

	layerFile, err := ioutil.TempFile(tmpDir, "dockerlayer-")
	if err != nil {
		return nil, nil, err
	}

	err = copier.AddCopy(in, name, size, layerFile)
	if err != nil {
		return nil, nil, err
	}

	return layerFile, res.Body, nil
}

func (rb *RepositoryBackend) makeRequest(req *http.Request, repo string, acceptHeaders []string) (*http.Response, error) {
	setBearerHeader := false
	hostAuthTokens, ok := rb.hostsV2AuthTokens[req.URL.Host]
	if ok {
		authToken, ok := hostAuthTokens[repo]
		if ok {
			req.Header.Set("Authorization", "Bearer "+authToken)
			setBearerHeader = true
		}
	}

	for _, acceptHeader := range acceptHeaders {
		req.Header.Add("Accept", acceptHeader)
	}

	client := util.GetTLSClient(rb.insecure.SkipVerify)
	res, err := client.Do(req)
	if err != nil {
		return nil, err
	}

	if res.StatusCode == http.StatusUnauthorized && setBearerHeader {
		return res, err
	}

	hdr := res.Header.Get("www-authenticate")
	if res.StatusCode != http.StatusUnauthorized || hdr == "" {
		return res, err
	}

	tokens := strings.Split(hdr, ",")
	if len(tokens) != 3 ||
		!strings.HasPrefix(strings.ToLower(tokens[0]), "bearer realm") {
		return res, err
	}
	res.Body.Close()

	var realm, service, scope string
	for _, token := range tokens {
		if strings.HasPrefix(strings.ToLower(token), "bearer realm") {
			realm = strings.Trim(token[len("bearer realm="):], "\"")
		}
		if strings.HasPrefix(token, "service") {
			service = strings.Trim(token[len("service="):], "\"")
		}
		if strings.HasPrefix(token, "scope") {
			scope = strings.Trim(token[len("scope="):], "\"")
		}
	}

	if realm == "" {
		return nil, fmt.Errorf("missing realm in bearer auth challenge")
	}
	if service == "" {
		return nil, fmt.Errorf("missing service in bearer auth challenge")
	}
	// The scope can be empty if we're not getting a token for a specific repo
	if scope == "" && repo != "" {
		// If the scope is empty and it shouldn't be, we can infer it based on the repo
		scope = fmt.Sprintf("repository:%s:pull", repo)
	}

	authReq, err := http.NewRequest("GET", realm, nil)
	if err != nil {
		return nil, err
	}

	getParams := authReq.URL.Query()
	getParams.Add("service", service)
	if scope != "" {
		getParams.Add("scope", scope)
	}
	authReq.URL.RawQuery = getParams.Encode()

	rb.setBasicAuth(authReq)

	res, err = client.Do(authReq)
	if err != nil {
		return nil, err
	}
	defer res.Body.Close()

	switch res.StatusCode {
	case http.StatusUnauthorized:
		return nil, fmt.Errorf("unable to retrieve auth token: 401 unauthorized")
	case http.StatusOK:
		break
	default:
		return nil, &httpStatusErr{res.StatusCode, authReq.URL}
	}

	tokenBlob, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return nil, err
	}

	tokenStruct := struct {
		Token string `json:"token"`
	}{}

	err = json.Unmarshal(tokenBlob, &tokenStruct)
	if err != nil {
		return nil, err
	}

	hostAuthTokens, ok = rb.hostsV2AuthTokens[req.URL.Host]
	if !ok {
		hostAuthTokens = make(map[string]string)
		rb.hostsV2AuthTokens[req.URL.Host] = hostAuthTokens
	}

	hostAuthTokens[repo] = tokenStruct.Token

	return rb.makeRequest(req, repo, acceptHeaders)
}

func (rb *RepositoryBackend) setBasicAuth(req *http.Request) {
	if rb.username != "" && rb.password != "" {
		req.SetBasicAuth(rb.username, rb.password)
	}
}


================================================
FILE: lib/internal/docker/docker.go
================================================
// Copyright 2015 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package docker

import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"path"
	"runtime"
	"strings"

	"github.com/appc/docker2aci/lib/internal/types"
)

const (
	dockercfgFileName    = "config.json"
	dockercfgFileNameOld = ".dockercfg"
	defaultIndexURL      = "registry-1.docker.io"
	defaultIndexURLAuth  = "https://index.docker.io/v1/"
	defaultRepoPrefix    = "library/"
)

// SplitReposName breaks a repo name into an index name and remote name.
func SplitReposName(name string) (indexName, remoteName string) {
	i := strings.IndexRune(name, '/')
	if i == -1 || (!strings.ContainsAny(name[:i], ".:") && name[:i] != "localhost") {
		indexName, remoteName = defaultIndexURL, name
	} else {
		indexName, remoteName = name[:i], name[i+1:]
	}
	if indexName == defaultIndexURL && !strings.ContainsRune(remoteName, '/') {
		remoteName = defaultRepoPrefix + remoteName
	}
	return
}

// Get a repos name and returns the right reposName + tag
// The tag can be confusing because of a port in a repository name.
//     Ex: localhost.localdomain:5000/samalba/hipache:latest
func parseRepositoryTag(repos string) (string, string) {
	n := strings.LastIndex(repos, ":")
	if n < 0 {
		return repos, ""
	}
	if tag := repos[n+1:]; !strings.Contains(tag, "/") {
		return repos[:n], tag
	}
	return repos, ""
}

func decodeDockerAuth(s string) (string, string, error) {
	decoded, err := base64.StdEncoding.DecodeString(s)
	if err != nil {
		return "", "", err
	}
	parts := strings.SplitN(string(decoded), ":", 2)
	if len(parts) != 2 {
		return "", "", fmt.Errorf("invalid auth configuration file")
	}
	user := parts[0]
	password := strings.Trim(parts[1], "\x00")
	return user, password, nil
}

func getHomeDir() string {
	if runtime.GOOS == "windows" {
		return os.Getenv("USERPROFILE")
	}
	return os.Getenv("HOME")
}

// GetDockercfgAuth reads a ~/.dockercfg file and returns the username and password
// of the given docker index server.
func GetAuthInfo(indexServer string) (string, string, error) {
	// official docker registry
	if indexServer == defaultIndexURL {
		indexServer = defaultIndexURLAuth
	}
	dockerCfgPath := path.Join(getHomeDir(), ".docker", dockercfgFileName)
	if _, err := os.Stat(dockerCfgPath); err == nil {
		j, err := ioutil.ReadFile(dockerCfgPath)
		if err != nil {
			return "", "", err
		}
		var dockerAuth types.DockerConfigFile
		if err := json.Unmarshal(j, &dockerAuth); err != nil {
			return "", "", err
		}
		// try the normal case
		if c, ok := dockerAuth.AuthConfigs[indexServer]; ok {
			return decodeDockerAuth(c.Auth)
		}
	} else if os.IsNotExist(err) {
		oldDockerCfgPath := path.Join(getHomeDir(), dockercfgFileNameOld)
		if _, err := os.Stat(oldDockerCfgPath); err != nil {
			return "", "", nil //missing file is not an error
		}
		j, err := ioutil.ReadFile(oldDockerCfgPath)
		if err != nil {
			return "", "", err
		}
		var dockerAuthOld map[string]types.DockerAuthConfigOld
		if err := json.Unmarshal(j, &dockerAuthOld); err != nil {
			return "", "", err
		}
		if c, ok := dockerAuthOld[indexServer]; ok {
			return decodeDockerAuth(c.Auth)
		}
	} else {
		// if file is there but we can't stat it for any reason other
		// than it doesn't exist then stop
		return "", "", fmt.Errorf("%s - %v", dockerCfgPath, err)
	}
	return "", "", nil
}


================================================
FILE: lib/internal/internal.go
================================================
// Copyright 2015 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package internal provides functions shared by different parts of docker2aci.
//
// Note: this package is an implementation detail and shouldn't be used outside
// of docker2aci.
package internal

import (
	"archive/tar"
	"encoding/json"
	"fmt"
	"io"
	"os"
	"path"
	"path/filepath"
	"runtime"
	"sort"
	"strconv"
	"strings"
	"time"

	"github.com/appc/docker2aci/lib/common"
	"github.com/appc/docker2aci/lib/internal/tarball"
	"github.com/appc/docker2aci/lib/internal/types"
	"github.com/appc/docker2aci/lib/internal/typesV2"
	"github.com/appc/docker2aci/lib/internal/util"
	"github.com/appc/docker2aci/pkg/log"
	"github.com/appc/spec/aci"
	"github.com/appc/spec/schema"
	appctypes "github.com/appc/spec/schema/types"
	gzip "github.com/klauspost/pgzip"
)

// Docker2ACIBackend is the interface that abstracts converting Docker layers
// to ACI from where they're stored (remote or file).
//
// GetImageInfo takes a Docker URL and returns a list of layers and the parsed
// Docker URL.
//
// BuildACI takes a Docker layer, converts it to ACI and returns its output
// path and its converted ImageManifest.
type Docker2ACIBackend interface {
	// GetImageInfo, given the url for a docker image, will return the
	// following:
	// - []string: an ordered list of all layer hashes
	// - string: a unique identifier for this image, like a hash of the manifest
	// - *common.ParsedDockerURL: a parsed docker URL
	// - error: an error if one occurred
	GetImageInfo(dockerUrl string) ([]string, string, *common.ParsedDockerURL, error)
	BuildACI(layerIDs []string, manhash string, dockerURL *common.ParsedDockerURL, outputDir string, tmpBaseDir string, compression common.Compression) ([]string, []*schema.ImageManifest, error)
}

// GenerateACI takes a Docker layer and generates an ACI from it.
func GenerateACI(layerNumber int, manhash string, layerData types.DockerImageData, dockerURL *common.ParsedDockerURL, outputDir string, layerFile *os.File, curPwl []string, compression common.Compression, debug log.Logger) (string, *schema.ImageManifest, error) {
	manifest, err := GenerateManifest(layerData, manhash, dockerURL, debug)
	if err != nil {
		return "", nil, fmt.Errorf("error generating the manifest: %v", err)
	}

	imageName := strings.Replace(dockerURL.ImageName, "/", "-", -1)
	aciPath := generateACIPath(outputDir, imageName, layerData.ID, dockerURL.Tag, layerData.OS, layerData.Architecture, layerNumber)

	manifest, err = writeACI(layerFile, *manifest, curPwl, aciPath, compression)
	if err != nil {
		return "", nil, fmt.Errorf("error writing ACI: %v", err)
	}

	if err := ValidateACI(aciPath); err != nil {
		return "", nil, fmt.Errorf("invalid ACI generated: %v", err)
	}

	return aciPath, manifest, nil
}

func GenerateACI22LowerLayer(dockerURL *common.ParsedDockerURL, layerDigest string, outputDir string, layerFile *os.File, curPwl []string, compression common.Compression) (string, *schema.ImageManifest, error) {
	formattedDigest := strings.Replace(layerDigest, ":", "-", -1)
	aciName := fmt.Sprintf("%s/%s-%s", dockerURL.IndexURL, dockerURL.ImageName, formattedDigest)
	sanitizedAciName, err := appctypes.SanitizeACIdentifier(aciName)
	if err != nil {
		return "", nil, err
	}
	manifest, err := GenerateEmptyManifest(sanitizedAciName)
	if err != nil {
		return "", nil, err
	}

	aciPath := generateACIPath(outputDir, aciName, layerDigest, dockerURL.Tag, runtime.GOOS, runtime.GOARCH, -1)
	manifest, err = writeACI(layerFile, *manifest, curPwl, aciPath, compression)
	if err != nil {
		return "", nil, err
	}

	err = ValidateACI(aciPath)
	if err != nil {
		return "", nil, fmt.Errorf("invalid ACI generated: %v", err)
	}
	return aciPath, manifest, nil
}

func GenerateACI22TopLayer(dockerURL *common.ParsedDockerURL, manhash string, imageConfig *typesV2.ImageConfig, layerDigest string, outputDir string, layerFile *os.File, curPwl []string, compression common.Compression, lowerLayers []*schema.ImageManifest, debug log.Logger) (string, *schema.ImageManifest, error) {
	aciName := fmt.Sprintf("%s/%s-%s", dockerURL.IndexURL, dockerURL.ImageName, layerDigest)
	sanitizedAciName, err := appctypes.SanitizeACIdentifier(aciName)
	if err != nil {
		return "", nil, err
	}
	manifest, err := GenerateManifestV22(sanitizedAciName, manhash, layerDigest, dockerURL, imageConfig, lowerLayers, debug)
	if err != nil {
		return "", nil, err
	}

	aciPath := generateACIPath(outputDir, aciName, layerDigest, dockerURL.Tag, runtime.GOOS, runtime.GOARCH, -1)
	manifest, err = writeACI(layerFile, *manifest, curPwl, aciPath, compression)
	if err != nil {
		return "", nil, err
	}

	err = ValidateACI(aciPath)
	if err != nil {
		return "", nil, fmt.Errorf("invalid ACI generated: %v", err)
	}
	return aciPath, manifest, nil
}

func generateACIPath(outputDir, imageName, digest, tag, osString, arch string, layerNum int) string {
	aciPath := imageName
	if tag != "" {
		aciPath += "-" + tag
	}
	if osString != "" {
		aciPath += "-" + osString
		if arch != "" {
			aciPath += "-" + arch
		}
	}
	if layerNum != -1 {
		aciPath += "-" + strconv.Itoa(layerNum)
	}
	aciPath += ".aci"
	return path.Join(outputDir, aciPath)
}

func generateEPCmdAnnotation(dockerEP, dockerCmd []string) (string, string, error) {
	var entrypointAnnotation, cmdAnnotation string
	if len(dockerEP) > 0 {
		entry, err := json.Marshal(dockerEP)
		if err != nil {
			return "", "", err
		}
		entrypointAnnotation = string(entry)
	}
	if len(dockerCmd) > 0 {
		cmd, err := json.Marshal(dockerCmd)
		if err != nil {
			return "", "", err
		}
		cmdAnnotation = string(cmd)
	}

	return entrypointAnnotation, cmdAnnotation, nil
}

// setLabel sets the label entries associated with non-empty key
// to the single non-empty value. It replaces any existing values
// associated with key.
func setLabel(labels map[appctypes.ACIdentifier]string, key, val string) {
	if key != "" && val != "" {
		labels[*appctypes.MustACIdentifier(key)] = val
	}
}

// setOSArch translates the given OS and architecture strings into
// the compatible with application container specification and sets
// the respective label entries.
//
// Returns an error if label translation fails.
func setOSArch(labels map[appctypes.ACIdentifier]string, os, arch string) error {
	// Translate arch tuple into the appc arch tuple.
	appcOS, appcArch, err := appctypes.ToAppcOSArch(os, arch, "")
	if err != nil {
		return err
	}

	// Set translated labels.
	setLabel(labels, "os", appcOS)
	setLabel(labels, "arch", appcArch)
	return nil
}

// setAnnotation sets the annotation entries associated with non-empty
// key to the single non-empty value. It replaces any existing values
// associated with key.
func setAnnotation(annotations *appctypes.Annotations, key, val string) {
	if key != "" && val != "" {
		annotations.Set(*appctypes.MustACIdentifier(key), val)
	}
}

// GenerateManifest converts the docker manifest format to an appc
// ImageManifest.
func GenerateManifest(layerData types.DockerImageData, manhash string, dockerURL *common.ParsedDockerURL, debug log.Logger) (*schema.ImageManifest, error) {
	dockerConfig := layerData.Config
	genManifest := &schema.ImageManifest{}

	appURL := ""
	appURL = dockerURL.IndexURL + "/"
	appURL += dockerURL.ImageName + "-" + layerData.ID
	appURL, err := appctypes.SanitizeACIdentifier(appURL)
	if err != nil {
		return nil, err
	}
	name := appctypes.MustACIdentifier(appURL)
	genManifest.Name = *name

	acVersion, err := appctypes.NewSemVer(schema.AppContainerVersion.String())
	if err != nil {
		panic("invalid appc spec version")
	}
	genManifest.ACVersion = *acVersion

	genManifest.ACKind = appctypes.ACKind(schema.ImageManifestKind)

	var annotations appctypes.Annotations

	labels := make(map[appctypes.ACIdentifier]string)
	parentLabels := make(map[appctypes.ACIdentifier]string)

	setLabel(labels, "layer", layerData.ID)
	setLabel(labels, "version", dockerURL.Tag)

	setOSArch(labels, layerData.OS, layerData.Architecture)
	setOSArch(parentLabels, layerData.OS, layerData.Architecture)

	setAnnotation(&annotations, "authors", layerData.Author)
	epoch := time.Unix(0, 0)
	if !layerData.Created.Equal(epoch) {
		setAnnotation(&annotations, "created", layerData.Created.Format(time.RFC3339))
	}
	setAnnotation(&annotations, "docker-comment", layerData.Comment)
	setAnnotation(&annotations, common.AppcDockerOriginalName, dockerURL.OriginalName)
	setAnnotation(&annotations, common.AppcDockerRegistryURL, dockerURL.IndexURL)
	setAnnotation(&annotations, common.AppcDockerRepository, dockerURL.ImageName)
	setAnnotation(&annotations, common.AppcDockerImageID, layerData.ID)
	setAnnotation(&annotations, common.AppcDockerParentImageID, layerData.Parent)
	setAnnotation(&annotations, common.AppcDockerManifestHash, manhash)

	if dockerConfig != nil {
		exec := getExecCommand(dockerConfig.Entrypoint, dockerConfig.Cmd)
		user, group := parseDockerUser(dockerConfig.User)
		var env appctypes.Environment
		for _, v := range dockerConfig.Env {
			parts := strings.SplitN(v, "=", 2)
                        if len(parts) == 2 {
				env.Set(parts[0], parts[1])
                        }
		}
		app := &appctypes.App{
			Exec:             exec,
			User:             user,
			Group:            group,
			Environment:      env,
			WorkingDirectory: dockerConfig.WorkingDir,
		}

		app.UserLabels = dockerConfig.Labels

		app.MountPoints, err = convertVolumesToMPs(dockerConfig.Volumes)
		if err != nil {
			return nil, err
		}

		app.Ports, err = convertPorts(dockerConfig.ExposedPorts, dockerConfig.PortSpecs, debug)
		if err != nil {
			return nil, err
		}

		ep, cmd, err := generateEPCmdAnnotation(dockerConfig.Entrypoint, dockerConfig.Cmd)
		if err != nil {
			return nil, err
		}
		if len(ep) > 0 {
			setAnnotation(&annotations, common.AppcDockerEntrypoint, ep)
		}
		if len(cmd) > 0 {
			setAnnotation(&annotations, common.AppcDockerCmd, cmd)
		}

		genManifest.App = app
	}

	if layerData.Parent != "" {
		indexPrefix := ""
		// omit docker hub index URL in app name
		indexPrefix = dockerURL.IndexURL + "/"
		parentImageNameString := indexPrefix + dockerURL.ImageName + "-" + layerData.Parent
		parentImageNameString, err := appctypes.SanitizeACIdentifier(parentImageNameString)
		if err != nil {
			return nil, err
		}
		parentImageName := appctypes.MustACIdentifier(parentImageNameString)

		plbl, err := appctypes.LabelsFromMap(labels)
		if err != nil {
			return nil, err
		}

		genManifest.Dependencies = append(genManifest.Dependencies, appctypes.Dependency{ImageName: *parentImageName, Labels: plbl})

		setAnnotation(&annotations, common.AppcDockerTag, dockerURL.Tag)
	}

	genManifest.Labels, err = appctypes.LabelsFromMap(labels)
	if err != nil {
		return nil, err
	}
	genManifest.Annotations = annotations

	return genManifest, nil
}

func GenerateEmptyManifest(name string) (*schema.ImageManifest, error) {
	acid, err := appctypes.NewACIdentifier(name)
	if err != nil {
		return nil, err
	}

	labelsMap := make(map[appctypes.ACIdentifier]string)
	err = setOSArch(labelsMap, runtime.GOOS, runtime.GOARCH)
	if err != nil {
		return nil, err
	}

	labels, err := appctypes.LabelsFromMap(labelsMap)
	if err != nil {
		return nil, err
	}

	return &schema.ImageManifest{
		ACKind:    schema.ImageManifestKind,
		ACVersion: schema.AppContainerVersion,
		Name:      *acid,
		Labels:    labels,
	}, nil
}

// GenerateManifestV22, given a large set of information (documented a couple
// lines down), will produce an image manifest compliant with the Dockver V2.2
// image spec
func GenerateManifestV22(
	name string, // The name of this image
	manhash string, // The hash of this image's manifest
	imageDigest string, // The digest of the image
	dockerURL *common.ParsedDockerURL, // The parsed docker URL
	config *typesV2.ImageConfig, // The image config
	lowerLayers []*schema.ImageManifest, // A list of manifests for the lower layers
	debug log.Logger, // The debug logger, for logging debug information
) (*schema.ImageManifest, error) {
	manifest, err := GenerateEmptyManifest(name)
	if err != nil {
		return nil, err
	}

	labels := manifest.Labels.ToMap()
	annotations := manifest.Annotations

	setLabel(labels, "version", dockerURL.Tag)
	setOSArch(labels, config.OS, config.Architecture)

	setAnnotation(&annotations, "author", config.Author)
	setAnnotation(&annotations, "created", config.Created)

	setAnnotation(&annotations, common.AppcDockerOriginalName, dockerURL.OriginalName)
	setAnnotation(&annotations, common.AppcDockerRegistryURL, dockerURL.IndexURL)
	setAnnotation(&annotations, common.AppcDockerRepository, dockerURL.ImageName)
	setAnnotation(&annotations, common.AppcDockerImageID, imageDigest)
	setAnnotation(&annotations, "created", config.Created)
	setAnnotation(&annotations, common.AppcDockerManifestHash, manhash)

	if config.Config != nil {
		innerCfg := config.Config
		exec := getExecCommand(innerCfg.Entrypoint, innerCfg.Cmd)
		user, group := parseDockerUser(innerCfg.User)
		var env appctypes.Environment
		for _, v := range innerCfg.Env {
			parts := strings.SplitN(v, "=", 2)
                        if len(parts) == 2 {
				env.Set(parts[0], parts[1])
                        }
		}
		manifest.App = &appctypes.App{
			Exec:             exec,
			User:             user,
			Group:            group,
			Environment:      env,
			WorkingDirectory: innerCfg.WorkingDir,
		}
		manifest.App.MountPoints, err = convertVolumesToMPs(innerCfg.Volumes)
		if err != nil {
			return nil, err
		}
		manifest.App.Ports, err = convertPorts(innerCfg.ExposedPorts, nil, debug)
		if err != nil {
			return nil, err
		}

		ep, cmd, err := generateEPCmdAnnotation(innerCfg.Entrypoint, innerCfg.Cmd)
		if err != nil {
			return nil, err
		}
		if len(ep) > 0 {
			setAnnotation(&annotations, common.AppcDockerEntrypoint, ep)
		}
		if len(cmd) > 0 {
			setAnnotation(&annotations, common.AppcDockerCmd, cmd)
		}
	}

	for _, lowerLayer := range lowerLayers {
		manifest.Dependencies = append(manifest.Dependencies, appctypes.Dependency{
			ImageName: lowerLayer.Name,
			Labels:    lowerLayer.Labels,
		})
	}

	manifest.Labels, err = appctypes.LabelsFromMap(labels)
	if err != nil {
		return nil, err
	}
	manifest.Annotations = annotations
	return manifest, nil
}

// ValidateACI checks whether the ACI in aciPath is valid.
func ValidateACI(aciPath string) error {
	aciFile, err := os.Open(aciPath)
	if err != nil {
		return err
	}
	defer aciFile.Close()

	tr, err := aci.NewCompressedTarReader(aciFile)
	if err != nil {
		return err
	}
	defer tr.Close()

	if err := aci.ValidateArchive(tr.Reader); err != nil {
		return err
	}

	return nil
}

type appcPortSorter []appctypes.Port

func (s appcPortSorter) Len() int {
	return len(s)
}

func (s appcPortSorter) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]
}

func (s appcPortSorter) Less(i, j int) bool {
	return s[i].Name.String() < s[j].Name.String()
}

func convertPorts(dockerExposedPorts map[string]struct{}, dockerPortSpecs []string, debug log.Logger) ([]appctypes.Port, error) {
	ports := []appctypes.Port{}

	for ep := range dockerExposedPorts {
		appcPort, err := parseDockerPort(ep)
		if err != nil {
			return nil, err
		}
		ports = append(ports, *appcPort)
	}

	if dockerExposedPorts == nil && dockerPortSpecs != nil {
		debug.Println("warning: docker image uses deprecated PortSpecs field")
		for _, ep := range dockerPortSpecs {
			appcPort, err := parseDockerPort(ep)
			if err != nil {
				return nil, err
			}
			ports = append(ports, *appcPort)
		}
	}

	sort.Sort(appcPortSorter(ports))

	return ports, nil
}

func parseDockerPort(dockerPort string) (*appctypes.Port, error) {
	var portString string
	proto := "tcp"
	sp := strings.Split(dockerPort, "/")
	if len(sp) < 2 {
		portString = dockerPort
	} else {
		proto = sp[1]
		portString = sp[0]
	}

	port, err := strconv.ParseUint(portString, 10, 0)
	if err != nil {
		return nil, fmt.Errorf("error parsing port %q: %v", portString, err)
	}

	sn, err := appctypes.SanitizeACName(dockerPort)
	if err != nil {
		return nil, err
	}

	appcPort := &appctypes.Port{
		Name:     *appctypes.MustACName(sn),
		Protocol: proto,
		Port:     uint(port),
	}

	return appcPort, nil
}

type appcVolSorter []appctypes.MountPoint

func (s appcVolSorter) Len() int {
	return len(s)
}

func (s appcVolSorter) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]
}

func (s appcVolSorter) Less(i, j int) bool {
	return s[i].Name.String() < s[j].Name.String()
}

func convertVolumesToMPs(dockerVolumes map[string]struct{}) ([]appctypes.MountPoint, error) {
	mps := []appctypes.MountPoint{}
	dup := make(map[string]int)

	for p := range dockerVolumes {
		n := filepath.Join("volume", p)
		sn, err := appctypes.SanitizeACName(n)
		if err != nil {
			return nil, err
		}

		// check for duplicate names
		if i, ok := dup[sn]; ok {
			dup[sn] = i + 1
			sn = fmt.Sprintf("%s-%d", sn, i)
		} else {
			dup[sn] = 1
		}

		mp := appctypes.MountPoint{
			Name: *appctypes.MustACName(sn),
			Path: p,
		}

		mps = append(mps, mp)
	}

	sort.Sort(appcVolSorter(mps))

	return mps, nil
}

func writeACI(layer io.ReadSeeker, manifest schema.ImageManifest, curPwl []string, output string, compression common.Compression) (*schema.ImageManifest, error) {
	dir, _ := path.Split(output)
	if dir != "" {
		err := os.MkdirAll(dir, 0755)
		if err != nil {
			return nil, fmt.Errorf("error creating ACI parent dir: %v", err)
		}
	}
	aciFile, err := os.Create(output)
	if err != nil {
		return nil, fmt.Errorf("error creating ACI file: %v", err)
	}
	defer aciFile.Close()

	var w io.WriteCloser = aciFile
	if compression == common.GzipCompression {
		w = gzip.NewWriter(aciFile)
		defer w.Close()
	}
	trw := tar.NewWriter(w)
	defer trw.Close()

	if err := WriteRootfsDir(trw); err != nil {
		return nil, fmt.Errorf("error writing rootfs entry: %v", err)
	}

	fileMap := make(map[string]struct{})
	var whiteouts []string
	convWalker := func(t *tarball.TarFile) error {
		name := t.Name()
		if name == "./" {
			return nil
		}
		newName := path.Join("rootfs", name)
		absolutePath := strings.TrimPrefix(newName, "rootfs")

		if filepath.Clean(absolutePath) == "/dev" && t.Header.Typeflag != tar.TypeDir {
			return fmt.Errorf(`invalid layer: "/dev" is not a directory`)
		}

		fileMap[absolutePath] = struct{}{}
		if strings.Contains(newName, "/.wh.") {
			whiteouts = append(whiteouts, strings.Replace(absolutePath, ".wh.", "", 1))
			return nil
		}

		newHeader := &tar.Header{
			Typeflag:   t.Header.Typeflag,
			Name:       newName,
			Linkname:   t.Header.Linkname,
			Size:       t.Header.Size,
			Mode:       t.Header.Mode,
			Uid:        t.Header.Uid,
			Gid:        t.Header.Gid,
			Uname:      t.Header.Uname,
			Gname:      t.Header.Gname,
			ModTime:    t.Header.ModTime,
			AccessTime: t.Header.AccessTime,
			ChangeTime: t.Header.ChangeTime,
			Devmajor:   t.Header.Devmajor,
			Devminor:   t.Header.Devminor,
			Xattrs:     t.Header.Xattrs,
		}
		if t.Header.Typeflag == tar.TypeLink {
			newHeader.Linkname = path.Join("rootfs", t.Linkname())
		}
		if err := trw.WriteHeader(newHeader); err != nil {
			return err
		}
		if _, err := io.Copy(trw, t.TarStream); err != nil {
			return err
		}

		if !util.In(curPwl, absolutePath) {
			curPwl = append(curPwl, absolutePath)
		}

		return nil
	}
	tr, err := aci.NewCompressedTarReader(layer)
	if err == nil {
		defer tr.Close()
		// write files in rootfs/
		if err := tarball.Walk(*tr.Reader, convWalker); err != nil {
			return nil, err
		}
	} else {
		// ignore errors: empty layers in tars generated by docker save are not
		// valid tar files so we ignore errors trying to open them. Converted
		// ACIs will have the manifest and an empty rootfs directory in any
		// case.
	}
	newPwl := subtractWhiteouts(curPwl, whiteouts)

	newPwl, err = writeStdioSymlinks(trw, fileMap, newPwl)
	if err != nil {
		return nil, err
	}
	// Let's copy the newly generated PathWhitelist to avoid unintended
	// side-effects
	manifest.PathWhitelist = make([]string, len(newPwl))
	copy(manifest.PathWhitelist, newPwl)

	if err := WriteManifest(trw, manifest); err != nil {
		return nil, fmt.Errorf("error writing manifest: %v", err)
	}

	return &manifest, nil
}

func getExecCommand(entrypoint []string, cmd []string) appctypes.Exec {
	return append(entrypoint, cmd...)
}

func parseDockerUser(dockerUser string) (string, string) {
	// if the docker user is empty assume root user and group
	if dockerUser == "" {
		return "0", "0"
	}

	dockerUserParts := strings.Split(dockerUser, ":")

	// when only the user is given, the docker spec says that the default and
	// supplementary groups of the user in /etc/passwd should be applied.
	// To avoid inspecting image content, we set gid to the same value as uid.
	if len(dockerUserParts) < 2 {
		return dockerUserParts[0], dockerUserParts[0]
	}

	return dockerUserParts[0], dockerUserParts[1]
}

func subtractWhiteouts(pathWhitelist []string, whiteouts []string) []string {
	matchPaths := []string{}
	for _, path := range pathWhitelist {
		// If one of the parent dirs of the current path matches the
		// whiteout then also this path should be removed
		curPath := path
		for curPath != "/" {
			for _, whiteout := range whiteouts {
				if curPath == whiteout {
					matchPaths = append(matchPaths, path)
				}
			}
			curPath = filepath.Dir(curPath)
		}
	}
	for _, matchPath := range matchPaths {
		idx := util.IndexOf(pathWhitelist, matchPath)
		if idx != -1 {
			pathWhitelist = append(pathWhitelist[:idx], pathWhitelist[idx+1:]...)
		}
	}

	sort.Sort(sort.StringSlice(pathWhitelist))

	return pathWhitelist
}

// WriteManifest writes a schema.ImageManifest entry on a tar.Writer.
func WriteManifest(outputWriter *tar.Writer, manifest schema.ImageManifest) error {
	b, err := json.Marshal(manifest)
	if err != nil {
		return err
	}

	hdr := getGenericTarHeader()
	hdr.Name = "manifest"
	hdr.Mode = 0644
	hdr.Size = int64(len(b))
	hdr.Typeflag = tar.TypeReg

	if err := outputWriter.WriteHeader(hdr); err != nil {
		return err
	}
	if _, err := outputWriter.Write(b); err != nil {
		return err
	}

	return nil
}

// WriteRootfsDir writes a "rootfs" dir entry on a tar.Writer.
func WriteRootfsDir(tarWriter *tar.Writer) error {
	hdr := getGenericTarHeader()
	hdr.Name = "rootfs"
	hdr.Mode = 0755
	hdr.Size = int64(0)
	hdr.Typeflag = tar.TypeDir

	return tarWriter.WriteHeader(hdr)
}

type symlink struct {
	linkname string
	target   string
}

// writeStdioSymlinks adds the /dev/stdin, /dev/stdout, /dev/stderr, and
// /dev/fd symlinks expected by Docker to the converted ACIs so apps can find
// them as expected
func writeStdioSymlinks(tarWriter *tar.Writer, fileMap map[string]struct{}, pwl []string) ([]string, error) {
	stdioSymlinks := []symlink{
		{"/dev/stdin", "/proc/self/fd/0"},
		// Docker makes /dev/{stdout,stderr} point to /proc/self/fd/{1,2} but
		// we point to /dev/console instead in order to support the case when
		// stdout/stderr is a Unix socket (e.g. for the journal).
		{"/dev/stdout", "/dev/console"},
		{"/dev/stderr", "/dev/console"},
		{"/dev/fd", "/proc/self/fd"},
	}

	for _, s := range stdioSymlinks {
		name := s.linkname
		target := s.target
		if _, exists := fileMap[name]; exists {
			continue
		}
		hdr := &tar.Header{
			Name:     filepath.Join("rootfs", name),
			Mode:     0777,
			Typeflag: tar.TypeSymlink,
			Linkname: target,
		}
		if err := tarWriter.WriteHeader(hdr); err != nil {
			return nil, err
		}
		if !util.In(pwl, name) {
			pwl = append(pwl, name)
		}
	}

	return pwl, nil
}

func getGenericTarHeader() *tar.Header {
	// FIXME(iaguis) Use docker image time instead of the Unix Epoch?
	hdr := &tar.Header{
		Uid:        0,
		Gid:        0,
		ModTime:    time.Unix(0, 0),
		Uname:      "0",
		Gname:      "0",
		ChangeTime: time.Unix(0, 0),
	}

	return hdr
}


================================================
FILE: lib/internal/internal_test.go
================================================
// Copyright 2017 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package internal

import (
	"testing"

	"github.com/appc/spec/schema/types"
)

func TestSetLabel(t *testing.T) {
	labels := make(map[types.ACIdentifier]string)

	tests := []struct {
		key, value string
		ok         bool
	}{
		{"", "amd64", false},
		{"freebsd", "", false},
		{"", "", false},
		{"version", "1.2.3", true},
		{"os", "linux", true},
		{"arch", "aarch64", true},
		{"arch", "amd64", true},
	}

	for i, tt := range tests {
		setLabel(labels, tt.key, tt.value)

		value, ok := labels[types.ACIdentifier(tt.key)]
		if ok != tt.ok {
			const text = "#%d failed on label existence validation: %v != %v"
			t.Errorf(text, i, ok, tt.ok)
		}

		if tt.ok && value != tt.value {
			const text = "#%d wrong label for %s key: %v != %v"
			t.Errorf(text, i, tt.key, value, tt.value)
		}
	}
}

func TestSetAnnotation(t *testing.T) {
	var annotations types.Annotations

	tests := []struct {
		key, value string
		ok         bool
	}{
		{"", "", false},
		{"", "name", false},
		{"gentoo", "", false},
		{"entrypoint", "/bin/bash", true},
		{"entrypoint", "/bin/sh", true},
		{"cmd", "-c", true},
	}

	for i, tt := range tests {
		setAnnotation(&annotations, tt.key, tt.value)

		value, ok := annotations.Get(tt.key)
		if ok != tt.ok {
			const text = "#%d failed on annotation existence validation: %v != %v"
			t.Errorf(text, i, ok, tt.ok)
		}

		if tt.ok && value != tt.value {
			const text = "#%d wrong annotation for %s key: %v != %v"
			t.Errorf(text, i, tt.key, value, tt.value)
		}
	}
}

func TestOSArch(t *testing.T) {
	tests := []struct {
		srcOS, srcArch string
		dstOS, dstArch string
		err            bool
	}{
		{"", "", "", "", false},
		{"TempleOS", "ia64", "", "", false},
		{"linux", "amd64", "linux", "amd64", true},
		{"linux", "arm64", "linux", "aarch64", true},
		{"freebsd", "386", "freebsd", "i386", true},
	}

	for i, tt := range tests {
		labels := make(map[types.ACIdentifier]string)
		err := setOSArch(labels, tt.srcOS, tt.srcArch)

		if tt.err != (err == nil) {
			const text = "#%d unexpected result of os/arch conversion: %v"
			t.Errorf(text, i, err)
		}

		if labels["os"] != tt.dstOS {
			const text = "#%d expected %v os, got %v instead"
			t.Errorf(text, i, tt.dstOS, labels["os"])
		}

		if labels["arch"] != tt.dstArch {
			const text = "#%d expected %v arch, got %v instead"
			t.Errorf(text, i, tt.dstArch, labels["arch"])
		}
	}
}


================================================
FILE: lib/internal/tarball/tarfile.go
================================================
// Copyright 2015 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package tarball provides functions to manipulate tar files.
//
// Note: this package is an implementation detail and shouldn't be used outside
// of docker2aci.
package tarball

import (
	"archive/tar"
	"io"
)

// TarFile is a representation of a file in a tarball. It consists of two parts,
// the Header and the Stream. The Header is a regular tar header, the Stream
// is a byte stream that can be used to read the file's contents.
type TarFile struct {
	Header    *tar.Header
	TarStream io.Reader
}

// Name returns the name of the file as reported by the header.
func (t *TarFile) Name() string {
	return t.Header.Name
}

// Linkname returns the Linkname of the file as reported by the header.
func (t *TarFile) Linkname() string {
	return t.Header.Linkname
}


================================================
FILE: lib/internal/tarball/walk.go
================================================
// Copyright 2015 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package tarball

import (
	"archive/tar"
	"fmt"
	"io"
)

// WalkFunc is a func for handling each file (header and byte stream) in a tarball
type WalkFunc func(t *TarFile) error

// Walk walks through the files in the tarball represented by tarstream and
// passes each of them to the WalkFunc provided as an argument
func Walk(tarReader tar.Reader, walkFunc func(t *TarFile) error) error {
	for {
		hdr, err := tarReader.Next()
		if err == io.EOF {
			// end of tar archive
			break
		}
		if err != nil {
			return fmt.Errorf("Error reading tar entry: %v", err)
		}
		if err := walkFunc(&TarFile{Header: hdr, TarStream: &tarReader}); err != nil {
			return err
		}
	}
	return nil
}


================================================
FILE: lib/internal/types/docker_types.go
================================================
// Copyright 2015 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package types

import "time"

// DockerImageData stores the JSON structure of a Docker image.
// Taken and adapted from upstream Docker.
type DockerImageData struct {
	ID              string             `json:"id"`
	Parent          string             `json:"parent,omitempty"`
	Comment         string             `json:"comment,omitempty"`
	Created         time.Time          `json:"created"`
	Container       string             `json:"container,omitempty"`
	ContainerConfig DockerImageConfig  `json:"container_config,omitempty"`
	DockerVersion   string             `json:"docker_version,omitempty"`
	Author          string             `json:"author,omitempty"`
	Config          *DockerImageConfig `json:"config,omitempty"`
	Architecture    string             `json:"architecture,omitempty"`
	OS              string             `json:"os,omitempty"`
	Checksum        string             `json:"checksum"`
}

// Note: the Config structure should hold only portable information about the container.
// Here, "portable" means "independent from the host we are running on".
// Non-portable information *should* appear in HostConfig.
// Taken and adapted from upstream Docker.
type DockerImageConfig struct {
	Hostname        string
	Domainname      string
	User            string
	Memory          int64  // Memory limit (in bytes)
	MemorySwap      int64  // Total memory usage (memory + swap); set `-1' to disable swap
	CpuShares       int64  // CPU shares (relative weight vs. other containers)
	Cpuset          string // Cpuset 0-2, 0,1
	AttachStdin     bool
	AttachStdout    bool
	AttachStderr    bool
	PortSpecs       []string // Deprecated - Can be in the format of 8080/tcp
	ExposedPorts    map[string]struct{}
	Tty             bool // Attach standard streams to a tty, including stdin if it is not closed.
	OpenStdin       bool // Open stdin
	StdinOnce       bool // If true, close stdin after the 1 attached client disconnects.
	Env             []string
	Cmd             []string
	Image           string // Name of the image as it was passed by the operator (eg. could be symbolic)
	Volumes         map[string]struct{}
	WorkingDir      string
	Entrypoint      []string
	NetworkDisabled bool
	MacAddress      string
	OnBuild         []string
	Labels          map[string]string
}

// DockerAuthConfigOld represents the deprecated ~/.dockercfg auth
// configuration.
// Taken from upstream Docker.
type DockerAuthConfigOld struct {
	Username      string `json:"username,omitempty"`
	Password      string `json:"password,omitempty"`
	Auth          string `json:"auth"`
	Email         string `json:"email"`
	ServerAddress string `json:"serveraddress,omitempty"`
}

// DockerAuthConfig represents a config.json auth entry.
// Taken from upstream Docker.
type DockerAuthConfig struct {
	Username      string `json:"username,omitempty"`
	Password      string `json:"password,omitempty"`
	Auth          string `json:"auth,omitempty"`
	ServerAddress string `json:"serveraddress,omitempty"`
	RegistryToken string `json:"registrytoken,omitempty"`
}

// DockerConfigFile represents a config.json auth file.
// Taken from upstream docker.
type DockerConfigFile struct {
	AuthConfigs map[string]DockerAuthConfig `json:"auths"`
}


================================================
FILE: lib/internal/typesV2/docker_types.go
================================================
// Copyright 2016 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package typesV2

import (
	"encoding/json"
	"errors"

	"github.com/appc/docker2aci/lib/common"
)

var (
	ErrIncorrectMediaType = errors.New("incorrect mediaType")
	ErrMissingConfig      = errors.New("the config field is empty")
	ErrMissingLayers      = errors.New("the layers field is empty")
)

type ImageManifest struct {
	SchemaVersion int                    `json:"schemaVersion"`
	MediaType     string                 `json:"mediaType"`
	Config        *ImageManifestDigest   `json:"config"`
	Layers        []*ImageManifestDigest `json:"layers"`
	Annotations   map[string]string      `json:"annotations"`
}

type ImageManifestDigest struct {
	MediaType string `json:"mediaType"`
	Size      int    `json:"size"`
	Digest    string `json:"digest"`
}

func (im *ImageManifest) String() string {
	manblob, err := json.Marshal(im)
	if err != nil {
		return err.Error()
	}
	return string(manblob)
}

func (im *ImageManifest) PrettyString() string {
	manblob, err := json.MarshalIndent(im, "", "    ")
	if err != nil {
		return err.Error()
	}
	return string(manblob)
}

func (im *ImageManifest) Validate() error {
	if im.MediaType != common.MediaTypeDockerV22Manifest && im.MediaType != common.MediaTypeOCIV1Manifest {
		return ErrIncorrectMediaType
	}
	if im.Config == nil {
		return ErrMissingConfig
	}
	if len(im.Layers) == 0 {
		return ErrMissingLayers
	}
	return nil
}

type ImageConfig struct {
	Created      string                `json:"created"`
	Author       string                `json:"author"`
	Architecture string                `json:"architecture"`
	OS           string                `json:"os"`
	Config       *ImageConfigConfig    `json:"config"`
	RootFS       *ImageConfigRootFS    `json:"rootfs"`
	History      []*ImageConfigHistory `json:"history"`
}

type ImageConfigConfig struct {
	User         string              `json:"User"`
	Memory       int                 `json:"Memory"`
	MemorySwap   int                 `json:"MemorySwap"`
	CpuShares    int                 `json:"CpuShares"`
	ExposedPorts map[string]struct{} `json:"ExposedPorts"`
	Env          []string            `json:"Env"`
	Entrypoint   []string            `json:"Entrypoint"`
	Cmd          []string            `json:"Cmd"`
	Volumes      map[string]struct{} `json:"Volumes"`
	WorkingDir   string              `json:"WorkingDir"`
}

type ImageConfigRootFS struct {
	DiffIDs []string `json:"diff_ids"`
	Type    string   `json:"type"`
}

type ImageConfigHistory struct {
	Created    string `json:"created,omitempty"`
	Author     string `json:"author,omitempty"`
	CreatedBy  string `json:"created_by,omitempty"`
	Comment    string `json:"comment,omitempty"`
	EmptyLayer bool   `json:"empty_layer,omitempty"`
}

func (ic *ImageConfig) String() string {
	manblob, err := json.Marshal(ic)
	if err != nil {
		return err.Error()
	}
	return string(manblob)
}

func (ic *ImageConfig) PrettyString() string {
	manblob, err := json.MarshalIndent(ic, "", "    ")
	if err != nil {
		return err.Error()
	}
	return string(manblob)
}


================================================
FILE: lib/internal/util/util.go
================================================
// Copyright 2015 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package util defines convenience functions for handling slices and debugging.
//
// Note: this package is an implementation detail and shouldn't be used outside
// of docker2aci.
package util

import (
	"crypto/tls"
	"fmt"
	"net"
	"net/http"
	"time"

	"github.com/appc/spec/pkg/acirenderer"
)

var (
	secureClient   = newClient(false)
	insecureClient = newClient(true)
)

// Quote takes a slice of strings and returns another slice with them quoted.
func Quote(l []string) []string {
	var quoted []string

	for _, s := range l {
		quoted = append(quoted, fmt.Sprintf("%q", s))
	}

	return quoted
}

// ReverseImages takes an acirenderer.Images and reverses it.
func ReverseImages(s acirenderer.Images) acirenderer.Images {
	var o acirenderer.Images
	for i := len(s) - 1; i >= 0; i-- {
		o = append(o, s[i])
	}

	return o
}

// In checks whether el is in list.
func In(list []string, el string) bool {
	return IndexOf(list, el) != -1
}

// IndexOf returns the index of el in list, or -1 if it's not found.
func IndexOf(list []string, el string) int {
	for i, x := range list {
		if el == x {
			return i
		}
	}
	return -1
}

// GetTLSClient gets an HTTP client that behaves like the default HTTP
// client, but optionally skips the TLS certificate verification.
func GetTLSClient(skipTLSCheck bool) *http.Client {
	if skipTLSCheck {
		return insecureClient
	}

	return secureClient
}

func newClient(skipTLSCheck bool) *http.Client {
	dialer := &net.Dialer{
		Timeout:   30 * time.Second,
		KeepAlive: 30 * time.Second,
	} // values taken from stdlib v1.5.3

	tr := &http.Transport{
		Proxy:               http.ProxyFromEnvironment,
		Dial:                dialer.Dial,
		TLSHandshakeTimeout: 10 * time.Second,
	} // values taken from stdlib v1.5.3

	if skipTLSCheck {
		tr.TLSClientConfig = &tls.Config{
			InsecureSkipVerify: true,
		}
	}

	return &http.Client{
		Transport: tr,
	}
}


================================================
FILE: lib/tests/common.go
================================================
package test

import (
	"archive/tar"
	"bytes"
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"io/ioutil"
	"os"
	"path"

	"github.com/appc/docker2aci/lib/common"
	"github.com/appc/docker2aci/lib/internal/typesV2"
)

type Layer map[*tar.Header][]byte

type Docker22Image struct {
	RepoTags []string
	Layers   []Layer
	Config   typesV2.ImageConfig
}

func GenerateDocker22(destPath string, img Docker22Image) error {
	layerHashes, err := GenLayers(destPath, img.Layers)
	if err != nil {
		return err
	}
	configHash, err := GenDocker22Config(destPath, img.Config, layerHashes)
	if err != nil {
		return err
	}
	err = GenDocker22Manifest(destPath, configHash, layerHashes)
	if err != nil {
		return err
	}
	return nil
}

func GenLayers(destPath string, layers []Layer) ([]string, error) {
	var layerHashes []string
	for _, l := range layers {
		layerBuffer := &bytes.Buffer{}
		tw := tar.NewWriter(layerBuffer)
		for hdr, contents := range l {
			hdr.Size = int64(len(contents))
			err := tw.WriteHeader(hdr)
			if err != nil {
				tw.Close()
				return nil, err
			}
			_, err = tw.Write(contents)
			if err != nil {
				tw.Close()
				return nil, err
			}
		}
		tw.Close()
		layerTarBlob := layerBuffer.Bytes()
		h := sha256.New()
		h.Write(layerTarBlob)
		hashStr := hex.EncodeToString(h.Sum(nil))
		layerHashes = append(layerHashes, hashStr)
		err := ioutil.WriteFile(path.Join(destPath, hashStr), layerTarBlob, 0644)
		if err != nil {
			return nil, err
		}
	}
	return layerHashes, nil
}

func GenDocker22Config(destPath string, conf typesV2.ImageConfig, layerHashes []string) (string, error) {
	conf.RootFS = &typesV2.ImageConfigRootFS{}
	conf.RootFS.Type = "layers"
	for _, h := range layerHashes {
		conf.RootFS.DiffIDs = append(conf.RootFS.DiffIDs, "sha256:"+h)
	}
	confblob, err := json.Marshal(conf)
	if err != nil {
		return "", err
	}
	h := sha256.New()
	h.Write(confblob)
	hashStr := hex.EncodeToString(h.Sum(nil))
	err = ioutil.WriteFile(path.Join(destPath, hashStr), confblob, 0644)
	if err != nil {
		return "", err
	}
	return hashStr, nil
}

func GenDocker22Manifest(destPath, configHash string, layerHashes []string) error {
	getDigestSize := func(digest string) (int64, error) {
		fi, err := os.Stat(path.Join(destPath, digest))
		if err != nil {
			return 0, err
		}
		return fi.Size(), nil
	}

	configSize, err := getDigestSize(configHash)
	if err != nil {
		return err
	}

	manifest := &typesV2.ImageManifest{
		SchemaVersion: 2,
		MediaType:     common.MediaTypeDockerV22Manifest,
		Config: &typesV2.ImageManifestDigest{
			MediaType: common.MediaTypeDockerV22Config,
			Size:      int(configSize),
			Digest:    "sha256:" + configHash,
		},
	}
	for _, h := range layerHashes {
		layerSize, err := getDigestSize(h)
		if err != nil {
			return err
		}
		manifest.Layers = append(manifest.Layers,
			&typesV2.ImageManifestDigest{
				MediaType: common.MediaTypeDockerV22RootFS,
				Size:      int(layerSize),
				Digest:    "sha256:" + h,
			})
	}

	manblob, err := json.Marshal(manifest)
	if err != nil {
		return err
	}

	err = ioutil.WriteFile(path.Join(destPath, "manifest.json"), manblob, 0644)
	if err != nil {
		return err
	}
	return nil
}


================================================
FILE: lib/tests/server.go
================================================
package test

import (
	"fmt"
	"io"
	"net/http"
	"net/http/httptest"
	"os"
	"path"
	"strings"
	"testing"
)

func RunDockerRegistry(t *testing.T, imgPath, imgName, imgRef, manifestMediaType string) *httptest.Server {
	handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		t.Logf("path requested: %s", r.URL.Path)
		if r.URL.Path == "/v2/" {
			w.Header().Add("Docker-Distribution-API-Version", "registry/2.0")
			w.WriteHeader(http.StatusOK)
			return
		}
		if strings.Contains(r.URL.Path, "manifests") {
			GetManifest(t, w, r, imgPath, imgName, imgRef, manifestMediaType)
			return
		}
		if strings.Contains(r.URL.Path, "blobs") {
			GetBlob(t, w, r, imgPath, imgName, imgRef)
			return
		}
		t.Errorf("invalid path: %s", r.URL.Path)
	})
	server := httptest.NewServer(handler)
	return server
}

func GetManifest(t *testing.T, w http.ResponseWriter, r *http.Request, imgPath, imgName, imgRef, manifestMediaType string) {
	parsedImgName, parsedRef, err := parseURL("manifests", r.URL.Path)
	if err != nil {
		w.WriteHeader(http.StatusNotFound)
		t.Errorf("get manifest: error parsing path: %v", err)
		return
	}
	if parsedImgName != imgName {
		w.WriteHeader(http.StatusNotFound)
		t.Errorf("get manifest: invalid image name requested: %q", parsedImgName)
		return
	}
	if parsedRef != imgRef {
		w.WriteHeader(http.StatusNotFound)
		t.Errorf("get manifest: invalid image ref requested: %q", parsedImgName)
		return
	}
	manFile, err := os.Open(path.Join(imgPath, "manifest.json"))
	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		t.Errorf("get manifest: couldn't open manifest: %v", err)
		return
	}
	defer manFile.Close()
	w.Header().Add("content-type", manifestMediaType)
	_, err = io.Copy(w, manFile)
	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		t.Errorf("get manifest: couldn't copy manifest: %v", err)
		return
	}
}

func GetBlob(t *testing.T, w http.ResponseWriter, r *http.Request, imgPath, imgName, imgRef string) {
	parsedImgName, digest, err := parseURL("blobs", r.URL.Path)
	if err != nil {
		w.WriteHeader(http.StatusNotFound)
		t.Errorf("get blob: %v", err)
		return
	}
	digest = strings.TrimPrefix(digest, "sha256:")
	if parsedImgName != imgName {
		w.WriteHeader(http.StatusNotFound)
		t.Errorf("get blob: invalid image name requested: %s", parsedImgName)
		return
	}
	blobFile, err := os.Open(path.Join(imgPath, digest))
	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		t.Errorf("get blob: couldn't open manifest: %v", err)
		return
	}
	defer blobFile.Close()
	_, err = io.Copy(w, blobFile)
	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		t.Errorf("get blob: couldn't copy manifest: %v", err)
		return
	}
}

func parseURL(resource, input string) (string, string, error) {
	tokens := strings.Split(input, "/")
	tokLen := len(tokens)
	if tokLen < 5 {
		return "", "", fmt.Errorf("invalid number of tokens in path: %d", len(tokens))
	}
	if tokens[0] != "" {
		return "", "", fmt.Errorf("path parse error: tok0 = %s", tokens[0])
	}
	if tokens[1] != "v2" {
		return "", "", fmt.Errorf("path parse error: tok1 = %s", tokens[1])
	}
	if tokens[tokLen-2] != resource {
		return "", "", fmt.Errorf("path parse error: tok-2 = %s", tokens[tokLen-2])
	}
	return path.Join(tokens[2 : tokLen-2]...), tokens[tokLen-1], nil
}


================================================
FILE: lib/tests/v22_test.go
================================================
package test

import (
	"testing"

	"archive/tar"
	"fmt"
	"io/ioutil"
	"os"
	"path"
	"reflect"
	"strings"
	"time"

	docker2aci "github.com/appc/docker2aci/lib"
	d2acommon "github.com/appc/docker2aci/lib/common"
	"github.com/appc/docker2aci/lib/internal/typesV2"
	"github.com/appc/spec/aci"
	"github.com/appc/spec/schema"
	"github.com/appc/spec/schema/types"
)

const variableTestValue = "variant"

// osArchTuple is a placeholder for operating system name and respective
// supported architecture.
type osArchTuple struct {
	Os   string
	Arch string
}

// osArchTuples defines the list of Go os/arch pairs used to test the
// conversion of Docker images to ACIs.
var osArchTuples = []osArchTuple{
	{"linux", "amd64"},
	{"linux", "386"},
	{"linux", "arm64"},
	{"linux", "arm"},
	{"linux", "ppc64"},
	{"linux", "ppc64le"},
	{"linux", "s390x"},

	{"freebsd", "amd64"},
	{"freebsd", "386"},
	{"freebsd", "arm"},

	{"darwin", "amd64"},
	{"darwin", "386"},
}

// dockerImageConfig defines the common image configuration.
var dockerImageConfig = typesV2.ImageConfigConfig{
	User:       "",
	Memory:     12345,
	MemorySwap: 0,
	CpuShares:  9001,
	ExposedPorts: map[string]struct{}{
		"80": struct{}{},
	},
	Env: []string{
		"FOO=1",
	},
	Entrypoint: []string{
		"/bin/sh",
		"-c",
		"echo",
	},
	Cmd: []string{
		"foo",
	},
	Volumes:    nil,
	WorkingDir: "/",
}

// testDocker22Images generates the Docker images v22 for all supported
// os/arch pairs and calls the passed testing function.
func testDocker22Images(layers []Layer, fn func(Docker22Image)) {
	for _, tuple := range osArchTuples {
		config := typesV2.ImageConfig{
			Created:      "2016-06-02T21:43:31.291506236Z",
			Author:       "rkt developer <rkt-dev@googlegroups.com>",
			Architecture: tuple.Arch,
			OS:           tuple.Os,
			Config:       &dockerImageConfig,
		}

		// Create a new Docker image configuration and pass it to
		// the testing function.
		fn(Docker22Image{
			RepoTags: []string{"testimage:latest"},
			Layers:   layers,
			Config:   config,
		})
	}
}

func expectedManifest(registryUrl, imageName, imageOs, imageArch string) schema.ImageManifest {
	return schema.ImageManifest{
		ACKind:    types.ACKind("ImageManifest"),
		ACVersion: schema.AppContainerVersion,
		Name:      *types.MustACIdentifier("variant"),
		Labels: []types.Label{
			types.Label{
				Name:  *types.MustACIdentifier("arch"),
				Value: imageArch,
			},
			types.Label{
				Name:  *types.MustACIdentifier("os"),
				Value: imageOs,
			},
			types.Label{
				Name:  *types.MustACIdentifier("version"),
				Value: "v0.1.0",
			},
		},
		App: &types.App{
			Exec: []string{
				"/bin/sh",
				"-c",
				"echo",
				"foo",
			},
			User:  "0",
			Group: "0",
			Environment: []types.EnvironmentVariable{
				{
					Name:  "FOO",
					Value: "1",
				},
			},
			WorkingDirectory: "/",
			Ports: []types.Port{
				{
					Name:            "80",
					Protocol:        "tcp",
					Port:            80,
					Count:           1,
					SocketActivated: false,
				},
			},
		},
		Annotations: []types.Annotation{
			{
				Name:  *types.MustACIdentifier("author"),
				Value: "rkt developer <rkt-dev@googlegroups.com>",
			},
			{
				Name:  *types.MustACIdentifier("created"),
				Value: "2016-06-02T21:43:31.291506236Z",
			},
			{
				Name:  *types.MustACIdentifier("appc.io/docker/registryurl"),
				Value: registryUrl,
			},
			{
				Name:  *types.MustACIdentifier("appc.io/docker/repository"),
				Value: "docker2aci/dockerv22test",
			},
			{
				Name:  *types.MustACIdentifier("appc.io/docker/imageid"),
				Value: variableTestValue,
				// Different each testrun for unknown reasons
			},
			{
				Name:  *types.MustACIdentifier("appc.io/docker/manifesthash"),
				Value: variableTestValue,
			},
			{
				Name:  *types.MustACIdentifier("appc.io/docker/originalname"),
				Value: imageName,
			},
			{
				Name:  *types.MustACIdentifier("appc.io/docker/entrypoint"),
				Value: "[\"/bin/sh\",\"-c\",\"echo\"]",
			},
			{
				Name:  *types.MustACIdentifier("appc.io/docker/cmd"),
				Value: "[\"foo\"]",
			},
		},
	}
}

func fetchImage(imgName, outputDir string, squash bool) ([]string, error) {
	conversionTmpDir, err := ioutil.TempDir("", "docker2aci-test-")
	if err != nil {
		return nil, err
	}
	defer os.RemoveAll(conversionTmpDir)

	conf := docker2aci.RemoteConfig{
		CommonConfig: docker2aci.CommonConfig{
			Squash:      squash,
			OutputDir:   outputDir,
			TmpDir:      conversionTmpDir,
			Compression: d2acommon.GzipCompression,
		},
		Username: "",
		Password: "",
		Insecure: d2acommon.InsecureConfig{
			SkipVerify: true,
			AllowHTTP:  true,
		},
	}

	return docker2aci.ConvertRemoteRepo(imgName, conf)
}

func TestFetchingByTagV22(t *testing.T) {
	layers := []Layer{
		Layer{
			&tar.Header{
				Name:    "thisisafile",
				Mode:    0644,
				ModTime: time.Now(),
			}: []byte("these are its contents"),
		},
	}

	testDocker22Images(layers, func(img Docker22Image) {
		tmpDir, err := ioutil.TempDir("", "docker2aci-test-")
		if err != nil {
			t.Fatalf("%v", err)
		}
		defer os.RemoveAll(tmpDir)

		err = GenerateDocker22(tmpDir, img)
		if err != nil {
			t.Fatalf("%v", err)
		}
		imgName := "docker2aci/dockerv22test"
		imgRef := "v0.1.0"
		server := RunDockerRegistry(t, tmpDir, imgName, imgRef, d2acommon.MediaTypeDockerV22Manifest)
		defer server.Close()

		bareServerURL := strings.TrimPrefix(server.URL, "http://")
		localUrl := path.Join(bareServerURL, imgName) + ":" + imgRef

		// Convert the Docker image os/arch pair into values compatible
		// with application container image specification.
		imgOs, imgArch := img.Config.OS, img.Config.Architecture
		imgOs, imgArch, err = types.ToAppcOSArch(imgOs, imgArch, "")
		if err != nil {
			t.Errorf("unexpected error: %v", err)
		}

		expectedImageManifest := expectedManifest(bareServerURL, localUrl, imgOs, imgArch)

		outputDir, err := ioutil.TempDir("", "docker2aci-test-")
		if err != nil {
			t.Fatalf("%v", err)
		}
		defer os.RemoveAll(outputDir)

		acis, err := fetchImage(localUrl, outputDir, true)
		if err != nil {
			t.Fatalf("%v", err)
		}

		converted := acis[0]

		f, err := os.Open(converted)
		if err != nil {
			t.Fatalf("%v", err)
		}
		defer f.Close()

		manifest, err := aci.ManifestFromImage(f)
		if err != nil {
			t.Fatalf("%v", err)
		}

		if err := manifestEqual(manifest, &expectedImageManifest); err != nil {
			t.Errorf("manifest doesn't match expected manifest: %v", err)
		}
	})
}

func manifestEqual(manifest, expected *schema.ImageManifest) error {
	if manifest.ACKind != expected.ACKind {
		return fmt.Errorf("expected ACKind %q, got %q", expected.ACKind, manifest.ACKind)
	}

	if manifest.ACVersion != expected.ACVersion {
		return fmt.Errorf("expected ACVersion %q, got %q", expected.ACVersion, manifest.ACVersion)
	}

	if !reflect.DeepEqual(*manifest.App, *expected.App) {
		return fmt.Errorf("expected App %v, got %v", *expected.App, *manifest.App)
	}

	if len(manifest.Labels) != len(expected.Labels) {
		return fmt.Errorf("Labels not equal: %v != %v", manifest.Labels, expected.Labels)
	}

	for _, label := range manifest.Labels {
		el, ok := expected.Labels.Get(label.Name.String())
		if !ok {
			return fmt.Errorf("expected label %v to exist, did not", label.Name)
		}
		if label.Value != el {
			return fmt.Errorf("expected label %v values to match, but %v != %v", label.Name, el, label.Value)
		}
	}

	if len(manifest.Annotations) != len(expected.Annotations) {
		return fmt.Errorf("annotations not equal: %v != %v", manifest.Annotations, expected.Annotations)
	}
	for _, ann := range manifest.Annotations {
		ea, ok := expected.Annotations.Get(ann.Name.String())
		if ea == variableTestValue {
			// marker to let us know we don't have to assert on this value; skip it
			continue
		}
		if !ok {
			return fmt.Errorf("expected annotation %v to exist, did not", ann.Name)
		}
		if ea != ann.Value {
			return fmt.Errorf("expected annotation %v values to match, but %v != %v", ann.Name, ea, ann.Value)
		}
	}

	return nil
}

func TestFetchingByDigestV22(t *testing.T) {
	layers := []Layer{
		Layer{
			&tar.Header{
				Name:    "thisisafile",
				Mode:    0644,
				ModTime: time.Now(),
			}: []byte("these are its contents"),
		},
	}

	testDocker22Images(layers, func(img Docker22Image) {
		tmpDir, err := ioutil.TempDir("", "docker2aci-test-")
		if err != nil {
			t.Fatalf("%v", err)
		}
		defer os.RemoveAll(tmpDir)

		err = GenerateDocker22(tmpDir, img)
		if err != nil {
			t.Fatalf("%v", err)
		}
		imgName := "docker2aci/dockerv22test"
		imgRef := "sha256:45b23dee08af5e43a7fea6c4cf9c25ccf269ee113168c19722f87876677c5cb2"
		server := RunDockerRegistry(t, tmpDir, imgName, imgRef, d2acommon.MediaTypeDockerV22Manifest)
		defer server.Close()

		localUrl := path.Join(strings.TrimPrefix(server.URL, "http://"), imgName) + "@" + imgRef

		outputDir, err := ioutil.TempDir("", "docker2aci-test-")
		if err != nil {
			t.Fatalf("%v", err)
		}
		defer os.RemoveAll(outputDir)

		_, err = fetchImage(localUrl, outputDir, true)
		if err != nil {
			t.Fatalf("%v", err)
		}
	})
}

func TestFetchingMultipleLayersV22(t *testing.T) {
	layers := []Layer{
		Layer{
			&tar.Header{
				Name:    "thisisafile",
				Mode:    0644,
				ModTime: time.Now(),
			}: []byte("these are its contents"),
		},
		Layer{
			&tar.Header{
				Name:    "thisisadifferentfile",
				Mode:    0644,
				ModTime: time.Now(),
			}: []byte("the contents of this file are different from the last!"),
		},
	}

	testDocker22Images(layers, func(img Docker22Image) {
		tmpDir, err := ioutil.TempDir("", "docker2aci-test-")
		if err != nil {
			t.Fatalf("%v", err)
		}
		defer os.RemoveAll(tmpDir)

		err = GenerateDocker22(tmpDir, img)
		if err != nil {
			t.Fatalf("%v", err)
		}
		imgName := "docker2aci/dockerv22test"
		imgRef := "v0.1.0"
		server := RunDockerRegistry(t, tmpDir, imgName, imgRef, d2acommon.MediaTypeDockerV22Manifest)
		defer server.Close()

		localUrl := path.Join(strings.TrimPrefix(server.URL, "http://"), imgName) + ":" + imgRef

		outputDir, err := ioutil.TempDir("", "docker2aci-test-")
		if err != nil {
			t.Fatalf("%v", err)
		}
		defer os.RemoveAll(outputDir)

		_, err = fetchImage(localUrl, outputDir, true)
		if err != nil {
			t.Fatalf("%v", err)
		}
	})
}


================================================
FILE: lib/version.go
================================================
// Copyright 2016 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package docker2aci

import "github.com/appc/spec/schema"

var Version = "0.17.2+git"
var AppcVersion = schema.AppContainerVersion


================================================
FILE: main.go
================================================
// Copyright 2015 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"flag"
	"fmt"
	"net/url"
	"os"
	"strings"

	"github.com/appc/docker2aci/lib"
	"github.com/appc/docker2aci/lib/common"
	"github.com/appc/docker2aci/pkg/log"

	"github.com/appc/spec/aci"
	"github.com/appc/spec/schema"
)

var (
	flagNoSquash           bool
	flagImage              string
	flagDebug              bool
	flagInsecureSkipVerify bool
	flagInsecureAllowHTTP  bool
	flagCompression        string
	flagVersion            bool
)

func init() {
	flag.BoolVar(&flagNoSquash, "nosquash", false, "Don't squash layers and output every layer as ACI")
	flag.StringVar(&flagImage, "image", "", "When converting a local file, it selects a particular image to convert. Format: IMAGE_NAME[:TAG]")
	flag.BoolVar(&flagDebug, "debug", false, "Enables debug messages")
	flag.BoolVar(&flagInsecureSkipVerify, "insecure-skip-verify", false, "Don't verify certificates when fetching images")
	flag.BoolVar(&flagInsecureAllowHTTP, "insecure-allow-http", false, "Uses unencrypted connections when fetching images")
	flag.StringVar(&flagCompression, "compression", "gzip", "Type of compression to use; allowed values: gzip, none")
	flag.BoolVar(&flagVersion, "version", false, "Print version")
}

func printVersion() {
	fmt.Println("docker2aci version", docker2aci.Version)
	fmt.Println("appc version", docker2aci.AppcVersion)
}

func runDocker2ACI(arg string) error {
	debug := log.NewNopLogger()
	info := log.NewStdLogger(os.Stderr)

	if flagDebug {
		debug = log.NewStdLogger(os.Stderr)
	}

	squash := !flagNoSquash

	var aciLayerPaths []string
	// try to convert a local file
	u, err := url.Parse(arg)
	if err != nil {
		return fmt.Errorf("error parsing argument: %v", err)
	}

	var compression common.Compression

	switch flagCompression {
	case "none":
		compression = common.NoCompression
	case "gzip":
		compression = common.GzipCompression
	default:
		return fmt.Errorf("unknown compression method: %s", flagCompression)
	}

	cfg := docker2aci.CommonConfig{
		Squash:      squash,
		OutputDir:   ".",
		TmpDir:      os.TempDir(),
		Compression: compression,
		Debug:       debug,
		Info:        info,
	}
	if u.Scheme == "docker" {
		if flagImage != "" {
			return fmt.Errorf("flag --image works only with files.")
		}
		dockerURL := strings.TrimPrefix(arg, "docker://")

		indexServer := docker2aci.GetIndexName(dockerURL)

		var username, password string
		username, password, err = docker2aci.GetDockercfgAuth(indexServer)
		if err != nil {
			return fmt.Errorf("error reading .dockercfg file: %v", err)
		}
		remoteConfig := docker2aci.RemoteConfig{
			CommonConfig: cfg,
			Username:     username,
			Password:     password,
			Insecure: common.InsecureConfig{
				SkipVerify: flagInsecureSkipVerify,
				AllowHTTP:  flagInsecureAllowHTTP,
			},
		}

		aciLayerPaths, err = docker2aci.ConvertRemoteRepo(dockerURL, remoteConfig)
	} else {
		fileConfig := docker2aci.FileConfig{
			CommonConfig: cfg,
			DockerURL:    flagImage,
		}
		aciLayerPaths, err = docker2aci.ConvertSavedFile(arg, fileConfig)
		if serr, ok := err.(*common.ErrSeveralImages); ok {
			err = fmt.Errorf("%s, use option --image with one of:\n\n%s", serr, strings.Join(serr.Images, "\n"))
		}
	}
	if err != nil {
		return fmt.Errorf("conversion error: %v", err)
	}

	// we get last layer's manifest, this will include all the elements in the
	// previous layers. If we're squashing, the last element of aciLayerPaths
	// will be the squashed image.
	manifest, err := getManifest(aciLayerPaths[len(aciLayerPaths)-1])
	if err != nil {
		return err
	}

	printConvertedVolumes(*manifest)
	printConvertedPorts(*manifest)

	fmt.Printf("\nGenerated ACI(s):\n")
	for _, aciFile := range aciLayerPaths {
		fmt.Println(aciFile)
	}

	return nil
}

func printConvertedVolumes(manifest schema.ImageManifest) {
	if manifest.App == nil {
		return
	}
	if mps := manifest.App.MountPoints; len(mps) > 0 {
		fmt.Printf("\nConverted volumes:\n")
		for _, mp := range mps {
			fmt.Printf("\tname: %q, path: %q, readOnly: %v\n", mp.Name, mp.Path, mp.ReadOnly)
		}
	}
}

func printConvertedPorts(manifest schema.ImageManifest) {
	if manifest.App == nil {
		return
	}
	if ports := manifest.App.Ports; len(ports) > 0 {
		fmt.Printf("\nConverted ports:\n")
		for _, port := range ports {
			fmt.Printf("\tname: %q, protocol: %q, port: %v, count: %v, socketActivated: %v\n",
				port.Name, port.Protocol, port.Port, port.Count, port.SocketActivated)
		}
	}
}

func getManifest(aciPath string) (*schema.ImageManifest, error) {
	f, err := os.Open(aciPath)
	if err != nil {
		return nil, fmt.Errorf("error opening converted image: %v", err)
	}
	defer f.Close()

	manifest, err := aci.ManifestFromImage(f)
	if err != nil {
		return nil, fmt.Errorf("error reading manifest from converted image: %v", err)
	}

	return manifest, nil
}

func usage() {
	fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
	fmt.Fprintf(os.Stderr, "docker2aci [-debug] [-nosquash] [-compression=(gzip|none)] IMAGE\n")
	fmt.Fprintf(os.Stderr, "  Where IMAGE is\n")
	fmt.Fprintf(os.Stderr, "    [-image=IMAGE_NAME[:TAG]] FILEPATH\n")
	fmt.Fprintf(os.Stderr, "  or\n")
	fmt.Fprintf(os.Stderr, "    docker://[REGISTRYURL/]IMAGE_NAME[:TAG]\n")
	fmt.Fprintf(os.Stderr, "Flags:\n")
	flag.PrintDefaults()
}

func main() {
	flag.Usage = usage
	flag.Parse()
	args := flag.Args()

	if flagVersion {
		printVersion()
		return
	}

	if len(args) != 1 {
		usage()
		os.Exit(2)
	}

	if err := runDocker2ACI(args[0]); err != nil {
		fmt.Fprintf(os.Stderr, "Error: %v\n", err)
		os.Exit(1)
	}
}


================================================
FILE: pkg/log/log.go
================================================
// Copyright 2016 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package log

import (
	"io"
	stdlog "log"
)

// Logger is the interface that enables logging.
// It is compatible with the stdlib "log" methods.
// It is also compatible with https://godoc.org/github.com/Sirupsen/logrus#StdLogger.
type Logger interface {
	Print(...interface{})
	Printf(string, ...interface{})
	Println(...interface{})
}

func NewStdLogger(out io.Writer) Logger {
	return stdlog.New(out, "", 0)
}

type nopLogger struct{}

func NewNopLogger() Logger {
	return &nopLogger{}
}

func (l *nopLogger) Print(...interface{}) {
	// nop
}

func (l *nopLogger) Printf(string, ...interface{}) {
	// nop
}

func (l *nopLogger) Println(...interface{}) {
	// nop
}


================================================
FILE: scripts/bump-release
================================================
#!/bin/bash -e
#
# Attempt to bump the docker2aci release to the specified version by replacing
# all occurrences of the current/previous version.
#
# Generates two commits: the release itself and the bump to the next +git
# version
#
# YMMV, no disclaimer or warranty, etc.

# make sure we are running in a toplevel directory
if ! [[ "$0" =~ "scripts/bump-release" ]]; then
	echo "This script must be run in a toplevel docker2aci directory"
	exit 255
fi

if ! [[ "$1" =~ ^v[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]$ ]]; then
	echo "Usage: scripts/bump-release <VERSION>"
	echo "   where VERSION must be vX.Y.Z"
	exit 255
fi

function replace_stuff() {
	local FROM
	local TO
	local REPLACE

	FROM=$1
	TO=$2
	# escape special characters
	REPLACE=$(sed -e 's/[]\/$*.^|[]/\\&/g'<<< $FROM)
	shift 2
	echo $* | xargs sed -i --follow-symlinks -e "s/$REPLACE/$TO/g"
}

function replace_version() {
	replace_stuff $1 $2 lib/version.go
}

NEXT=${1:1} 	        # 0.2.3
NEXTGIT="${NEXT}+git"   # 0.2.3+git

PREVGIT=$(grep -Po 'var Version = "\K[^"]*(?=")' lib/version.go) # 0.1.2+git
PREV=${PREVGIT::-4}     # 0.1.2

replace_version $PREVGIT $NEXT
git commit -am "version: bump to v${NEXT}"

replace_version $NEXT $NEXTGIT
git commit -am "version: bump to v${NEXTGIT}"


================================================
FILE: scripts/glide-update
================================================
#!/usr/bin/env bash
set -e

if ! [[ "$0" =~ "scripts/glide-update"  ]]; then
  echo "must be run from repository root"
  exit 255
fi

if [ ! $(command -v glide)  ]; then
  echo "glide: command not found"
  exit 255
fi

if [ ! $(command -v glide-vc)  ]; then
  echo "glide-vc: command not found"
  exit 255
fi

glide update --strip-vendor
glide-vc --only-code --no-tests --no-test-imports --use-lock-file


================================================
FILE: tests/README.md
================================================
# docker2aci tests

## Semaphore

The tests run on the [Semaphore](https://semaphoreci.com/) CI system.

The tests are executed on Semaphore at each Pull Request (PR).
Each GitHub PR page should have a link to the [test results on Semaphore](https://semaphoreci.com/appc/docker2aci).

### Build settings

The tests will run on two VMs.
The "Setup" and "Post thread" sections will be executed on both VMs.
The "Thread 1" and "Thread 2" will be executed in parallel in separate VMs.

#### Setup

```
./build.sh
```

#### Thread 1

```
./tests/test.sh
```

### Platform

Select `Ubuntu 14.04 LTS v1503 (beta with Docker support)`.
The platform with *Docker support* means the tests will run in a VM.



================================================
FILE: tests/fixture-test-depsloop/check.sh
================================================
#!/bin/sh

DOCKER2ACI=../bin/docker2aci
TESTDIR=$1
TESTNAME=$2

timeout 10s ${DOCKER2ACI} "${TESTDIR}/${TESTNAME}/${TESTNAME}.docker"
if [ $? -eq 1 ]; then
	echo "### Test case ${TESTNAME}: SUCCESS"
	exit 0
else
	echo "### Test case ${TESTNAME}: FAIL"
	exit 1
fi



================================================
FILE: tests/fixture-test-invalidlayerid/check.sh
================================================
#!/bin/sh

DOCKER2ACI=../bin/docker2aci
TESTDIR=$1
TESTNAME=$2

sudo ${DOCKER2ACI} "${TESTDIR}/${TESTNAME}/${TESTNAME}.docker"
if [ $? -eq 1 ]; then
	echo "### Test case ${TESTNAME}: SUCCESS"
	exit 0
else
	echo "### Test case ${TESTNAME}: FAIL"
	exit 1
fi



================================================
FILE: tests/rkt-v1.1.0.md5sum
================================================
MD5 (rkt-v1.1.0.tar.gz) = d3d9d62429e53d8f631dbec93e4e719f


================================================
FILE: tests/test-basic/Dockerfile
================================================
FROM busybox
COPY check.sh /
RUN echo file1 > file1 ; ln file1 file2
RUN echo file3 > file3
RUN echo file4 > file4
CMD /check.sh 2>&1


================================================
FILE: tests/test-basic/check.sh
================================================
#!/bin/sh
set -e
set -x

grep -q file1 file1
grep -q file1 file2
grep -q file3 file3
grep -q file4 file4
if [ "$CHECK" != "rkt-rendered" ] ; then
	# Skip this test because of:
	# https://github.com/coreos/rkt/issues/1774
	test $(ls -i file1 |awk '{print $1}') -eq $(ls -i file2 |awk '{print $1}')
	test $(ls -i file3 |awk '{print $1}') -ne $(ls -i file4 |awk '{print $1}')
fi
echo "SUCCESS"


================================================
FILE: tests/test-pwl/Dockerfile
================================================
FROM gcr.io/google_containers/nginx:1.7.9
COPY check.sh /
ENTRYPOINT /check.sh 2>&1


================================================
FILE: tests/test-pwl/check.sh
================================================
#!/bin/sh
set -e
set -x

ls -l /var/run
echo "SUCCESS"


================================================
FILE: tests/test-whiteouts/Dockerfile
================================================
FROM busybox
COPY check.sh /

RUN echo yes > layer0-file1 ; ln layer0-file1 layer0-file2 ; ln layer0-file1 layer0-file3
RUN echo yes > layer1-file1 ; ln layer1-file1 layer1-file2 ; ln layer1-file1 layer1-file3
RUN echo yes > layer2-file1 ; ln layer2-file1 layer2-file2 ; ln layer2-file1 layer2-file3
RUN echo yes > layer3-file1 ; ln layer3-file1 layer3-file2 ; ln layer3-file1 layer3-file3
RUN rm -f layer1-file1 layer2-file2 layer3-file3

RUN echo yes > layer4-file1 ; ln layer4-file1 layer4-file2 ; ln layer4-file1 layer4-file3
RUN echo yes > layer5-file1 ; ln layer5-file1 layer5-file2 ; ln layer5-file1 layer5-file3
RUN echo yes > layer6-file1 ; ln layer6-file1 layer6-file2 ; ln layer6-file1 layer6-file3
RUN rm -f layer4-file2 layer5-file1 layer6-file1 layer4-file3 layer5-file3 layer6-file2

RUN echo OLD > layer10-file1 ; ln layer10-file1 layer10-file2 ; ln layer10-file1 layer10-file3
RUN echo NEW > layer10-file1 ; ln -f layer10-file1 layer10-file2 ; ln -f layer10-file1 layer10-file3 ; echo foo > foo

RUN echo line1 >  layer11-file1 ; ln layer11-file1 layer11-file2 ; ln layer11-file1 layer11-file3
RUN echo line2 >> layer11-file1

CMD /check.sh 2>&1


================================================
FILE: tests/test-whiteouts/check.sh
================================================
#!/bin/sh
set -e
set -x

grep -q yes layer0-file1
grep -q yes layer0-file2
grep -q yes layer0-file3

test ! -e layer1-file1
test   -e layer1-file2
test   -e layer1-file3

test   -e layer2-file1
test ! -e layer2-file2
test   -e layer2-file3

test   -e layer3-file1
test   -e layer3-file2
test ! -e layer3-file3

grep -q yes layer1-file2
grep -q yes layer1-file3

grep -q yes layer2-file1
grep -q yes layer2-file3

grep -q yes layer3-file1
grep -q yes layer3-file2


test   -e layer4-file1
test ! -e layer4-file2
test ! -e layer4-file3

test ! -e layer5-file1
test   -e layer5-file2
test ! -e layer5-file3

test ! -e layer6-file1
test ! -e layer6-file2
test   -e layer6-file3

grep -q yes layer4-file1
grep -q yes layer5-file2
grep -q yes layer6-file3


grep -q NEW layer10-file1
grep -q NEW layer10-file2
grep -q NEW layer10-file3

grep -q line1 layer11-file1
grep -q line1 layer11-file2
grep -q line1 layer11-file3

# # Docker with AUFS or overlay storage backend does not handle this test
# # correctly and Semaphore uses AUFS
if [ "$DOCKER_STORAGE_BACKEND" == devicemapper ] ; then
	grep -q line2 layer11-file1
	grep -q line2 layer11-file2
	grep -q line2 layer11-file3
	cmp layer11-file1 layer11-file2
	cmp layer11-file1 layer11-file3
fi

echo "SUCCESS"


================================================
FILE: tests/test.sh
================================================
#!/bin/bash

set -e

# Gets the parent of the directory that this script is stored in.
# https://stackoverflow.com/questions/59895/can-a-bash-script-tell-what-directory-its-stored-in
DIR="$( cd "$( dirname $( dirname "${BASH_SOURCE[0]}" ) )" && pwd )"

ORG_PATH="github.com/appc"
REPO_PATH="${ORG_PATH}/docker2aci"

if [ ! -h ${DIR}/gopath/src/${REPO_PATH} ]; then
  mkdir -p ${DIR}/gopath/src/${ORG_PATH}
  cd ${DIR} && ln -s ../../../.. gopath/src/${REPO_PATH} || exit 255
fi

export GO15VENDOREXPERIMENT=1
export GOPATH=${DIR}/gopath
REPO_GOPATH="${GOPATH}/src/${REPO_PATH}"

cd "${REPO_GOPATH}"

go vet ./pkg/...
go vet ./lib/...
go test -v ${REPO_PATH}/lib/tests
go test -v ${REPO_PATH}/lib/internal
go test -v ${REPO_PATH}/lib/common

DOCKER2ACI=../bin/docker2aci
PREFIX=docker2aci-tests
TESTDIR="${REPO_GOPATH}/tests/"
RKTVERSION=v1.1.0

cd $TESTDIR

# install rkt in Semaphore
if ! which rkt > /dev/null ; then
	if [ "$SEMAPHORE" != "true" ] ; then
		echo "Please install rkt"
		exit 1
	fi
	pushd $SEMAPHORE_CACHE_DIR
	if ! md5sum -c $TESTDIR/rkt-$RKTVERSION.md5sum; then
		wget https://github.com/coreos/rkt/releases/download/$RKTVERSION/rkt-$RKTVERSION.tar.gz
	fi
	md5sum -c $TESTDIR/rkt-$RKTVERSION.md5sum
	tar xf rkt-$RKTVERSION.tar.gz
	export PATH=$PATH:$PWD/rkt-$RKTVERSION/
	popd
fi
RKT=$(which rkt)

DOCKER_STORAGE_BACKEND=$(sudo docker info|grep '^Storage Driver:'|sed 's/Storage Driver: //')

for i in $(find . -maxdepth 1 -type d -name 'fixture-test*') ; do
	  TESTNAME=$(basename $i)
	  echo "### Test case ${TESTNAME}..."
	  $TESTDIR/${TESTNAME}/check.sh "${TESTDIR}" "${TESTNAME}"
done

for i in $(find . -maxdepth 1 -type d -name 'test-*') ; do
	TESTNAME=$(basename $i)
	echo "### Test case ${TESTNAME}: build..."
	sudo docker build --tag=$PREFIX/${TESTNAME} --no-cache=true ${TESTNAME}

	echo "### Test case ${TESTNAME}: test in Docker..."
	sudo docker run --rm \
	                --env=CHECK=docker-run \
	                --env=DOCKER_STORAGE_BACKEND=$DOCKER_STORAGE_BACKEND \
	                $PREFIX/${TESTNAME}

	echo "### Test case ${TESTNAME}: converting to ACI..."
	sudo docker save -o ${TESTNAME}.docker $PREFIX/${TESTNAME}
	# Docker now writes files as root, so make them readable
	sudo chmod o+rx ${TESTNAME}.docker
	$DOCKER2ACI ${TESTNAME}.docker

	echo "### Test case ${TESTNAME}: test in rkt..."
	sudo $RKT prepare --insecure-options=image \
	                  --set-env=CHECK=rkt-run \
	                  --set-env=DOCKER_STORAGE_BACKEND=$DOCKER_STORAGE_BACKEND \
	                  ./${PREFIX}-${TESTNAME}-latest.aci \
	                  > rkt-uuid-${TESTNAME}
	sudo $RKT run-prepared $(cat rkt-uuid-${TESTNAME})
	sudo $RKT status $(cat rkt-uuid-${TESTNAME}) | grep app-${TESTNAME}=0
	sudo $RKT rm $(cat rkt-uuid-${TESTNAME})

	echo "### Test case ${TESTNAME}: test with 'rkt image render'..."
	sudo $RKT image render --overwrite ${PREFIX}/${TESTNAME} ./rendered-${TESTNAME}
	pushd rendered-${TESTNAME}/rootfs
	CHECK=rkt-rendered DOCKER_STORAGE_BACKEND=$DOCKER_STORAGE_BACKEND $TESTDIR/${TESTNAME}/check.sh
	popd
	echo "### Test case ${TESTNAME}: SUCCESS"

	sudo docker rmi $PREFIX/${TESTNAME}
done


================================================
FILE: vendor/github.com/appc/spec/LICENSE
================================================
Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          w
Download .txt
gitextract_sbk4zkuw/

├── .gitignore
├── CHANGELOG.md
├── Documentation/
│   └── devel/
│       └── release.md
├── LICENSE
├── MAINTAINERS
├── README.md
├── build.sh
├── glide.yaml
├── lib/
│   ├── common/
│   │   ├── common.go
│   │   └── common_test.go
│   ├── conversion_store.go
│   ├── docker2aci.go
│   ├── internal/
│   │   ├── backend/
│   │   │   ├── file/
│   │   │   │   └── file.go
│   │   │   └── repository/
│   │   │       ├── repository.go
│   │   │       ├── repository1.go
│   │   │       └── repository2.go
│   │   ├── docker/
│   │   │   └── docker.go
│   │   ├── internal.go
│   │   ├── internal_test.go
│   │   ├── tarball/
│   │   │   ├── tarfile.go
│   │   │   └── walk.go
│   │   ├── types/
│   │   │   └── docker_types.go
│   │   ├── typesV2/
│   │   │   └── docker_types.go
│   │   └── util/
│   │       └── util.go
│   ├── tests/
│   │   ├── common.go
│   │   ├── server.go
│   │   └── v22_test.go
│   └── version.go
├── main.go
├── pkg/
│   └── log/
│       └── log.go
├── scripts/
│   ├── bump-release
│   └── glide-update
├── tests/
│   ├── README.md
│   ├── fixture-test-depsloop/
│   │   ├── check.sh
│   │   └── fixture-test-depsloop.docker
│   ├── fixture-test-invalidlayerid/
│   │   ├── check.sh
│   │   └── fixture-test-invalidlayerid.docker
│   ├── rkt-v1.1.0.md5sum
│   ├── test-basic/
│   │   ├── Dockerfile
│   │   └── check.sh
│   ├── test-pwl/
│   │   ├── Dockerfile
│   │   └── check.sh
│   ├── test-whiteouts/
│   │   ├── Dockerfile
│   │   └── check.sh
│   └── test.sh
└── vendor/
    ├── github.com/
    │   ├── appc/
    │   │   └── spec/
    │   │       ├── LICENSE
    │   │       ├── aci/
    │   │       │   ├── build.go
    │   │       │   ├── doc.go
    │   │       │   ├── file.go
    │   │       │   ├── layout.go
    │   │       │   └── writer.go
    │   │       ├── pkg/
    │   │       │   ├── acirenderer/
    │   │       │   │   ├── acirenderer.go
    │   │       │   │   └── resolve.go
    │   │       │   ├── device/
    │   │       │   │   ├── device_linux.go
    │   │       │   │   └── device_posix.go
    │   │       │   └── tarheader/
    │   │       │       ├── doc.go
    │   │       │       ├── pop_darwin.go
    │   │       │       ├── pop_linux.go
    │   │       │       ├── pop_posix.go
    │   │       │       └── tarheader.go
    │   │       └── schema/
    │   │           ├── common/
    │   │           │   └── common.go
    │   │           ├── doc.go
    │   │           ├── image.go
    │   │           ├── kind.go
    │   │           ├── pod.go
    │   │           ├── types/
    │   │           │   ├── acidentifier.go
    │   │           │   ├── ackind.go
    │   │           │   ├── acname.go
    │   │           │   ├── annotations.go
    │   │           │   ├── app.go
    │   │           │   ├── date.go
    │   │           │   ├── dependencies.go
    │   │           │   ├── doc.go
    │   │           │   ├── environment.go
    │   │           │   ├── errors.go
    │   │           │   ├── event_handler.go
    │   │           │   ├── exec.go
    │   │           │   ├── hash.go
    │   │           │   ├── isolator.go
    │   │           │   ├── isolator_linux_specific.go
    │   │           │   ├── isolator_resources.go
    │   │           │   ├── isolator_unix.go
    │   │           │   ├── labels.go
    │   │           │   ├── mountpoint.go
    │   │           │   ├── port.go
    │   │           │   ├── resource/
    │   │           │   │   ├── amount.go
    │   │           │   │   ├── math.go
    │   │           │   │   ├── quantity.go
    │   │           │   │   ├── scale_int.go
    │   │           │   │   └── suffix.go
    │   │           │   ├── semver.go
    │   │           │   ├── url.go
    │   │           │   ├── user_annotations.go
    │   │           │   ├── user_labels.go
    │   │           │   ├── uuid.go
    │   │           │   └── volume.go
    │   │           └── version.go
    │   ├── coreos/
    │   │   ├── go-semver/
    │   │   │   ├── LICENSE
    │   │   │   ├── example.go
    │   │   │   └── semver/
    │   │   │       ├── semver.go
    │   │   │       └── sort.go
    │   │   ├── ioprogress/
    │   │   │   ├── LICENSE
    │   │   │   ├── draw.go
    │   │   │   └── reader.go
    │   │   └── pkg/
    │   │       ├── LICENSE
    │   │       ├── NOTICE
    │   │       └── progressutil/
    │   │           ├── iocopy.go
    │   │           └── progressbar.go
    │   ├── docker/
    │   │   └── distribution/
    │   │       ├── LICENSE
    │   │       ├── blobs.go
    │   │       ├── digestset/
    │   │       │   └── set.go
    │   │       ├── doc.go
    │   │       ├── errors.go
    │   │       ├── manifests.go
    │   │       ├── reference/
    │   │       │   ├── helpers.go
    │   │       │   ├── normalize.go
    │   │       │   ├── reference.go
    │   │       │   └── regexp.go
    │   │       ├── registry.go
    │   │       └── tags.go
    │   ├── klauspost/
    │   │   ├── compress/
    │   │   │   ├── LICENSE
    │   │   │   └── flate/
    │   │   │       ├── copy.go
    │   │   │       ├── crc32_amd64.go
    │   │   │       ├── crc32_amd64.s
    │   │   │       ├── crc32_noasm.go
    │   │   │       ├── deflate.go
    │   │   │       ├── dict_decoder.go
    │   │   │       ├── gen.go
    │   │   │       ├── huffman_bit_writer.go
    │   │   │       ├── huffman_code.go
    │   │   │       ├── inflate.go
    │   │   │       ├── reverse_bits.go
    │   │   │       ├── snappy.go
    │   │   │       └── token.go
    │   │   ├── cpuid/
    │   │   │   ├── LICENSE
    │   │   │   ├── cpuid.go
    │   │   │   ├── cpuid_386.s
    │   │   │   ├── cpuid_amd64.s
    │   │   │   ├── detect_intel.go
    │   │   │   ├── detect_ref.go
    │   │   │   ├── generate.go
    │   │   │   └── private-gen.go
    │   │   ├── crc32/
    │   │   │   ├── LICENSE
    │   │   │   ├── crc32.go
    │   │   │   ├── crc32_amd64.go
    │   │   │   ├── crc32_amd64.s
    │   │   │   ├── crc32_amd64p32.go
    │   │   │   ├── crc32_amd64p32.s
    │   │   │   └── crc32_generic.go
    │   │   └── pgzip/
    │   │       ├── LICENSE
    │   │       ├── gunzip.go
    │   │       └── gzip.go
    │   ├── opencontainers/
    │   │   ├── go-digest/
    │   │   │   ├── LICENSE.code
    │   │   │   ├── LICENSE.docs
    │   │   │   ├── algorithm.go
    │   │   │   ├── digest.go
    │   │   │   ├── digester.go
    │   │   │   ├── doc.go
    │   │   │   └── verifiers.go
    │   │   └── image-spec/
    │   │       ├── LICENSE
    │   │       └── specs-go/
    │   │           ├── v1/
    │   │           │   ├── config.go
    │   │           │   ├── descriptor.go
    │   │           │   ├── manifest.go
    │   │           │   ├── manifest_list.go
    │   │           │   └── mediatype.go
    │   │           ├── version.go
    │   │           └── versioned.go
    │   └── spf13/
    │       └── pflag/
    │           ├── LICENSE
    │           └── flag.go
    ├── go4.org/
    │   ├── LICENSE
    │   └── errorutil/
    │       └── highlight.go
    ├── golang.org/
    │   └── x/
    │       └── crypto/
    │           ├── LICENSE
    │           ├── PATENTS
    │           └── ssh/
    │               └── terminal/
    │                   ├── terminal.go
    │                   ├── util.go
    │                   ├── util_bsd.go
    │                   ├── util_linux.go
    │                   └── util_windows.go
    └── gopkg.in/
        └── inf.v0/
            ├── LICENSE
            ├── dec.go
            └── rounder.go
Download .txt
SYMBOL INDEX (1736 symbols across 127 files)

FILE: lib/common/common.go
  type Compression (line 28) | type Compression
  constant NoCompression (line 31) | NoCompression = iota
  constant GzipCompression (line 32) | GzipCompression
  constant AppcDockerOriginalName (line 45) | AppcDockerOriginalName  = "appc.io/docker/originalname"
  constant AppcDockerRegistryURL (line 46) | AppcDockerRegistryURL   = "appc.io/docker/registryurl"
  constant AppcDockerRepository (line 47) | AppcDockerRepository    = "appc.io/docker/repository"
  constant AppcDockerTag (line 48) | AppcDockerTag           = "appc.io/docker/tag"
  constant AppcDockerImageID (line 49) | AppcDockerImageID       = "appc.io/docker/imageid"
  constant AppcDockerParentImageID (line 50) | AppcDockerParentImageID = "appc.io/docker/parentimageid"
  constant AppcDockerEntrypoint (line 51) | AppcDockerEntrypoint    = "appc.io/docker/entrypoint"
  constant AppcDockerCmd (line 52) | AppcDockerCmd           = "appc.io/docker/cmd"
  constant AppcDockerManifestHash (line 53) | AppcDockerManifestHash  = "appc.io/docker/manifesthash"
  constant defaultTag (line 56) | defaultTag = "latest"
  type ParsedDockerURL (line 59) | type ParsedDockerURL struct
  type ErrSeveralImages (line 67) | type ErrSeveralImages struct
    method Error (line 78) | func (e *ErrSeveralImages) Error() string {
  type InsecureConfig (line 73) | type InsecureConfig struct
  function ParseDockerURL (line 84) | func ParseDockerURL(arg string) (*ParsedDockerURL, error) {
  function ValidateLayerId (line 112) | func ValidateLayerId(id string) error {
  constant MediaTypeDockerV21Manifest (line 124) | MediaTypeDockerV21Manifest       = "application/vnd.docker.distribution....
  constant MediaTypeDockerV21SignedManifest (line 125) | MediaTypeDockerV21SignedManifest = "application/vnd.docker.distribution....
  constant MediaTypeDockerV21ManifestLayer (line 126) | MediaTypeDockerV21ManifestLayer  = "application/vnd.docker.container.ima...
  constant MediaTypeDockerV22Manifest (line 128) | MediaTypeDockerV22Manifest     = "application/vnd.docker.distribution.ma...
  constant MediaTypeDockerV22ManifestList (line 129) | MediaTypeDockerV22ManifestList = "application/vnd.docker.distribution.ma...
  constant MediaTypeDockerV22Config (line 130) | MediaTypeDockerV22Config       = "application/vnd.docker.container.image...
  constant MediaTypeDockerV22RootFS (line 131) | MediaTypeDockerV22RootFS       = "application/vnd.docker.image.rootfs.di...
  constant MediaTypeOCIV1Manifest (line 133) | MediaTypeOCIV1Manifest     = spec.MediaTypeImageManifest
  constant MediaTypeOCIV1ManifestList (line 134) | MediaTypeOCIV1ManifestList = spec.MediaTypeImageManifestList
  constant MediaTypeOCIV1Config (line 135) | MediaTypeOCIV1Config       = spec.MediaTypeImageConfig
  constant MediaTypeOCIV1Layer (line 136) | MediaTypeOCIV1Layer        = spec.MediaTypeImageLayer
  type MediaTypeOption (line 141) | type MediaTypeOption
  constant MediaTypeOptionDockerV21 (line 144) | MediaTypeOptionDockerV21 = iota
  constant MediaTypeOptionDockerV22 (line 145) | MediaTypeOptionDockerV22
  constant MediaTypeOptionOCIV1Pre (line 146) | MediaTypeOptionOCIV1Pre
  type MediaTypeSet (line 156) | type MediaTypeSet
    method ManifestMediaTypes (line 158) | func (m MediaTypeSet) ManifestMediaTypes() []string {
    method ConfigMediaTypes (line 182) | func (m MediaTypeSet) ConfigMediaTypes() []string {
    method LayerMediaTypes (line 202) | func (m MediaTypeSet) LayerMediaTypes() []string {
  type RegistryOption (line 224) | type RegistryOption
  constant RegistryOptionV1 (line 227) | RegistryOptionV1 = iota
  constant RegistryOptionV2 (line 228) | RegistryOptionV2
  type RegistryOptionSet (line 237) | type RegistryOptionSet
    method AllowsV1 (line 239) | func (r RegistryOptionSet) AllowsV1() bool {
    method AllowsV2 (line 251) | func (r RegistryOptionSet) AllowsV2() bool {

FILE: lib/common/common_test.go
  function TestMediaTypeSet (line 23) | func TestMediaTypeSet(t *testing.T) {
  function TestRegistryOptionSet (line 81) | func TestRegistryOptionSet(t *testing.T) {
  function isEqual (line 110) | func isEqual(val1, val2 []string) bool {
  function TestParseDockerURL (line 126) | func TestParseDockerURL(t *testing.T) {

FILE: lib/conversion_store.go
  constant hashPrefix (line 31) | hashPrefix = "sha512-"
  type aciInfo (line 34) | type aciInfo struct
  type conversionStore (line 43) | type conversionStore struct
    method WriteACI (line 51) | func (ms *conversionStore) WriteACI(path string) (string, error) {
    method GetImageManifest (line 82) | func (ms *conversionStore) GetImageManifest(key string) (*schema.Image...
    method GetACI (line 90) | func (ms *conversionStore) GetACI(name types.ACIdentifier, labels type...
    method ReadStream (line 101) | func (ms *conversionStore) ReadStream(key string) (io.ReadCloser, erro...
    method ResolveKey (line 119) | func (ms *conversionStore) ResolveKey(key string) (string, error) {
    method HashToKey (line 123) | func (ms *conversionStore) HashToKey(h hash.Hash) string {
  function newConversionStore (line 47) | func newConversionStore() *conversionStore {

FILE: lib/docker2aci.go
  type CommonConfig (line 44) | type CommonConfig struct
    method initLogger (line 55) | func (c *CommonConfig) initLogger() {
  type RemoteConfig (line 67) | type RemoteConfig struct
  type FileConfig (line 78) | type FileConfig struct
  function ConvertRemoteRepo (line 91) | func ConvertRemoteRepo(dockerURL string, config RemoteConfig) ([]string,...
  function ConvertSavedFile (line 113) | func ConvertSavedFile(dockerSavedFile string, config FileConfig) ([]stri...
  function GetIndexName (line 130) | func GetIndexName(dockerURL string) string {
  function GetDockercfgAuth (line 137) | func GetDockercfgAuth(indexServer string) (string, string, error) {
  type converter (line 141) | type converter struct
    method convert (line 147) | func (c *converter) convert() ([]string, error) {
  function squashLayers (line 209) | func squashLayers(images []acirenderer.Image, aciRegistry acirenderer.AC...
  function getSquashedFilename (line 256) | func getSquashedFilename(parsedDockerURL common.ParsedDockerURL) string {
  function getManifests (line 266) | func getManifests(renderedACI acirenderer.RenderedACI, aciRegistry acire...
  function writeSquashedImage (line 280) | func writeSquashedImage(outputFile *os.File, renderedACI acirenderer.Ren...
  function mergeManifests (line 429) | func mergeManifests(manifests []schema.ImageManifest) schema.ImageManife...
  function stripLayerID (line 460) | func stripLayerID(layerName string) string {

FILE: lib/internal/backend/file/file.go
  type FileBackend (line 43) | type FileBackend struct
    method GetImageInfo (line 62) | func (lb *FileBackend) GetImageInfo(dockerURL string) ([]string, strin...
    method BuildACI (line 95) | func (lb *FileBackend) BuildACI(layerIDs []string, manhash string, doc...
    method BuildACIV22 (line 147) | func (lb *FileBackend) BuildACIV22(layerIDs []string, manhash string, ...
  function NewFileBackend (line 48) | func NewFileBackend(file *os.File, debug, info log.Logger) *FileBackend {
  function getImageID (line 202) | func getImageID(file *os.File, dockerURL *common.ParsedDockerURL, name s...
  function getDataFromManifest (line 334) | func getDataFromManifest(file *os.File, manifestID string) (string, []st...
  function getJson (line 378) | func getJson(file *os.File, layerID string) ([]byte, error) {
  function getJsonV22 (line 383) | func getJsonV22(file *os.File, layerID string) ([]byte, error) {
  function getTarFileBytes (line 389) | func getTarFileBytes(file *os.File, path string) ([]byte, error) {
  function extractEmbeddedLayer (line 419) | func extractEmbeddedLayer(file *os.File, layerTarPath string, outputPath...
  function getAncestry (line 459) | func getAncestry(file *os.File, imgID string, debug log.Logger) ([]strin...
  function getParent (line 481) | func getParent(file *os.File, imgID string, debug log.Logger) (string, e...

FILE: lib/internal/backend/repository/repository.go
  type registryVersion (line 34) | type registryVersion
  constant registryV1 (line 37) | registryV1 registryVersion = iota
  constant registryV2 (line 38) | registryV2
  type httpStatusErr (line 41) | type httpStatusErr struct
    method Error (line 46) | func (e httpStatusErr) Error() string {
  function isErrHTTP404 (line 50) | func isErrHTTP404(err error) bool {
  type RepositoryBackend (line 57) | type RepositoryBackend struct
    method GetImageInfo (line 100) | func (rb *RepositoryBackend) GetImageInfo(url string) ([]string, strin...
    method BuildACI (line 152) | func (rb *RepositoryBackend) BuildACI(layerIDs []string, manhash strin...
    method supportsRegistry (line 176) | func (rb *RepositoryBackend) supportsRegistry(indexURL string, version...
  function NewRepositoryBackend (line 76) | func NewRepositoryBackend(username, password string, insecure common.Ins...
  function checkRegistryStatus (line 162) | func checkRegistryStatus(statusCode int, hdr http.Header, version regist...

FILE: lib/internal/backend/repository/repository1.go
  type RepoData (line 37) | type RepoData struct
  method getImageInfoV1 (line 43) | func (rb *RepositoryBackend) getImageInfoV1(dockerURL *common.ParsedDock...
  method buildACIV1 (line 65) | func (rb *RepositoryBackend) buildACIV1(layerIDs []string, manhash strin...
  method getRepoDataV1 (line 138) | func (rb *RepositoryBackend) getRepoDataV1(indexURL string, remote strin...
  method getImageIDFromTagV1 (line 188) | func (rb *RepositoryBackend) getImageIDFromTagV1(registry string, appNam...
  method getAncestryV1 (line 231) | func (rb *RepositoryBackend) getAncestryV1(imgID, registry string, repoD...
  method getJsonV1 (line 264) | func (rb *RepositoryBackend) getJsonV1(imgID, registry string, repoData ...
  method getLayerV1 (line 299) | func (rb *RepositoryBackend) getLayerV1(imgID, registry string, repoData...
  function setAuthTokenV1 (line 368) | func setAuthTokenV1(req *http.Request, token []string) {
  function setCookieV1 (line 374) | func setCookieV1(req *http.Request, cookie []string) {
  function makeEndpointsListV1 (line 380) | func makeEndpointsListV1(headers []string) []string {

FILE: lib/internal/backend/repository/repository2.go
  constant defaultIndexURL (line 42) | defaultIndexURL = "registry-1.docker.io"
  type v2Manifest (line 46) | type v2Manifest struct
  method getImageInfoV2 (line 58) | func (rb *RepositoryBackend) getImageInfoV2(dockerURL *common.ParsedDock...
  method buildACIV2 (line 67) | func (rb *RepositoryBackend) buildACIV2(layerIDs []string, manhash strin...
  method buildACIV21 (line 75) | func (rb *RepositoryBackend) buildACIV21(layerIDs []string, manhash stri...
  type layer (line 178) | type layer struct
  method buildACIV22 (line 185) | func (rb *RepositoryBackend) buildACIV22(layerIDs []string, manhash stri...
  method getManifestV2 (line 282) | func (rb *RepositoryBackend) getManifestV2(dockerURL *common.ParsedDocke...
  method getManifestV21 (line 317) | func (rb *RepositoryBackend) getManifestV21(dockerURL *common.ParsedDock...
  method getManifestV22 (line 360) | func (rb *RepositoryBackend) getManifestV22(dockerURL *common.ParsedDock...
  method getConfigV22 (line 393) | func (rb *RepositoryBackend) getConfigV22(dockerURL *common.ParsedDocker...
  function fixManifestLayers (line 421) | func fixManifestLayers(manifest *v2Manifest) error {
  method getLayerV2 (line 470) | func (rb *RepositoryBackend) getLayerV2(layerID string, dockerURL *commo...
  method makeRequest (line 541) | func (rb *RepositoryBackend) makeRequest(req *http.Request, repo string,...
  method setBasicAuth (line 657) | func (rb *RepositoryBackend) setBasicAuth(req *http.Request) {

FILE: lib/internal/docker/docker.go
  constant dockercfgFileName (line 31) | dockercfgFileName    = "config.json"
  constant dockercfgFileNameOld (line 32) | dockercfgFileNameOld = ".dockercfg"
  constant defaultIndexURL (line 33) | defaultIndexURL      = "registry-1.docker.io"
  constant defaultIndexURLAuth (line 34) | defaultIndexURLAuth  = "https://index.docker.io/v1/"
  constant defaultRepoPrefix (line 35) | defaultRepoPrefix    = "library/"
  function SplitReposName (line 39) | func SplitReposName(name string) (indexName, remoteName string) {
  function parseRepositoryTag (line 55) | func parseRepositoryTag(repos string) (string, string) {
  function decodeDockerAuth (line 66) | func decodeDockerAuth(s string) (string, string, error) {
  function getHomeDir (line 80) | func getHomeDir() string {
  function GetAuthInfo (line 89) | func GetAuthInfo(indexServer string) (string, string, error) {

FILE: lib/internal/internal.go
  type Docker2ACIBackend (line 55) | type Docker2ACIBackend interface
  function GenerateACI (line 67) | func GenerateACI(layerNumber int, manhash string, layerData types.Docker...
  function GenerateACI22LowerLayer (line 88) | func GenerateACI22LowerLayer(dockerURL *common.ParsedDockerURL, layerDig...
  function GenerateACI22TopLayer (line 113) | func GenerateACI22TopLayer(dockerURL *common.ParsedDockerURL, manhash st...
  function generateACIPath (line 137) | func generateACIPath(outputDir, imageName, digest, tag, osString, arch s...
  function generateEPCmdAnnotation (line 155) | func generateEPCmdAnnotation(dockerEP, dockerCmd []string) (string, stri...
  function setLabel (line 178) | func setLabel(labels map[appctypes.ACIdentifier]string, key, val string) {
  function setOSArch (line 189) | func setOSArch(labels map[appctypes.ACIdentifier]string, os, arch string...
  function setAnnotation (line 205) | func setAnnotation(annotations *appctypes.Annotations, key, val string) {
  function GenerateManifest (line 213) | func GenerateManifest(layerData types.DockerImageData, manhash string, d...
  function GenerateEmptyManifest (line 333) | func GenerateEmptyManifest(name string) (*schema.ImageManifest, error) {
  function GenerateManifestV22 (line 361) | func GenerateManifestV22(
  function ValidateACI (line 446) | func ValidateACI(aciPath string) error {
  type appcPortSorter (line 466) | type appcPortSorter
    method Len (line 468) | func (s appcPortSorter) Len() int {
    method Swap (line 472) | func (s appcPortSorter) Swap(i, j int) {
    method Less (line 476) | func (s appcPortSorter) Less(i, j int) bool {
  function convertPorts (line 480) | func convertPorts(dockerExposedPorts map[string]struct{}, dockerPortSpec...
  function parseDockerPort (line 507) | func parseDockerPort(dockerPort string) (*appctypes.Port, error) {
  type appcVolSorter (line 537) | type appcVolSorter
    method Len (line 539) | func (s appcVolSorter) Len() int {
    method Swap (line 543) | func (s appcVolSorter) Swap(i, j int) {
    method Less (line 547) | func (s appcVolSorter) Less(i, j int) bool {
  function convertVolumesToMPs (line 551) | func convertVolumesToMPs(dockerVolumes map[string]struct{}) ([]appctypes...
  function writeACI (line 583) | func writeACI(layer io.ReadSeeker, manifest schema.ImageManifest, curPwl...
  function getExecCommand (line 693) | func getExecCommand(entrypoint []string, cmd []string) appctypes.Exec {
  function parseDockerUser (line 697) | func parseDockerUser(dockerUser string) (string, string) {
  function subtractWhiteouts (line 715) | func subtractWhiteouts(pathWhitelist []string, whiteouts []string) []str...
  function WriteManifest (line 743) | func WriteManifest(outputWriter *tar.Writer, manifest schema.ImageManife...
  function WriteRootfsDir (line 766) | func WriteRootfsDir(tarWriter *tar.Writer) error {
  type symlink (line 776) | type symlink struct
  function writeStdioSymlinks (line 784) | func writeStdioSymlinks(tarWriter *tar.Writer, fileMap map[string]struct...
  function getGenericTarHeader (line 818) | func getGenericTarHeader() *tar.Header {

FILE: lib/internal/internal_test.go
  function TestSetLabel (line 23) | func TestSetLabel(t *testing.T) {
  function TestSetAnnotation (line 55) | func TestSetAnnotation(t *testing.T) {
  function TestOSArch (line 86) | func TestOSArch(t *testing.T) {

FILE: lib/internal/tarball/tarfile.go
  type TarFile (line 29) | type TarFile struct
    method Name (line 35) | func (t *TarFile) Name() string {
    method Linkname (line 40) | func (t *TarFile) Linkname() string {

FILE: lib/internal/tarball/walk.go
  type WalkFunc (line 24) | type WalkFunc
  function Walk (line 28) | func Walk(tarReader tar.Reader, walkFunc func(t *TarFile) error) error {

FILE: lib/internal/types/docker_types.go
  type DockerImageData (line 21) | type DockerImageData struct
  type DockerImageConfig (line 40) | type DockerImageConfig struct
  type DockerAuthConfigOld (line 71) | type DockerAuthConfigOld struct
  type DockerAuthConfig (line 81) | type DockerAuthConfig struct
  type DockerConfigFile (line 91) | type DockerConfigFile struct

FILE: lib/internal/typesV2/docker_types.go
  type ImageManifest (line 30) | type ImageManifest struct
    method String (line 44) | func (im *ImageManifest) String() string {
    method PrettyString (line 52) | func (im *ImageManifest) PrettyString() string {
    method Validate (line 60) | func (im *ImageManifest) Validate() error {
  type ImageManifestDigest (line 38) | type ImageManifestDigest struct
  type ImageConfig (line 73) | type ImageConfig struct
    method String (line 109) | func (ic *ImageConfig) String() string {
    method PrettyString (line 117) | func (ic *ImageConfig) PrettyString() string {
  type ImageConfigConfig (line 83) | type ImageConfigConfig struct
  type ImageConfigRootFS (line 96) | type ImageConfigRootFS struct
  type ImageConfigHistory (line 101) | type ImageConfigHistory struct

FILE: lib/internal/util/util.go
  function Quote (line 37) | func Quote(l []string) []string {
  function ReverseImages (line 48) | func ReverseImages(s acirenderer.Images) acirenderer.Images {
  function In (line 58) | func In(list []string, el string) bool {
  function IndexOf (line 63) | func IndexOf(list []string, el string) int {
  function GetTLSClient (line 74) | func GetTLSClient(skipTLSCheck bool) *http.Client {
  function newClient (line 82) | func newClient(skipTLSCheck bool) *http.Client {

FILE: lib/tests/common.go
  type Layer (line 17) | type Layer
  type Docker22Image (line 19) | type Docker22Image struct
  function GenerateDocker22 (line 25) | func GenerateDocker22(destPath string, img Docker22Image) error {
  function GenLayers (line 41) | func GenLayers(destPath string, layers []Layer) ([]string, error) {
  function GenDocker22Config (line 73) | func GenDocker22Config(destPath string, conf typesV2.ImageConfig, layerH...
  function GenDocker22Manifest (line 93) | func GenDocker22Manifest(destPath, configHash string, layerHashes []stri...

FILE: lib/tests/server.go
  function RunDockerRegistry (line 14) | func RunDockerRegistry(t *testing.T, imgPath, imgName, imgRef, manifestM...
  function GetManifest (line 36) | func GetManifest(t *testing.T, w http.ResponseWriter, r *http.Request, i...
  function GetBlob (line 69) | func GetBlob(t *testing.T, w http.ResponseWriter, r *http.Request, imgPa...
  function parseURL (line 97) | func parseURL(resource, input string) (string, string, error) {

FILE: lib/tests/v22_test.go
  constant variableTestValue (line 23) | variableTestValue = "variant"
  type osArchTuple (line 27) | type osArchTuple struct
  function testDocker22Images (line 77) | func testDocker22Images(layers []Layer, fn func(Docker22Image)) {
  function expectedManifest (line 97) | func expectedManifest(registryUrl, imageName, imageOs, imageArch string)...
  function fetchImage (line 184) | func fetchImage(imgName, outputDir string, squash bool) ([]string, error) {
  function TestFetchingByTagV22 (line 209) | func TestFetchingByTagV22(t *testing.T) {
  function manifestEqual (line 279) | func manifestEqual(manifest, expected *schema.ImageManifest) error {
  function TestFetchingByDigestV22 (line 326) | func TestFetchingByDigestV22(t *testing.T) {
  function TestFetchingMultipleLayersV22 (line 368) | func TestFetchingMultipleLayersV22(t *testing.T) {

FILE: main.go
  function init (line 42) | func init() {
  function printVersion (line 52) | func printVersion() {
  function runDocker2ACI (line 57) | func runDocker2ACI(arg string) error {
  function printConvertedVolumes (line 150) | func printConvertedVolumes(manifest schema.ImageManifest) {
  function printConvertedPorts (line 162) | func printConvertedPorts(manifest schema.ImageManifest) {
  function getManifest (line 175) | func getManifest(aciPath string) (*schema.ImageManifest, error) {
  function usage (line 190) | func usage() {
  function main (line 201) | func main() {

FILE: pkg/log/log.go
  type Logger (line 25) | type Logger interface
  function NewStdLogger (line 31) | func NewStdLogger(out io.Writer) Logger {
  type nopLogger (line 35) | type nopLogger struct
    method Print (line 41) | func (l *nopLogger) Print(...interface{}) {
    method Printf (line 45) | func (l *nopLogger) Printf(string, ...interface{}) {
    method Println (line 49) | func (l *nopLogger) Println(...interface{}) {
  function NewNopLogger (line 37) | func NewNopLogger() Logger {

FILE: vendor/github.com/appc/spec/aci/build.go
  type TarHeaderWalkFunc (line 32) | type TarHeaderWalkFunc
  function BuildWalker (line 37) | func BuildWalker(root string, aw ArchiveWriter, cb TarHeaderWalkFunc) fi...

FILE: vendor/github.com/appc/spec/aci/file.go
  type FileType (line 35) | type FileType
  constant TypeGzip (line 38) | TypeGzip    = FileType("gz")
  constant TypeBzip2 (line 39) | TypeBzip2   = FileType("bz2")
  constant TypeXz (line 40) | TypeXz      = FileType("xz")
  constant TypeTar (line 41) | TypeTar     = FileType("tar")
  constant TypeText (line 42) | TypeText    = FileType("text")
  constant TypeUnknown (line 43) | TypeUnknown = FileType("unknown")
  constant readLen (line 45) | readLen = 512
  constant hexHdrGzip (line 47) | hexHdrGzip  = "1f8b"
  constant hexHdrBzip2 (line 48) | hexHdrBzip2 = "425a68"
  constant hexHdrXz (line 49) | hexHdrXz    = "fd377a585a00"
  constant hexSigTar (line 50) | hexSigTar   = "7573746172"
  constant tarOffset (line 52) | tarOffset = 257
  constant textMime (line 54) | textMime = "text/plain; charset=utf-8"
  function mustDecodeHex (line 65) | func mustDecodeHex(s string) []byte {
  function init (line 73) | func init() {
  function DetectFileType (line 83) | func DetectFileType(r io.Reader) (FileType, error) {
  type XzReader (line 107) | type XzReader struct
    method Close (line 139) | func (r *XzReader) Close() error {
  function NewXzReader (line 117) | func NewXzReader(r io.Reader) (*XzReader, error) {
  function ManifestFromImage (line 146) | func ManifestFromImage(rs io.ReadSeeker) (*schema.ImageManifest, error) {
  type TarReadCloser (line 180) | type TarReadCloser struct
    method Close (line 185) | func (r *TarReadCloser) Close() error {
  function NewCompressedTarReader (line 193) | func NewCompressedTarReader(rs io.ReadSeeker) (*TarReadCloser, error) {
  function NewCompressedReader (line 203) | func NewCompressedReader(rs io.ReadSeeker) (io.ReadCloser, error) {

FILE: vendor/github.com/appc/spec/aci/layout.go
  constant ManifestFile (line 48) | ManifestFile = "manifest"
  constant RootfsDir (line 50) | RootfsDir = "rootfs"
  type ErrOldVersion (line 53) | type ErrOldVersion struct
    method Error (line 57) | func (e ErrOldVersion) Error() string {
  function ValidateLayout (line 70) | func ValidateLayout(dir string) error {
  function ValidateArchive (line 114) | func ValidateArchive(tr *tar.Reader) error {
  function validate (line 156) | func validate(imOK bool, im io.Reader, rfsOK bool, files []string) error {

FILE: vendor/github.com/appc/spec/aci/writer.go
  type ArchiveWriter (line 30) | type ArchiveWriter interface
  type imageArchiveWriter (line 35) | type imageArchiveWriter struct
    method AddFile (line 51) | func (aw *imageArchiveWriter) AddFile(hdr *tar.Header, r io.Reader) er...
    method addFileNow (line 67) | func (aw *imageArchiveWriter) addFileNow(path string, contents []byte)...
    method addManifest (line 85) | func (aw *imageArchiveWriter) addManifest(name string, m json.Marshale...
    method Close (line 93) | func (aw *imageArchiveWriter) Close() error {
  function NewImageWriter (line 43) | func NewImageWriter(am schema.ImageManifest, w *tar.Writer) ArchiveWriter {

FILE: vendor/github.com/appc/spec/pkg/acirenderer/acirenderer.go
  type ACIRegistry (line 33) | type ACIRegistry interface
  type ACIProvider (line 42) | type ACIProvider interface
  type Image (line 55) | type Image struct
  type Images (line 67) | type Images
  type ACIFiles (line 70) | type ACIFiles struct
  type RenderedACI (line 76) | type RenderedACI
  function GetRenderedACIWithImageID (line 81) | func GetRenderedACIWithImageID(imageID types.Hash, ap ACIRegistry) (Rend...
  function GetRenderedACI (line 92) | func GetRenderedACI(name types.ACIdentifier, labels types.Labels, ap ACI...
  function GetRenderedACIFromList (line 102) | func GetRenderedACIFromList(imgs Images, ap ACIProvider) (RenderedACI, e...
  function getUpperPWLM (line 130) | func getUpperPWLM(imgs Images, pos int) map[string]struct{} {
  function getACIFiles (line 146) | func getACIFiles(img Image, ap ACIProvider, allFiles map[string]byte, pw...
  function pwlToMap (line 226) | func pwlToMap(pwl []string) map[string]struct{} {
  function Walk (line 238) | func Walk(tarReader *tar.Reader, walkFunc func(hdr *tar.Header) error) e...

FILE: vendor/github.com/appc/spec/pkg/acirenderer/resolve.go
  function CreateDepListFromImageID (line 25) | func CreateDepListFromImageID(imageID types.Hash, ap ACIRegistry) (Image...
  function CreateDepListFromNameLabels (line 35) | func CreateDepListFromNameLabels(name types.ACIdentifier, labels types.L...
  function createDepList (line 44) | func createDepList(key string, ap ACIRegistry) (Images, error) {

FILE: vendor/github.com/appc/spec/pkg/device/device_linux.go
  function Major (line 21) | func Major(rdev uint64) uint {
  function Minor (line 25) | func Minor(rdev uint64) uint {
  function Makedev (line 29) | func Makedev(maj uint, min uint) uint64 {

FILE: vendor/github.com/appc/spec/pkg/device/device_posix.go
  function Major (line 44) | func Major(rdev uint64) uint {
  function Minor (line 49) | func Minor(rdev uint64) uint {
  function Makedev (line 54) | func Makedev(maj uint, min uint) uint64 {

FILE: vendor/github.com/appc/spec/pkg/tarheader/pop_darwin.go
  function init (line 26) | func init() {
  function populateHeaderCtime (line 30) | func populateHeaderCtime(h *tar.Header, fi os.FileInfo, _ map[uint64]str...

FILE: vendor/github.com/appc/spec/pkg/tarheader/pop_linux.go
  function init (line 26) | func init() {
  function populateHeaderCtime (line 30) | func populateHeaderCtime(h *tar.Header, fi os.FileInfo, _ map[uint64]str...

FILE: vendor/github.com/appc/spec/pkg/tarheader/pop_posix.go
  function init (line 27) | func init() {
  function populateHeaderUnix (line 31) | func populateHeaderUnix(h *tar.Header, fi os.FileInfo, seen map[uint64]s...

FILE: vendor/github.com/appc/spec/pkg/tarheader/tarheader.go
  function Populate (line 24) | func Populate(h *tar.Header, fi os.FileInfo, seen map[uint64]string) {

FILE: vendor/github.com/appc/spec/schema/common/common.go
  function MakeQueryString (line 29) | func MakeQueryString(app string) (string, error) {

FILE: vendor/github.com/appc/spec/schema/image.go
  constant ACIExtension (line 29) | ACIExtension      = ".aci"
  constant ImageManifestKind (line 30) | ImageManifestKind = types.ACKind("ImageManifest")
  type ImageManifest (line 33) | type ImageManifest struct
    method UnmarshalJSON (line 52) | func (im *ImageManifest) UnmarshalJSON(data []byte) error {
    method MarshalJSON (line 70) | func (im ImageManifest) MarshalJSON() ([]byte, error) {
    method assertValid (line 84) | func (im *ImageManifest) assertValid() error {
    method GetLabel (line 97) | func (im *ImageManifest) GetLabel(name string) (val string, ok bool) {
    method GetAnnotation (line 101) | func (im *ImageManifest) GetAnnotation(name string) (val string, ok bo...
  type imageManifest (line 46) | type imageManifest
  function BlankImageManifest (line 48) | func BlankImageManifest() *ImageManifest {

FILE: vendor/github.com/appc/spec/schema/kind.go
  type Kind (line 23) | type Kind struct
    method UnmarshalJSON (line 30) | func (k *Kind) UnmarshalJSON(data []byte) error {
    method MarshalJSON (line 40) | func (k Kind) MarshalJSON() ([]byte, error) {
  type kind (line 28) | type kind

FILE: vendor/github.com/appc/spec/schema/pod.go
  constant PodManifestKind (line 28) | PodManifestKind = types.ACKind("PodManifest")
  type PodManifest (line 30) | type PodManifest struct
    method UnmarshalJSON (line 50) | func (pm *PodManifest) UnmarshalJSON(data []byte) error {
    method MarshalJSON (line 68) | func (pm PodManifest) MarshalJSON() ([]byte, error) {
    method assertValid (line 82) | func (pm *PodManifest) assertValid() error {
  type podManifest (line 44) | type podManifest
  function BlankPodManifest (line 46) | func BlankPodManifest() *PodManifest {
  type AppList (line 89) | type AppList
    method UnmarshalJSON (line 93) | func (al *AppList) UnmarshalJSON(data []byte) error {
    method MarshalJSON (line 107) | func (al AppList) MarshalJSON() ([]byte, error) {
    method assertValid (line 114) | func (al AppList) assertValid() error {
    method Get (line 128) | func (al AppList) Get(name types.ACName) *RuntimeApp {
  type appList (line 91) | type appList
  type Mount (line 142) | type Mount struct
    method assertValid (line 148) | func (r Mount) assertValid() error {
  type RuntimeApp (line 159) | type RuntimeApp struct
  type RuntimeImage (line 169) | type RuntimeImage struct

FILE: vendor/github.com/appc/spec/schema/types/acidentifier.go
  type ACIdentifier (line 46) | type ACIdentifier
    method String (line 48) | func (n ACIdentifier) String() string {
    method Set (line 54) | func (n *ACIdentifier) Set(s string) error {
    method Equals (line 63) | func (n ACIdentifier) Equals(o ACIdentifier) bool {
    method Empty (line 68) | func (n ACIdentifier) Empty() bool {
    method assertValid (line 92) | func (n ACIdentifier) assertValid() error {
    method UnmarshalJSON (line 107) | func (n *ACIdentifier) UnmarshalJSON(data []byte) error {
    method MarshalJSON (line 121) | func (n ACIdentifier) MarshalJSON() ([]byte, error) {
  function NewACIdentifier (line 74) | func NewACIdentifier(s string) (*ACIdentifier, error) {
  function MustACIdentifier (line 84) | func MustACIdentifier(s string) *ACIdentifier {
  function SanitizeACIdentifier (line 135) | func SanitizeACIdentifier(s string) (string, error) {

FILE: vendor/github.com/appc/spec/schema/types/ackind.go
  type ACKind (line 29) | type ACKind
    method String (line 31) | func (a ACKind) String() string {
    method assertValid (line 35) | func (a ACKind) assertValid() error {
    method MarshalJSON (line 48) | func (a ACKind) MarshalJSON() ([]byte, error) {
    method UnmarshalJSON (line 55) | func (a *ACKind) UnmarshalJSON(data []byte) error {

FILE: vendor/github.com/appc/spec/schema/types/acname.go
  type ACName (line 46) | type ACName
    method String (line 48) | func (n ACName) String() string {
    method Set (line 54) | func (n *ACName) Set(s string) error {
    method Equals (line 63) | func (n ACName) Equals(o ACName) bool {
    method Empty (line 68) | func (n ACName) Empty() bool {
    method assertValid (line 92) | func (n ACName) assertValid() error {
    method UnmarshalJSON (line 107) | func (n *ACName) UnmarshalJSON(data []byte) error {
    method MarshalJSON (line 121) | func (n ACName) MarshalJSON() ([]byte, error) {
  function NewACName (line 74) | func NewACName(s string) (*ACName, error) {
  function MustACName (line 84) | func MustACName(s string) *ACName {
  function SanitizeACName (line 135) | func SanitizeACName(s string) (string, error) {

FILE: vendor/github.com/appc/spec/schema/types/annotations.go
  type Annotations (line 22) | type Annotations
    method assertValid (line 31) | func (a Annotations) assertValid() error {
    method MarshalJSON (line 59) | func (a Annotations) MarshalJSON() ([]byte, error) {
    method UnmarshalJSON (line 66) | func (a *Annotations) UnmarshalJSON(data []byte) error {
    method Get (line 81) | func (a Annotations) Get(name string) (val string, ok bool) {
    method Set (line 91) | func (a *Annotations) Set(name ACIdentifier, value string) {
  type annotations (line 24) | type annotations
  type Annotation (line 26) | type Annotation struct

FILE: vendor/github.com/appc/spec/schema/types/app.go
  type App (line 24) | type App struct
    method UnmarshalJSON (line 43) | func (a *App) UnmarshalJSON(data []byte) error {
    method MarshalJSON (line 60) | func (a App) MarshalJSON() ([]byte, error) {
    method assertValid (line 67) | func (a *App) assertValid() error {
  type app (line 41) | type app

FILE: vendor/github.com/appc/spec/schema/types/date.go
  type Date (line 30) | type Date
    method String (line 41) | func (d Date) String() string {
    method UnmarshalJSON (line 45) | func (d *Date) UnmarshalJSON(data []byte) error {
    method MarshalJSON (line 58) | func (d Date) MarshalJSON() ([]byte, error) {
  function NewDate (line 32) | func NewDate(s string) (*Date, error) {

FILE: vendor/github.com/appc/spec/schema/types/dependencies.go
  type Dependencies (line 22) | type Dependencies
  type Dependency (line 24) | type Dependency struct
    method assertValid (line 33) | func (d Dependency) assertValid() error {
    method MarshalJSON (line 40) | func (d Dependency) MarshalJSON() ([]byte, error) {
    method UnmarshalJSON (line 47) | func (d *Dependency) UnmarshalJSON(data []byte) error {
  type dependency (line 31) | type dependency

FILE: vendor/github.com/appc/spec/schema/types/environment.go
  type Environment (line 27) | type Environment
    method assertValid (line 46) | func (e Environment) assertValid() error {
    method MarshalJSON (line 62) | func (e Environment) MarshalJSON() ([]byte, error) {
    method UnmarshalJSON (line 69) | func (e *Environment) UnmarshalJSON(data []byte) error {
    method Get (line 84) | func (e Environment) Get(name string) (value string, ok bool) {
    method Set (line 95) | func (e *Environment) Set(name string, value string) {
  type environment (line 29) | type environment
  type EnvironmentVariable (line 31) | type EnvironmentVariable struct
    method assertValid (line 36) | func (ev EnvironmentVariable) assertValid() error {

FILE: vendor/github.com/appc/spec/schema/types/errors.go
  type ACKindError (line 20) | type ACKindError
    method Error (line 22) | func (e ACKindError) Error() string {
  function InvalidACKindError (line 26) | func InvalidACKindError(kind ACKind) ACKindError {
  type ACVersionError (line 31) | type ACVersionError
    method Error (line 33) | func (e ACVersionError) Error() string {
  type ACIdentifierError (line 38) | type ACIdentifierError
    method Error (line 40) | func (e ACIdentifierError) Error() string {
  type ACNameError (line 45) | type ACNameError
    method Error (line 47) | func (e ACNameError) Error() string {

FILE: vendor/github.com/appc/spec/schema/types/event_handler.go
  type EventHandler (line 23) | type EventHandler struct
    method assertValid (line 30) | func (e EventHandler) assertValid() error {
    method MarshalJSON (line 42) | func (e EventHandler) MarshalJSON() ([]byte, error) {
    method UnmarshalJSON (line 49) | func (e *EventHandler) UnmarshalJSON(data []byte) error {
  type eventHandler (line 28) | type eventHandler

FILE: vendor/github.com/appc/spec/schema/types/exec.go
  type Exec (line 19) | type Exec
    method assertValid (line 23) | func (e Exec) assertValid() error {
    method MarshalJSON (line 27) | func (e Exec) MarshalJSON() ([]byte, error) {
    method UnmarshalJSON (line 34) | func (e *Exec) UnmarshalJSON(data []byte) error {
  type exec (line 21) | type exec

FILE: vendor/github.com/appc/spec/schema/types/hash.go
  constant maxHashSize (line 27) | maxHashSize = (sha512.Size / 2) + len("sha512-")
  type Hash (line 36) | type Hash struct
    method String (line 56) | func (h Hash) String() string {
    method Set (line 60) | func (h *Hash) Set(s string) error {
    method Empty (line 68) | func (h Hash) Empty() bool {
    method assertValid (line 72) | func (h Hash) assertValid() error {
    method UnmarshalJSON (line 86) | func (h *Hash) UnmarshalJSON(data []byte) error {
    method MarshalJSON (line 99) | func (h Hash) MarshalJSON() ([]byte, error) {
  function NewHash (line 41) | func NewHash(s string) (*Hash, error) {
  function NewHashSHA512 (line 106) | func NewHashSHA512(b []byte) *Hash {
  function ShortHash (line 113) | func ShortHash(hash string) string {

FILE: vendor/github.com/appc/spec/schema/types/isolator.go
  function init (line 34) | func init() {
  type IsolatorValueConstructor (line 38) | type IsolatorValueConstructor
  function AddIsolatorValueConstructor (line 40) | func AddIsolatorValueConstructor(n ACIdentifier, i IsolatorValueConstruc...
  function AddIsolatorName (line 44) | func AddIsolatorName(n ACIdentifier, ns map[ACIdentifier]struct{}) {
  type Isolators (line 50) | type Isolators
    method assertValid (line 54) | func (isolators Isolators) assertValid() error {
    method GetByName (line 80) | func (is *Isolators) GetByName(name ACIdentifier) *Isolator {
    method ReplaceIsolatorsByName (line 93) | func (is *Isolators) ReplaceIsolatorsByName(newIs Isolator, oldNames [...
    method Unrecognized (line 110) | func (is *Isolators) Unrecognized() Isolators {
  type IsolatorValue (line 123) | type IsolatorValue interface
  type Isolator (line 139) | type Isolator struct
    method Value (line 157) | func (i *Isolator) Value() IsolatorValue {
    method UnmarshalJSON (line 164) | func (i *Isolator) UnmarshalJSON(b []byte) error {
  type isolator (line 153) | type isolator

FILE: vendor/github.com/appc/spec/schema/types/isolator_linux_specific.go
  constant LinuxCapabilitiesRetainSetName (line 26) | LinuxCapabilitiesRetainSetName = "os/linux/capabilities-retain-set"
  constant LinuxCapabilitiesRevokeSetName (line 27) | LinuxCapabilitiesRevokeSetName = "os/linux/capabilities-remove-set"
  constant LinuxNoNewPrivilegesName (line 28) | LinuxNoNewPrivilegesName       = "os/linux/no-new-privileges"
  constant LinuxSeccompRemoveSetName (line 29) | LinuxSeccompRemoveSetName      = "os/linux/seccomp-remove-set"
  constant LinuxSeccompRetainSetName (line 30) | LinuxSeccompRetainSetName      = "os/linux/seccomp-retain-set"
  constant LinuxOOMScoreAdjName (line 31) | LinuxOOMScoreAdjName           = "os/linux/oom-score-adj"
  constant LinuxCPUSharesName (line 32) | LinuxCPUSharesName             = "os/linux/cpu-shares"
  constant LinuxSELinuxContextName (line 33) | LinuxSELinuxContextName        = "os/linux/selinux-context"
  function init (line 38) | func init() {
  type LinuxNoNewPrivileges (line 54) | type LinuxNoNewPrivileges
    method AssertValid (line 56) | func (l LinuxNoNewPrivileges) AssertValid() error {
    method multipleAllowed (line 62) | func (l LinuxNoNewPrivileges) multipleAllowed() bool {
    method Conflicts (line 65) | func (l LinuxNoNewPrivileges) Conflicts() []ACIdentifier {
    method UnmarshalJSON (line 69) | func (l *LinuxNoNewPrivileges) UnmarshalJSON(b []byte) error {
  type AsIsolator (line 81) | type AsIsolator interface
  type LinuxCapabilitiesSet (line 85) | type LinuxCapabilitiesSet interface
  type LinuxCapability (line 90) | type LinuxCapability
  type linuxCapabilitiesSetValue (line 92) | type linuxCapabilitiesSetValue struct
  type linuxCapabilitiesSetBase (line 96) | type linuxCapabilitiesSetBase struct
    method AssertValid (line 100) | func (l linuxCapabilitiesSetBase) AssertValid() error {
    method multipleAllowed (line 109) | func (l linuxCapabilitiesSetBase) multipleAllowed() bool {
    method Conflicts (line 112) | func (l linuxCapabilitiesSetBase) Conflicts() []ACIdentifier {
    method UnmarshalJSON (line 116) | func (l *linuxCapabilitiesSetBase) UnmarshalJSON(b []byte) error {
    method Set (line 128) | func (l linuxCapabilitiesSetBase) Set() []LinuxCapability {
  type LinuxCapabilitiesRetainSet (line 132) | type LinuxCapabilitiesRetainSet struct
    method AsIsolator (line 153) | func (l LinuxCapabilitiesRetainSet) AsIsolator() (*Isolator, error) {
  function NewLinuxCapabilitiesRetainSet (line 136) | func NewLinuxCapabilitiesRetainSet(caps ...string) (*LinuxCapabilitiesRe...
  type LinuxCapabilitiesRevokeSet (line 166) | type LinuxCapabilitiesRevokeSet struct
    method AsIsolator (line 187) | func (l LinuxCapabilitiesRevokeSet) AsIsolator() (*Isolator, error) {
  function NewLinuxCapabilitiesRevokeSet (line 170) | func NewLinuxCapabilitiesRevokeSet(caps ...string) (*LinuxCapabilitiesRe...
  type LinuxSeccompSet (line 200) | type LinuxSeccompSet interface
  type LinuxSeccompEntry (line 206) | type LinuxSeccompEntry
  type LinuxSeccompErrno (line 207) | type LinuxSeccompErrno
  type linuxSeccompValue (line 209) | type linuxSeccompValue struct
  type linuxSeccompBase (line 214) | type linuxSeccompBase struct
    method multipleAllowed (line 218) | func (l linuxSeccompBase) multipleAllowed() bool {
    method AssertValid (line 222) | func (l linuxSeccompBase) AssertValid() error {
    method UnmarshalJSON (line 237) | func (l *linuxSeccompBase) UnmarshalJSON(b []byte) error {
    method Set (line 247) | func (l linuxSeccompBase) Set() []LinuxSeccompEntry {
    method Errno (line 251) | func (l linuxSeccompBase) Errno() LinuxSeccompErrno {
  type LinuxSeccompRetainSet (line 255) | type LinuxSeccompRetainSet struct
    method Conflicts (line 259) | func (l LinuxSeccompRetainSet) Conflicts() []ACIdentifier {
    method AsIsolator (line 281) | func (l LinuxSeccompRetainSet) AsIsolator() (*Isolator, error) {
  function NewLinuxSeccompRetainSet (line 263) | func NewLinuxSeccompRetainSet(errno string, syscall ...string) (*LinuxSe...
  type LinuxSeccompRemoveSet (line 294) | type LinuxSeccompRemoveSet struct
    method Conflicts (line 298) | func (l LinuxSeccompRemoveSet) Conflicts() []ACIdentifier {
    method AsIsolator (line 320) | func (l LinuxSeccompRemoveSet) AsIsolator() (*Isolator, error) {
  function NewLinuxSeccompRemoveSet (line 302) | func NewLinuxSeccompRemoveSet(errno string, syscall ...string) (*LinuxSe...
  type LinuxCPUShares (line 336) | type LinuxCPUShares
    method AssertValid (line 347) | func (l LinuxCPUShares) AssertValid() error {
    method multipleAllowed (line 354) | func (l LinuxCPUShares) multipleAllowed() bool {
    method Conflicts (line 358) | func (l LinuxCPUShares) Conflicts() []ACIdentifier {
    method UnmarshalJSON (line 362) | func (l *LinuxCPUShares) UnmarshalJSON(b []byte) error {
    method AsIsolator (line 373) | func (l LinuxCPUShares) AsIsolator() Isolator {
  function NewLinuxCPUShares (line 338) | func NewLinuxCPUShares(val int) (*LinuxCPUShares, error) {
  type LinuxOOMScoreAdj (line 387) | type LinuxOOMScoreAdj
    method AssertValid (line 398) | func (l LinuxOOMScoreAdj) AssertValid() error {
    method multipleAllowed (line 405) | func (l LinuxOOMScoreAdj) multipleAllowed() bool {
    method Conflicts (line 409) | func (l LinuxOOMScoreAdj) Conflicts() []ACIdentifier {
    method UnmarshalJSON (line 413) | func (l *LinuxOOMScoreAdj) UnmarshalJSON(b []byte) error {
    method AsIsolator (line 424) | func (l LinuxOOMScoreAdj) AsIsolator() Isolator {
  function NewLinuxOOMScoreAdj (line 389) | func NewLinuxOOMScoreAdj(val int) (*LinuxOOMScoreAdj, error) {
  type LinuxSELinuxUser (line 437) | type LinuxSELinuxUser
  type LinuxSELinuxRole (line 438) | type LinuxSELinuxRole
  type LinuxSELinuxType (line 439) | type LinuxSELinuxType
  type LinuxSELinuxLevel (line 440) | type LinuxSELinuxLevel
  type linuxSELinuxValue (line 442) | type linuxSELinuxValue struct
  type LinuxSELinuxContext (line 449) | type LinuxSELinuxContext struct
    method AssertValid (line 453) | func (l LinuxSELinuxContext) AssertValid() error {
    method UnmarshalJSON (line 469) | func (l *LinuxSELinuxContext) UnmarshalJSON(b []byte) error {
    method User (line 479) | func (l LinuxSELinuxContext) User() LinuxSELinuxUser {
    method Role (line 483) | func (l LinuxSELinuxContext) Role() LinuxSELinuxRole {
    method Type (line 487) | func (l LinuxSELinuxContext) Type() LinuxSELinuxType {
    method Level (line 491) | func (l LinuxSELinuxContext) Level() LinuxSELinuxLevel {
    method multipleAllowed (line 495) | func (l LinuxSELinuxContext) multipleAllowed() bool {
    method Conflicts (line 499) | func (l LinuxSELinuxContext) Conflicts() []ACIdentifier {
    method AsIsolator (line 518) | func (l LinuxSELinuxContext) AsIsolator() (*Isolator, error) {
  function NewLinuxSELinuxContext (line 503) | func NewLinuxSELinuxContext(selinuxUser, selinuxRole, selinuxType, selin...

FILE: vendor/github.com/appc/spec/schema/types/isolator_resources.go
  constant ResourceBlockBandwidthName (line 34) | ResourceBlockBandwidthName   = "resource/block-bandwidth"
  constant ResourceBlockIOPSName (line 35) | ResourceBlockIOPSName        = "resource/block-iops"
  constant ResourceCPUName (line 36) | ResourceCPUName              = "resource/cpu"
  constant ResourceMemoryName (line 37) | ResourceMemoryName           = "resource/memory"
  constant ResourceNetworkBandwidthName (line 38) | ResourceNetworkBandwidthName = "resource/network-bandwidth"
  function init (line 41) | func init() {
  type Resource (line 54) | type Resource interface
  type ResourceBase (line 60) | type ResourceBase struct
    method Limit (line 70) | func (r ResourceBase) Limit() *resource.Quantity {
    method Request (line 73) | func (r ResourceBase) Request() *resource.Quantity {
    method Default (line 76) | func (r ResourceBase) Default() bool {
    method UnmarshalJSON (line 80) | func (r *ResourceBase) UnmarshalJSON(b []byte) error {
    method AssertValid (line 84) | func (r ResourceBase) AssertValid() error {
    method multipleAllowed (line 90) | func (l ResourceBase) multipleAllowed() bool {
    method Conflicts (line 93) | func (l ResourceBase) Conflicts() []ACIdentifier {
  type resourceValue (line 64) | type resourceValue struct
  type ResourceBlockBandwidth (line 97) | type ResourceBlockBandwidth struct
    method AssertValid (line 101) | func (r ResourceBlockBandwidth) AssertValid() error {
  type ResourceBlockIOPS (line 111) | type ResourceBlockIOPS struct
    method AssertValid (line 115) | func (r ResourceBlockIOPS) AssertValid() error {
  type ResourceCPU (line 125) | type ResourceCPU struct
    method String (line 129) | func (r ResourceCPU) String() string {
    method AssertValid (line 133) | func (r ResourceCPU) AssertValid() error {
    method AsIsolator (line 140) | func (r ResourceCPU) AsIsolator() Isolator {
  function NewResourceCPUIsolator (line 155) | func NewResourceCPUIsolator(request, limit string) (*ResourceCPU, error) {
  type ResourceMemory (line 179) | type ResourceMemory struct
    method String (line 183) | func (r ResourceMemory) String() string {
    method AssertValid (line 187) | func (r ResourceMemory) AssertValid() error {
    method AsIsolator (line 194) | func (r ResourceMemory) AsIsolator() Isolator {
  function NewResourceMemoryIsolator (line 209) | func NewResourceMemoryIsolator(request, limit string) (*ResourceMemory, ...
  type ResourceNetworkBandwidth (line 233) | type ResourceNetworkBandwidth struct
    method AssertValid (line 237) | func (r ResourceNetworkBandwidth) AssertValid() error {

FILE: vendor/github.com/appc/spec/schema/types/isolator_unix.go
  constant UnixSysctlName (line 27) | UnixSysctlName = "os/unix/sysctl"
  function init (line 30) | func init() {
  type UnixSysctl (line 39) | type UnixSysctl
    method UnmarshalJSON (line 41) | func (s *UnixSysctl) UnmarshalJSON(b []byte) error {
    method AssertValid (line 51) | func (s UnixSysctl) AssertValid() error {
    method multipleAllowed (line 55) | func (s UnixSysctl) multipleAllowed() bool {
    method Conflicts (line 58) | func (s UnixSysctl) Conflicts() []ACIdentifier {
    method AsIsolator (line 62) | func (s UnixSysctl) AsIsolator() Isolator {
  function NewUnixSysctlIsolator (line 77) | func NewUnixSysctlIsolator(cfg map[string]string) (*UnixSysctl, error) {

FILE: vendor/github.com/appc/spec/schema/types/labels.go
  type Labels (line 29) | type Labels
    method assertValid (line 81) | func (l Labels) assertValid() error {
    method MarshalJSON (line 96) | func (l Labels) MarshalJSON() ([]byte, error) {
    method UnmarshalJSON (line 103) | func (l *Labels) UnmarshalJSON(data []byte) error {
    method Get (line 117) | func (l Labels) Get(name string) (val string, ok bool) {
    method ToMap (line 127) | func (l Labels) ToMap() map[ACIdentifier]string {
  type labels (line 31) | type labels
  type Label (line 33) | type Label struct
  type appcArchTuple (line 39) | type appcArchTuple struct
  type goArchTuple (line 43) | type goArchTuple struct
  function IsValidOSArch (line 51) | func IsValidOSArch(labels map[ACIdentifier]string, validOSArch map[strin...
  function LabelsFromMap (line 136) | func LabelsFromMap(labelsMap map[ACIdentifier]string) (Labels, error) {
  function ToAppcOSArch (line 149) | func ToAppcOSArch(goOs string, goArch string, goArchFlavor string) (appc...
  function ToGoOSArch (line 180) | func ToGoOSArch(appcOs string, appcArch string) (goOs string, goArch str...

FILE: vendor/github.com/appc/spec/schema/types/mountpoint.go
  type MountPoint (line 27) | type MountPoint struct
    method assertValid (line 33) | func (mount MountPoint) assertValid() error {
  function MountPointFromString (line 49) | func MountPointFromString(mp string) (*MountPoint, error) {

FILE: vendor/github.com/appc/spec/schema/types/port.go
  type Port (line 30) | type Port struct
    method UnmarshalJSON (line 50) | func (p *Port) UnmarshalJSON(data []byte) error {
    method MarshalJSON (line 66) | func (p Port) MarshalJSON() ([]byte, error) {
    method assertValid (line 73) | func (p Port) assertValid() error {
  type ExposedPort (line 41) | type ExposedPort struct
  type port (line 48) | type port
  function PortFromString (line 92) | func PortFromString(pt string) (*Port, error) {

FILE: vendor/github.com/appc/spec/schema/types/resource/amount.go
  type Scale (line 29) | type Scale
    method infScale (line 32) | func (s Scale) infScale() inf.Scale {
  constant Nano (line 37) | Nano  Scale = -9
  constant Micro (line 38) | Micro Scale = -6
  constant Milli (line 39) | Milli Scale = -3
  constant Kilo (line 40) | Kilo  Scale = 3
  constant Mega (line 41) | Mega  Scale = 6
  constant Giga (line 42) | Giga  Scale = 9
  constant Tera (line 43) | Tera  Scale = 12
  constant Peta (line 44) | Peta  Scale = 15
  constant Exa (line 45) | Exa   Scale = 18
  type int64Amount (line 57) | type int64Amount struct
    method Sign (line 63) | func (a int64Amount) Sign() int {
    method AsInt64 (line 77) | func (a int64Amount) AsInt64() (int64, bool) {
    method AsScaledInt64 (line 94) | func (a int64Amount) AsScaledInt64(scale Scale) (result int64, ok bool) {
    method AsDec (line 103) | func (a int64Amount) AsDec() *inf.Dec {
    method Cmp (line 111) | func (a int64Amount) Cmp(b int64Amount) int {
    method Add (line 161) | func (a *int64Amount) Add(b int64Amount) bool {
    method Sub (line 201) | func (a *int64Amount) Sub(b int64Amount) bool {
    method AsScale (line 207) | func (a int64Amount) AsScale(scale Scale) (int64Amount, bool) {
    method AsCanonicalBytes (line 218) | func (a int64Amount) AsCanonicalBytes(out []byte) (result []byte, expo...
    method AsCanonicalBase1024Bytes (line 247) | func (a int64Amount) AsCanonicalBase1024Bytes(out []byte) (result []by...
  type infDecAmount (line 258) | type infDecAmount struct
    method AsScale (line 264) | func (a infDecAmount) AsScale(scale Scale) (infDecAmount, bool) {
    method AsCanonicalBytes (line 273) | func (a infDecAmount) AsCanonicalBytes(out []byte) (result []byte, exp...
    method AsCanonicalBase1024Bytes (line 293) | func (a infDecAmount) AsCanonicalBase1024Bytes(out []byte) (result []b...

FILE: vendor/github.com/appc/spec/schema/types/resource/math.go
  constant maxInt64Factors (line 28) | maxInt64Factors = 18
  constant mostNegative (line 56) | mostNegative = -(mostPositive + 1)
  constant mostPositive (line 57) | mostPositive = 1<<63 - 1
  function int64Add (line 60) | func int64Add(a, b int64) (int64, bool) {
  function int64Multiply (line 79) | func int64Multiply(a, b int64) (int64, bool) {
  function int64MultiplyScale (line 92) | func int64MultiplyScale(a int64, b int64) (int64, bool) {
  function int64MultiplyScale10 (line 105) | func int64MultiplyScale10(a int64) (int64, bool) {
  function int64MultiplyScale100 (line 118) | func int64MultiplyScale100(a int64) (int64, bool) {
  function int64MultiplyScale1000 (line 131) | func int64MultiplyScale1000(a int64) (int64, bool) {
  function positiveScaleInt64 (line 144) | func positiveScaleInt64(base int64, scale Scale) (int64, bool) {
  function negativeScaleInt64 (line 173) | func negativeScaleInt64(base int64, scale Scale) (result int64, exact bo...
  function pow10Int64 (line 205) | func pow10Int64(b int64) int64 {
  function powInt64 (line 251) | func powInt64(a, b int64) int64 {
  function divideByScaleInt64 (line 265) | func divideByScaleInt64(base int64, scale Scale) (result, remainder int6...
  function removeInt64Factors (line 279) | func removeInt64Factors(value int64, base int64) (result int64, times in...
  function removeBigIntFactors (line 315) | func removeBigIntFactors(d, factor *big.Int) (result *big.Int, times int...

FILE: vendor/github.com/appc/spec/schema/types/resource/quantity.go
  type Quantity (line 95) | type Quantity struct
    method CanonicalizeBytes (line 396) | func (q *Quantity) CanonicalizeBytes(out []byte) (result, suffix []byt...
    method AsInt64 (line 437) | func (q *Quantity) AsInt64() (int64, bool) {
    method ToDec (line 445) | func (q *Quantity) ToDec() *Quantity {
    method AsDec (line 454) | func (q *Quantity) AsDec() *inf.Dec {
    method AsCanonicalBytes (line 466) | func (q *Quantity) AsCanonicalBytes(out []byte) (result []byte, expone...
    method IsZero (line 474) | func (q *Quantity) IsZero() bool {
    method Sign (line 483) | func (q *Quantity) Sign() int {
    method AsScale (line 492) | func (q *Quantity) AsScale(scale Scale) (CanonicalValue, bool) {
    method RoundUp (line 502) | func (q *Quantity) RoundUp(scale Scale) bool {
    method Add (line 521) | func (q *Quantity) Add(y Quantity) {
    method Sub (line 538) | func (q *Quantity) Sub(y Quantity) {
    method Cmp (line 551) | func (q *Quantity) Cmp(y Quantity) int {
    method CmpInt64 (line 560) | func (q *Quantity) CmpInt64(y int64) int {
    method Neg (line 568) | func (q *Quantity) Neg() {
    method String (line 584) | func (q *Quantity) String() string {
    method MarshalJSON (line 595) | func (q Quantity) MarshalJSON() ([]byte, error) {
    method UnmarshalJSON (line 623) | func (q *Quantity) UnmarshalJSON(value []byte) error {
    method Value (line 674) | func (q *Quantity) Value() int64 {
    method MilliValue (line 680) | func (q *Quantity) MilliValue() int64 {
    method ScaledValue (line 686) | func (q *Quantity) ScaledValue(scale Scale) int64 {
    method Set (line 696) | func (q *Quantity) Set(value int64) {
    method SetMilli (line 701) | func (q *Quantity) SetMilli(value int64) {
    method SetScaled (line 706) | func (q *Quantity) SetScaled(value int64, scale Scale) {
    method Copy (line 714) | func (q *Quantity) Copy() *Quantity {
  type CanonicalValue (line 109) | type CanonicalValue interface
  type Format (line 121) | type Format
  constant DecimalExponent (line 124) | DecimalExponent = Format("DecimalExponent")
  constant BinarySI (line 125) | BinarySI        = Format("BinarySI")
  constant DecimalSI (line 126) | DecimalSI       = Format("DecimalSI")
  function MustParse (line 131) | func MustParse(str string) Quantity {
  constant splitREString (line 142) | splitREString = "^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$"
  function parseQuantityString (line 156) | func parseQuantityString(str string) (positive bool, value, num, denom, ...
  function ParseQuantity (line 273) | func ParseQuantity(str string) (Quantity, error) {
  constant int64QuantityExpectedBytes (line 579) | int64QuantityExpectedBytes = 18
  function NewQuantity (line 646) | func NewQuantity(value int64, format Format) *Quantity {
  function NewMilliQuantity (line 657) | func NewMilliQuantity(value int64, format Format) *Quantity {
  function NewScaledQuantity (line 666) | func NewScaledQuantity(value int64, scale Scale) *Quantity {
  type qFlag (line 731) | type qFlag struct
    method Set (line 736) | func (qf qFlag) Set(val string) error {
    method String (line 747) | func (qf qFlag) String() string {
    method Type (line 752) | func (qf qFlag) Type() string {
  function QuantityFlag (line 758) | func QuantityFlag(flagName, defaultValue, description string) *Quantity {
  function NewQuantityFlagValue (line 766) | func NewQuantityFlagValue(q *Quantity) flag.Value {

FILE: vendor/github.com/appc/spec/schema/types/resource/scale_int.go
  function init (line 31) | func init() {
  function scaledValue (line 43) | func scaledValue(unscaled *big.Int, scale, newScale int) int64 {

FILE: vendor/github.com/appc/spec/schema/types/resource/suffix.go
  type suffix (line 23) | type suffix
  type suffixer (line 26) | type suffixer interface
  type bePair (line 36) | type bePair struct
  type listSuffixer (line 40) | type listSuffixer struct
    method addSuffix (line 46) | func (ls *listSuffixer) addSuffix(s suffix, pair bePair) {
    method lookup (line 61) | func (ls *listSuffixer) lookup(s suffix) (base, exponent int32, ok boo...
    method construct (line 69) | func (ls *listSuffixer) construct(base, exponent int32) (s suffix, ok ...
    method constructBytes (line 74) | func (ls *listSuffixer) constructBytes(base, exponent int32) (s []byte...
  type suffixHandler (line 79) | type suffixHandler struct
    method construct (line 137) | func (sh *suffixHandler) construct(base, exponent int32, fmt Format) (...
    method constructBytes (line 155) | func (sh *suffixHandler) constructBytes(base, exponent int32, format F...
    method interpret (line 180) | func (sh *suffixHandler) interpret(suffix suffix) (base, exponent int3...
  type fastLookup (line 84) | type fastLookup struct
    method interpret (line 88) | func (l fastLookup) interpret(s suffix) (base, exponent int32, format ...
  function newSuffixer (line 108) | func newSuffixer() suffixer {

FILE: vendor/github.com/appc/spec/schema/types/semver.go
  type SemVer (line 31) | type SemVer
    method LessThanMajor (line 47) | func (sv SemVer) LessThanMajor(versionB SemVer) bool {
    method LessThanExact (line 56) | func (sv SemVer) LessThanExact(versionB SemVer) bool {
    method String (line 62) | func (sv SemVer) String() string {
    method Empty (line 67) | func (sv SemVer) Empty() bool {
    method UnmarshalJSON (line 72) | func (sv *SemVer) UnmarshalJSON(data []byte) error {
    method MarshalJSON (line 86) | func (sv SemVer) MarshalJSON() ([]byte, error) {
  function NewSemVer (line 35) | func NewSemVer(s string) (*SemVer, error) {

FILE: vendor/github.com/appc/spec/schema/types/url.go
  type URL (line 25) | type URL
    method String (line 39) | func (u URL) String() string {
    method assertValidScheme (line 44) | func (u URL) assertValidScheme() error {
    method UnmarshalJSON (line 53) | func (u *URL) UnmarshalJSON(data []byte) error {
    method MarshalJSON (line 66) | func (u URL) MarshalJSON() ([]byte, error) {
  function NewURL (line 27) | func NewURL(s string) (*URL, error) {

FILE: vendor/github.com/appc/spec/schema/types/user_annotations.go
  type UserAnnotations (line 18) | type UserAnnotations

FILE: vendor/github.com/appc/spec/schema/types/user_labels.go
  type UserLabels (line 18) | type UserLabels

FILE: vendor/github.com/appc/spec/schema/types/uuid.go
  type UUID (line 36) | type UUID
    method String (line 38) | func (u UUID) String() string {
    method Set (line 42) | func (u *UUID) Set(s string) error {
    method Empty (line 68) | func (u UUID) Empty() bool {
    method UnmarshalJSON (line 72) | func (u *UUID) UnmarshalJSON(data []byte) error {
    method MarshalJSON (line 87) | func (u UUID) MarshalJSON() ([]byte, error) {
  function NewUUID (line 52) | func NewUUID(s string) (*UUID, error) {

FILE: vendor/github.com/appc/spec/schema/types/volume.go
  constant emptyVolumeDefaultMode (line 30) | emptyVolumeDefaultMode = "0755"
  constant emptyVolumeDefaultUID (line 31) | emptyVolumeDefaultUID  = 0
  constant emptyVolumeDefaultGID (line 32) | emptyVolumeDefaultGID  = 0
  type Volume (line 37) | type Volume struct
    method assertValid (line 55) | func (v Volume) assertValid() error {
    method UnmarshalJSON (line 97) | func (v *Volume) UnmarshalJSON(data []byte) error {
    method MarshalJSON (line 111) | func (v Volume) MarshalJSON() ([]byte, error) {
    method String (line 118) | func (v Volume) String() string {
  type volume (line 53) | type volume
  function VolumeFromString (line 158) | func VolumeFromString(vp string) (*Volume, error) {
  function VolumeFromParams (line 172) | func VolumeFromParams(params map[string][]string) (*Volume, error) {
  function maybeSetDefaults (line 234) | func maybeSetDefaults(vol *Volume) {

FILE: vendor/github.com/appc/spec/schema/version.go
  constant version (line 25) | version string = "0.8.10"
  function init (line 33) | func init() {

FILE: vendor/github.com/coreos/go-semver/example.go
  function main (line 9) | func main() {

FILE: vendor/github.com/coreos/go-semver/semver/semver.go
  type Version (line 26) | type Version struct
    method String (line 83) | func (v Version) String() string {
    method UnmarshalYAML (line 99) | func (v *Version) UnmarshalYAML(unmarshal func(interface{}) error) err...
    method MarshalJSON (line 112) | func (v Version) MarshalJSON() ([]byte, error) {
    method UnmarshalJSON (line 116) | func (v *Version) UnmarshalJSON(data []byte) error {
    method LessThan (line 132) | func (v Version) LessThan(versionB Version) bool {
    method Slice (line 148) | func (v Version) Slice() []int64 {
    method BumpMajor (line 236) | func (v *Version) BumpMajor() {
    method BumpMinor (line 245) | func (v *Version) BumpMinor() {
    method BumpPatch (line 253) | func (v *Version) BumpPatch() {
  type PreRelease (line 34) | type PreRelease
    method Slice (line 152) | func (p PreRelease) Slice() []string {
  function splitOff (line 36) | func splitOff(input *string, delim string) (val string) {
  function NewVersion (line 47) | func NewVersion(version string) (*Version, error) {
  function Must (line 76) | func Must(v *Version, err error) *Version {
  function preReleaseCompare (line 157) | func preReleaseCompare(versionA Version, versionB Version) int {
  function recursiveCompare (line 173) | func recursiveCompare(versionA []int64, versionB []int64) int {
  function recursivePreReleaseCompare (line 190) | func recursivePreReleaseCompare(versionA []string, versionB []string) int {

FILE: vendor/github.com/coreos/go-semver/semver/sort.go
  type Versions (line 21) | type Versions
    method Len (line 23) | func (s Versions) Len() int {
    method Swap (line 27) | func (s Versions) Swap(i, j int) {
    method Less (line 31) | func (s Versions) Less(i, j int) bool {
  function Sort (line 36) | func Sort(versions []*Version) {

FILE: vendor/github.com/coreos/ioprogress/draw.go
  type DrawFunc (line 13) | type DrawFunc
  type DrawTextFormatFunc (line 17) | type DrawTextFormatFunc
  function init (line 21) | func init() {
  function isTerminal (line 26) | func isTerminal(w io.Writer) bool {
  function DrawTerminal (line 35) | func DrawTerminal(w io.Writer) DrawFunc {
  function DrawTerminalf (line 43) | func DrawTerminalf(w io.Writer, f DrawTextFormatFunc) DrawFunc {
  function DrawTextFormatBytes (line 76) | func DrawTextFormatBytes(progress, total int64) string {
  function DrawTextFormatBar (line 93) | func DrawTextFormatBar(width int64) DrawTextFormatFunc {
  function DrawTextFormatBarForW (line 100) | func DrawTextFormatBarForW(width int64, w io.Writer) DrawTextFormatFunc {
  function ByteUnitStr (line 122) | func ByteUnitStr(n int64) string {

FILE: vendor/github.com/coreos/ioprogress/reader.go
  type Reader (line 10) | type Reader struct
    method Read (line 32) | func (r *Reader) Read(p []byte) (int, error) {
    method drawProgress (line 60) | func (r *Reader) drawProgress() {
    method finishProgress (line 82) | func (r *Reader) finishProgress() {
    method initProgress (line 94) | func (r *Reader) initProgress() {
    method drawFunc (line 101) | func (r *Reader) drawFunc() DrawFunc {

FILE: vendor/github.com/coreos/pkg/progressutil/iocopy.go
  type copyReader (line 29) | type copyReader struct
    method Read (line 36) | func (cr *copyReader) Read(p []byte) (int, error) {
    method updateProgressBar (line 46) | func (cr *copyReader) updateProgressBar() error {
    method formattedProgress (line 163) | func (cr *copyReader) formattedProgress() string {
  function NewCopyProgressPrinter (line 57) | func NewCopyProgressPrinter() *CopyProgressPrinter {
  type CopyProgressPrinter (line 63) | type CopyProgressPrinter struct
    method AddCopy (line 80) | func (cpp *CopyProgressPrinter) AddCopy(reader io.Reader, name string,...
    method PrintAndWait (line 121) | func (cpp *CopyProgressPrinter) PrintAndWait(printTo io.Writer, printI...
  function ByteUnitStr (line 176) | func ByteUnitStr(n int64) string {

FILE: vendor/github.com/coreos/pkg/progressutil/progressbar.go
  type ProgressBar (line 40) | type ProgressBar struct
    method clone (line 49) | func (pb *ProgressBar) clone() *ProgressBar {
    method GetCurrentProgress (line 61) | func (pb *ProgressBar) GetCurrentProgress() float64 {
    method SetCurrentProgress (line 70) | func (pb *ProgressBar) SetCurrentProgress(progress float64) error {
    method GetDone (line 81) | func (pb *ProgressBar) GetDone() bool {
    method SetDone (line 89) | func (pb *ProgressBar) SetDone(val bool) {
    method GetPrintBefore (line 96) | func (pb *ProgressBar) GetPrintBefore() string {
    method SetPrintBefore (line 104) | func (pb *ProgressBar) SetPrintBefore(before string) {
    method GetPrintAfter (line 111) | func (pb *ProgressBar) GetPrintAfter() string {
    method SetPrintAfter (line 119) | func (pb *ProgressBar) SetPrintAfter(after string) {
    method printToTerminal (line 216) | func (pb *ProgressBar) printToTerminal(printTo io.Writer, numColumns i...
    method printToNonTerminal (line 241) | func (pb *ProgressBar) printToNonTerminal(printTo io.Writer) {
  type ProgressBarPrinter (line 127) | type ProgressBarPrinter struct
    method AddProgressBar (line 148) | func (pbp *ProgressBarPrinter) AddProgressBar() *ProgressBar {
    method Print (line 162) | func (pbp *ProgressBarPrinter) Print(printTo io.Writer) (bool, error) {
  function moveCursorUp (line 210) | func moveCursorUp(printTo io.Writer, numLines int) {
  function isTerminal (line 251) | func isTerminal(w io.Writer) bool {

FILE: vendor/github.com/docker/distribution/blobs.go
  type ErrBlobInvalidDigest (line 34) | type ErrBlobInvalidDigest struct
    method Error (line 39) | func (err ErrBlobInvalidDigest) Error() string {
  type ErrBlobMounted (line 46) | type ErrBlobMounted struct
    method Error (line 51) | func (err ErrBlobMounted) Error() string {
  type Descriptor (line 60) | type Descriptor struct
    method Descriptor (line 85) | func (d Descriptor) Descriptor() Descriptor {
  type BlobStatter (line 92) | type BlobStatter interface
  type BlobDeleter (line 99) | type BlobDeleter interface
  type BlobEnumerator (line 104) | type BlobEnumerator interface
  type BlobDescriptorService (line 112) | type BlobDescriptorService interface
  type BlobDescriptorServiceFactory (line 131) | type BlobDescriptorServiceFactory interface
  type ReadSeekCloser (line 137) | type ReadSeekCloser interface
  type BlobProvider (line 143) | type BlobProvider interface
  type BlobServer (line 154) | type BlobServer interface
  type BlobIngester (line 171) | type BlobIngester interface
  type BlobCreateOption (line 191) | type BlobCreateOption interface
  type CreateOptions (line 197) | type CreateOptions struct
  type BlobWriter (line 211) | type BlobWriter interface
  type BlobService (line 245) | type BlobService interface
  type BlobStore (line 253) | type BlobStore interface

FILE: vendor/github.com/docker/distribution/digestset/set.go
  type Set (line 32) | type Set struct
    method Lookup (line 69) | func (dst *Set) Lookup(d string) (digest.Digest, error) {
    method Add (line 113) | func (dst *Set) Add(d digest.Digest) error {
    method Remove (line 144) | func (dst *Set) Remove(d digest.Digest) error {
    method All (line 172) | func (dst *Set) All() []digest.Digest {
  function NewSet (line 39) | func NewSet() *Set {
  function checkShortMatch (line 49) | func checkShortMatch(alg digest.Algorithm, hex, shortAlg, shortHex strin...
  function ShortCodeTable (line 188) | func ShortCodeTable(dst *Set, length int) map[digest.Digest]string {
  type digestEntry (line 226) | type digestEntry struct
  type digestEntries (line 232) | type digestEntries
    method Len (line 234) | func (d digestEntries) Len() int {
    method Less (line 238) | func (d digestEntries) Less(i, j int) bool {
    method Swap (line 245) | func (d digestEntries) Swap(i, j int) {

FILE: vendor/github.com/docker/distribution/errors.go
  type ErrTagUnknown (line 24) | type ErrTagUnknown struct
    method Error (line 28) | func (err ErrTagUnknown) Error() string {
  type ErrRepositoryUnknown (line 34) | type ErrRepositoryUnknown struct
    method Error (line 38) | func (err ErrRepositoryUnknown) Error() string {
  type ErrRepositoryNameInvalid (line 44) | type ErrRepositoryNameInvalid struct
    method Error (line 49) | func (err ErrRepositoryNameInvalid) Error() string {
  type ErrManifestUnknown (line 55) | type ErrManifestUnknown struct
    method Error (line 60) | func (err ErrManifestUnknown) Error() string {
  type ErrManifestUnknownRevision (line 66) | type ErrManifestUnknownRevision struct
    method Error (line 71) | func (err ErrManifestUnknownRevision) Error() string {
  type ErrManifestUnverified (line 77) | type ErrManifestUnverified struct
    method Error (line 79) | func (ErrManifestUnverified) Error() string {
  type ErrManifestVerification (line 86) | type ErrManifestVerification
    method Error (line 88) | func (errs ErrManifestVerification) Error() string {
  type ErrManifestBlobUnknown (line 98) | type ErrManifestBlobUnknown struct
    method Error (line 102) | func (err ErrManifestBlobUnknown) Error() string {
  type ErrManifestNameInvalid (line 108) | type ErrManifestNameInvalid struct
    method Error (line 113) | func (err ErrManifestNameInvalid) Error() string {

FILE: vendor/github.com/docker/distribution/manifests.go
  type Manifest (line 13) | type Manifest interface
  type ManifestBuilder (line 32) | type ManifestBuilder interface
  type ManifestService (line 51) | type ManifestService interface
  type ManifestEnumerator (line 67) | type ManifestEnumerator interface
  type Describable (line 73) | type Describable interface
  function ManifestMediaTypes (line 78) | func ManifestMediaTypes() (mediaTypes []string) {
  type UnmarshalFunc (line 88) | type UnmarshalFunc
  function UnmarshalManifest (line 94) | func UnmarshalManifest(ctHeader string, p []byte) (Manifest, Descriptor,...
  function RegisterManifestSchema (line 119) | func RegisterManifestSchema(mediaType string, u UnmarshalFunc) error {

FILE: vendor/github.com/docker/distribution/reference/helpers.go
  function IsNameOnly (line 6) | func IsNameOnly(ref Named) bool {
  function FamiliarName (line 18) | func FamiliarName(ref Named) string {
  function FamiliarString (line 27) | func FamiliarString(ref Reference) string {
  function FamiliarMatch (line 36) | func FamiliarMatch(pattern string, ref Reference) (bool, error) {

FILE: vendor/github.com/docker/distribution/reference/normalize.go
  type normalizedNamed (line 24) | type normalizedNamed interface
  function ParseNormalizedNamed (line 33) | func ParseNormalizedNamed(s string) (Named, error) {
  function splitDockerDomain (line 62) | func splitDockerDomain(name string) (domain, remainder string) {
  function familiarizeName (line 84) | func familiarizeName(named namedRepository) repository {
  method Familiar (line 100) | func (r reference) Familiar() Named {
  method Familiar (line 108) | func (r repository) Familiar() Named {
  method Familiar (line 112) | func (t taggedReference) Familiar() Named {
  method Familiar (line 119) | func (c canonicalReference) Familiar() Named {
  function TagNameOnly (line 128) | func TagNameOnly(ref Named) Named {
  function ParseAnyReference (line 144) | func ParseAnyReference(ref string) (Reference, error) {
  function ParseAnyReferenceWithSet (line 157) | func ParseAnyReferenceWithSet(ref string, ds *digestset.Set) (Reference,...

FILE: vendor/github.com/docker/distribution/reference/reference.go
  constant NameTotalLengthMax (line 37) | NameTotalLengthMax = 255
  type Reference (line 65) | type Reference interface
  type Field (line 72) | type Field struct
    method Reference (line 85) | func (f Field) Reference() Reference {
    method MarshalText (line 91) | func (f Field) MarshalText() (p []byte, err error) {
    method UnmarshalText (line 98) | func (f *Field) UnmarshalText(p []byte) error {
  function AsField (line 77) | func AsField(reference Reference) Field {
  type Named (line 109) | type Named interface
  type Tagged (line 115) | type Tagged interface
  type NamedTagged (line 121) | type NamedTagged interface
  type Digested (line 128) | type Digested interface
  type Canonical (line 135) | type Canonical interface
  type namedRepository (line 142) | type namedRepository interface
  function Domain (line 149) | func Domain(named Named) string {
  function Path (line 158) | func Path(named Named) (name string) {
  function splitDomain (line 166) | func splitDomain(name string) (string, string) {
  function SplitHostname (line 179) | func SplitHostname(named Named) (string, string) {
  function Parse (line 189) | func Parse(s string) (Reference, error) {
  function ParseNamed (line 241) | func ParseNamed(s string) (Named, error) {
  function WithName (line 254) | func WithName(name string) (Named, error) {
  function WithTag (line 271) | func WithTag(name Named, tag string) (NamedTagged, error) {
  function WithDigest (line 297) | func WithDigest(name Named, digest digest.Digest) (Canonical, error) {
  function TrimNamed (line 322) | func TrimNamed(ref Named) Named {
  function getBestReferenceType (line 330) | func getBestReferenceType(ref reference) Reference {
  type reference (line 357) | type reference struct
    method String (line 363) | func (r reference) String() string {
    method Tag (line 367) | func (r reference) Tag() string {
    method Digest (line 371) | func (r reference) Digest() digest.Digest {
  type repository (line 375) | type repository struct
    method String (line 380) | func (r repository) String() string {
    method Name (line 384) | func (r repository) Name() string {
    method Domain (line 391) | func (r repository) Domain() string {
    method Path (line 395) | func (r repository) Path() string {
  type digestReference (line 399) | type digestReference
    method String (line 401) | func (d digestReference) String() string {
    method Digest (line 405) | func (d digestReference) Digest() digest.Digest {
  type taggedReference (line 409) | type taggedReference struct
    method String (line 414) | func (t taggedReference) String() string {
    method Tag (line 418) | func (t taggedReference) Tag() string {
  type canonicalReference (line 422) | type canonicalReference struct
    method String (line 427) | func (c canonicalReference) String() string {
    method Digest (line 431) | func (c canonicalReference) Digest() digest.Digest {

FILE: vendor/github.com/docker/distribution/reference/regexp.go
  function literal (line 97) | func literal(s string) *regexp.Regexp {
  function expression (line 109) | func expression(res ...*regexp.Regexp) *regexp.Regexp {
  function optional (line 120) | func optional(res ...*regexp.Regexp) *regexp.Regexp {
  function repeated (line 126) | func repeated(res ...*regexp.Regexp) *regexp.Regexp {
  function group (line 131) | func group(res ...*regexp.Regexp) *regexp.Regexp {
  function capture (line 136) | func capture(res ...*regexp.Regexp) *regexp.Regexp {
  function anchored (line 141) | func anchored(res ...*regexp.Regexp) *regexp.Regexp {

FILE: vendor/github.com/docker/distribution/registry.go
  type Scope (line 10) | type Scope interface
  type fullScope (line 15) | type fullScope struct
    method Contains (line 17) | func (f fullScope) Contains(string) bool {
  type Namespace (line 28) | type Namespace interface
  type RepositoryEnumerator (line 53) | type RepositoryEnumerator interface
  type ManifestServiceOption (line 58) | type ManifestServiceOption interface
  function WithTag (line 63) | func WithTag(tag string) ManifestServiceOption {
  type WithTagOption (line 68) | type WithTagOption struct
    method Apply (line 71) | func (o WithTagOption) Apply(m ManifestService) error {
  type Repository (line 77) | type Repository interface

FILE: vendor/github.com/docker/distribution/tags.go
  type TagService (line 8) | type TagService interface

FILE: vendor/github.com/klauspost/compress/flate/copy.go
  function forwardCopy (line 13) | func forwardCopy(mem []byte, dst, src, n int) {

FILE: vendor/github.com/klauspost/compress/flate/crc32_amd64.go
  function crc32sse (line 15) | func crc32sse(a []byte) uint32
  function crc32sseAll (line 21) | func crc32sseAll(a []byte, dst []uint32)
  function matchLenSSE4 (line 30) | func matchLenSSE4(a, b []byte, max int) int
  function histogram (line 36) | func histogram(b []byte, h []int32)
  function init (line 39) | func init() {

FILE: vendor/github.com/klauspost/compress/flate/crc32_noasm.go
  function init (line 7) | func init() {
  function crc32sse (line 12) | func crc32sse(a []byte) uint32 {
  function crc32sseAll (line 17) | func crc32sseAll(a []byte, dst []uint32) {
  function matchLenSSE4 (line 22) | func matchLenSSE4(a, b []byte, max int) int {
  function histogram (line 30) | func histogram(b []byte, h []int32) {

FILE: vendor/github.com/klauspost/compress/flate/deflate.go
  constant NoCompression (line 15) | NoCompression      = 0
  constant BestSpeed (line 16) | BestSpeed          = 1
  constant BestCompression (line 17) | BestCompression    = 9
  constant DefaultCompression (line 18) | DefaultCompression = -1
  constant HuffmanOnly (line 29) | HuffmanOnly         = -2
  constant ConstantCompression (line 30) | ConstantCompression = HuffmanOnly
  constant logWindowSize (line 32) | logWindowSize    = 15
  constant windowSize (line 33) | windowSize       = 1 << logWindowSize
  constant windowMask (line 34) | windowMask       = windowSize - 1
  constant logMaxOffsetSize (line 35) | logMaxOffsetSize = 15
  constant minMatchLength (line 36) | minMatchLength   = 4
  constant maxMatchLength (line 37) | maxMatchLength   = 258
  constant minOffsetSize (line 38) | minOffsetSize    = 1
  constant maxFlateBlockTokens (line 42) | maxFlateBlockTokens = 1 << 14
  constant maxStoreBlockSize (line 43) | maxStoreBlockSize   = 65535
  constant hashBits (line 44) | hashBits            = 17
  constant hashSize (line 45) | hashSize            = 1 << hashBits
  constant hashMask (line 46) | hashMask            = (1 << hashBits) - 1
  constant hashShift (line 47) | hashShift           = (hashBits + minMatchLength - 1) / minMatchLength
  constant maxHashOffset (line 48) | maxHashOffset       = 1 << 24
  constant skipNever (line 50) | skipNever = math.MaxInt32
  type compressionLevel (line 55) | type compressionLevel struct
  type compressor (line 80) | type compressor struct
    method fillDeflate (line 123) | func (d *compressor) fillDeflate(b []byte) int {
    method writeBlock (line 160) | func (d *compressor) writeBlock(tok tokens, index int, eof bool) error {
    method writeBlockSkip (line 176) | func (d *compressor) writeBlockSkip(tok tokens, index int, eof bool) e...
    method fillWindow (line 201) | func (d *compressor) fillWindow(b []byte) {
    method findMatch (line 252) | func (d *compressor) findMatch(pos int, prevHead int, prevLength int, ...
    method findMatchSSE (line 307) | func (d *compressor) findMatchSSE(pos int, prevHead int, prevLength in...
    method writeStoredBlock (line 359) | func (d *compressor) writeStoredBlock(buf []byte) error {
    method initDeflate (line 405) | func (d *compressor) initDeflate() {
    method deflate (line 422) | func (d *compressor) deflate() {
    method deflateLazy (line 561) | func (d *compressor) deflateLazy() {
    method deflateSSE (line 737) | func (d *compressor) deflateSSE() {
    method deflateLazySSE (line 877) | func (d *compressor) deflateLazySSE() {
    method store (line 1051) | func (d *compressor) store() {
    method fillBlock (line 1060) | func (d *compressor) fillBlock(b []byte) int {
    method storeHuff (line 1069) | func (d *compressor) storeHuff() {
    method storeSnappy (line 1081) | func (d *compressor) storeSnappy() {
    method write (line 1125) | func (d *compressor) write(b []byte) (n int, err error) {
    method syncFlush (line 1140) | func (d *compressor) syncFlush() error {
    method init (line 1155) | func (d *compressor) init(w io.Writer, level int) (err error) {
    method reset (line 1200) | func (d *compressor) reset(w io.Writer) {
    method close (line 1235) | func (d *compressor) close() error {
  constant hashmul (line 367) | hashmul = 0x1e35a7bd
  function hash4 (line 372) | func hash4(b []byte) uint32 {
  function bulkHash4 (line 378) | func bulkHash4(b []byte, dst []uint32) {
  function matchLen (line 394) | func matchLen(a, b []byte, max int) int {
  function NewWriter (line 1263) | func NewWriter(w io.Writer, level int) (*Writer, error) {
  function NewWriterDict (line 1277) | func NewWriterDict(w io.Writer, level int, dict []byte) (*Writer, error) {
  type dictWriter (line 1288) | type dictWriter struct
    method Write (line 1292) | func (w *dictWriter) Write(b []byte) (n int, err error) {
  type Writer (line 1298) | type Writer struct
    method Write (line 1305) | func (w *Writer) Write(data []byte) (n int, err error) {
    method Flush (line 1318) | func (w *Writer) Flush() error {
    method Close (line 1325) | func (w *Writer) Close() error {
    method Reset (line 1332) | func (w *Writer) Reset(dst io.Writer) {
    method ResetDict (line 1347) | func (w *Writer) ResetDict(dst io.Writer, dict []byte) {

FILE: vendor/github.com/klauspost/compress/flate/dict_decoder.go
  type dictDecoder (line 27) | type dictDecoder struct
    method init (line 39) | func (dd *dictDecoder) init(size int, dict []byte) {
    method histSize (line 59) | func (dd *dictDecoder) histSize() int {
    method availRead (line 67) | func (dd *dictDecoder) availRead() int {
    method availWrite (line 72) | func (dd *dictDecoder) availWrite() int {
    method writeSlice (line 79) | func (dd *dictDecoder) writeSlice() []byte {
    method writeMark (line 86) | func (dd *dictDecoder) writeMark(cnt int) {
    method writeByte (line 93) | func (dd *dictDecoder) writeByte(c byte) {
    method writeCopy (line 103) | func (dd *dictDecoder) writeCopy(dist, length int) int {
    method tryWriteCopy (line 153) | func (dd *dictDecoder) tryWriteCopy(dist, length int) int {
    method readFlush (line 176) | func (dd *dictDecoder) readFlush() []byte {

FILE: vendor/github.com/klauspost/compress/flate/gen.go
  constant maxCodeLen (line 25) | maxCodeLen = 16
  constant huffmanChunkBits (line 34) | huffmanChunkBits  = 9
  constant huffmanNumChunks (line 35) | huffmanNumChunks  = 1 << huffmanChunkBits
  constant huffmanCountMask (line 36) | huffmanCountMask  = 15
  constant huffmanValueShift (line 37) | huffmanValueShift = 4
  type huffmanDecoder (line 40) | type huffmanDecoder struct
    method init (line 52) | func (h *huffmanDecoder) init(bits []int) bool {
  function main (line 194) | func main() {
  function initReverseByte (line 257) | func initReverseByte() {

FILE: vendor/github.com/klauspost/compress/flate/huffman_bit_writer.go
  constant offsetCodeCount (line 13) | offsetCodeCount = 30
  constant endBlockMarker (line 16) | endBlockMarker = 256
  constant lengthCodesStart (line 19) | lengthCodesStart = 257
  constant codegenCodeCount (line 22) | codegenCodeCount = 19
  constant badCode (line 23) | badCode          = 255
  constant bufferFlushSize (line 29) | bufferFlushSize = 240
  constant bufferSize (line 34) | bufferSize = bufferFlushSize + 8
  type huffmanBitWriter (line 79) | type huffmanBitWriter struct
    method reset (line 113) | func (w *huffmanBitWriter) reset(writer io.Writer) {
    method flush (line 119) | func (w *huffmanBitWriter) flush() {
    method write (line 140) | func (w *huffmanBitWriter) write(b []byte) {
    method writeBits (line 147) | func (w *huffmanBitWriter) writeBits(b int32, nb uint) {
    method writeBytes (line 174) | func (w *huffmanBitWriter) writeBytes(bytes []byte) {
    method generateCodegen (line 208) | func (w *huffmanBitWriter) generateCodegen(numLiterals int, numOffsets...
    method dynamicSize (line 296) | func (w *huffmanBitWriter) dynamicSize(litEnc, offEnc *huffmanEncoder,...
    method fixedSize (line 315) | func (w *huffmanBitWriter) fixedSize(extraBits int) int {
    method storedSize (line 325) | func (w *huffmanBitWriter) storedSize(in []byte) (int, bool) {
    method writeCode (line 335) | func (w *huffmanBitWriter) writeCode(c hcode) {
    method writeDynamicHeader (line 367) | func (w *huffmanBitWriter) writeDynamicHeader(numLiterals int, numOffs...
    method writeStoredHeader (line 411) | func (w *huffmanBitWriter) writeStoredHeader(length int, isEof bool) {
    method writeFixedHeader (line 425) | func (w *huffmanBitWriter) writeFixedHeader(isEof bool) {
    method writeBlock (line 442) | func (w *huffmanBitWriter) writeBlock(tokens []token, eof bool, input ...
    method writeBlockDynamic (line 511) | func (w *huffmanBitWriter) writeBlockDynamic(tokens []token, eof bool,...
    method indexTokens (line 543) | func (w *huffmanBitWriter) indexTokens(tokens []token) (numLiterals, n...
    method writeTokens (line 585) | func (w *huffmanBitWriter) writeTokens(tokens []token, leCodes, oeCode...
    method writeBlockHuff (line 629) | func (w *huffmanBitWriter) writeBlockHuff(eof bool, input []byte) {
  function newHuffmanBitWriter (line 101) | func newHuffmanBitWriter(w io.Writer) *huffmanBitWriter {
  function init (line 619) | func init() {

FILE: vendor/github.com/klauspost/compress/flate/huffman_code.go
  type hcode (line 13) | type hcode struct
    method set (line 51) | func (h *hcode) set(code uint16, length uint16) {
  type huffmanEncoder (line 17) | type huffmanEncoder struct
    method bitLength (line 108) | func (h *huffmanEncoder) bitLength(freq []int32) int {
    method bitCounts (line 133) | func (h *huffmanEncoder) bitCounts(list []literalNode, maxBits int32) ...
    method assignEncodingAndSize (line 247) | func (h *huffmanEncoder) assignEncodingAndSize(bitCount []int32, list ...
    method generate (line 273) | func (h *huffmanEncoder) generate(freq []int32, maxBits int32) {
  type literalNode (line 25) | type literalNode struct
  type levelInfo (line 31) | type levelInfo struct
  function maxNode (line 56) | func maxNode() literalNode { return literalNode{math.MaxUint16, math.Max...
  function newHuffmanEncoder (line 58) | func newHuffmanEncoder(size int) *huffmanEncoder {
  function generateFixedLiteralEncoding (line 63) | func generateFixedLiteralEncoding() *huffmanEncoder {
  function generateFixedOffsetEncoding (line 96) | func generateFixedOffsetEncoding() *huffmanEncoder {
  constant maxBitsLimit (line 118) | maxBitsLimit = 16
  type byLiteral (line 313) | type byLiteral
    method sort (line 315) | func (s *byLiteral) sort(a []literalNode) {
    method Len (line 320) | func (s byLiteral) Len() int { return len(s) }
    method Less (line 322) | func (s byLiteral) Less(i, j int) bool {
    method Swap (line 326) | func (s byLiteral) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
  type byFreq (line 328) | type byFreq
    method sort (line 330) | func (s *byFreq) sort(a []literalNode) {
    method Len (line 335) | func (s byFreq) Len() int { return len(s) }
    method Less (line 337) | func (s byFreq) Less(i, j int) bool {
    method Swap (line 344) | func (s byFreq) Swap(i, j int) { s[i], s[j] = s[j], s[i] }

FILE: vendor/github.com/klauspost/compress/flate/inflate.go
  constant maxCodeLen (line 18) | maxCodeLen = 16
  constant maxNumLit (line 22) | maxNumLit  = 286
  constant maxNumDist (line 23) | maxNumDist = 30
  constant numCodes (line 24) | numCodes   = 19
  type CorruptInputError (line 32) | type CorruptInputError
    method Error (line 34) | func (e CorruptInputError) Error() string {
  type InternalError (line 39) | type InternalError
    method Error (line 41) | func (e InternalError) Error() string { return "flate: internal error:...
  type ReadError (line 46) | type ReadError struct
    method Error (line 51) | func (e *ReadError) Error() string {
  type WriteError (line 58) | type WriteError struct
    method Error (line 63) | func (e *WriteError) Error() string {
  type Resetter (line 70) | type Resetter interface
  constant huffmanChunkBits (line 97) | huffmanChunkBits  = 9
  constant huffmanNumChunks (line 98) | huffmanNumChunks  = 1 << huffmanChunkBits
  constant huffmanCountMask (line 99) | huffmanCountMask  = 15
  constant huffmanValueShift (line 100) | huffmanValueShift = 4
  type huffmanDecoder (line 103) | type huffmanDecoder struct
    method init (line 115) | func (h *huffmanDecoder) init(bits []int) bool {
  type Reader (line 260) | type Reader interface
  type decompressor (line 266) | type decompressor struct
    method nextBlock (line 300) | func (f *decompressor) nextBlock() {
    method Read (line 333) | func (f *decompressor) Read(b []byte) (int, error) {
    method WriteTo (line 354) | func (f *decompressor) WriteTo(w io.Writer) (int64, error) {
    method Close (line 386) | func (f *decompressor) Close() error {
    method readHuffman (line 398) | func (f *decompressor) readHuffman() error {
    method huffmanBlock (line 510) | func (f *decompressor) huffmanBlock() {
    method dataBlock (line 654) | func (f *decompressor) dataBlock() {
    method copyData (line 689) | func (f *decompressor) copyData() {
    method finishBlock (line 715) | func (f *decompressor) finishBlock() {
    method moreBits (line 725) | func (f *decompressor) moreBits() error {
    method huffSym (line 740) | func (f *decompressor) huffSym(h *huffmanDecoder) (int, error) {
    method Reset (line 797) | func (f *decompressor) Reset(r io.Reader, dict []byte) error {
  function makeReader (line 770) | func makeReader(r io.Reader) Reader {
  function fixedHuffmanDecoderInit (line 777) | func fixedHuffmanDecoderInit() {
  function NewReader (line 817) | func NewReader(r io.Reader) io.ReadCloser {
  function NewReaderDict (line 836) | func NewReaderDict(r io.Reader, dict []byte) io.ReadCloser {

FILE: vendor/github.com/klauspost/compress/flate/reverse_bits.go
  function reverseUint16 (line 42) | func reverseUint16(v uint16) uint16 {
  function reverseBits (line 46) | func reverseBits(number uint16, bitLength byte) uint16 {

FILE: vendor/github.com/klauspost/compress/flate/snappy.go
  function emitLiteral (line 9) | func emitLiteral(dst *tokens, lit []byte) {
  function emitCopy (line 18) | func emitCopy(dst *tokens, offset, length int) {
  type snappyEnc (line 23) | type snappyEnc interface
  function newSnappy (line 28) | func newSnappy(level int) snappyEnc {
  constant tableBits (line 44) | tableBits       = 14
  constant tableSize (line 45) | tableSize       = 1 << tableBits
  constant tableMask (line 46) | tableMask       = tableSize - 1
  constant tableShift (line 47) | tableShift      = 32 - tableBits
  constant baseMatchOffset (line 48) | baseMatchOffset = 1
  constant baseMatchLength (line 49) | baseMatchLength = 3
  constant maxMatchOffset (line 50) | maxMatchOffset  = 1 << 15
  function load32 (line 53) | func load32(b []byte, i int) uint32 {
  function load64 (line 58) | func load64(b []byte, i int) uint64 {
  function hash (line 64) | func hash(u uint32) uint32 {
  type snappyL1 (line 69) | type snappyL1 struct
    method Reset (line 71) | func (e *snappyL1) Reset() {}
    method Encode (line 73) | func (e *snappyL1) Encode(dst *tokens, src []byte) {
  type tableEntry (line 216) | type tableEntry struct
  function load3232 (line 221) | func load3232(b []byte, i int32) uint32 {
  function load6432 (line 226) | func load6432(b []byte, i int32) uint64 {
  type snappyGen (line 235) | type snappyGen struct
    method matchlen (line 839) | func (e *snappyGen) matchlen(s, t int32, src []byte) int32 {
    method Reset (line 897) | func (e *snappyGen) Reset() {
  type snappyL2 (line 243) | type snappyL2 struct
    method Encode (line 250) | func (e *snappyL2) Encode(dst *tokens, src []byte) {
  type tableEntryPrev (line 399) | type tableEntryPrev struct
  type snappyL3 (line 405) | type snappyL3 struct
    method Encode (line 411) | func (e *snappyL3) Encode(dst *tokens, src []byte) {
  type snappyL4 (line 613) | type snappyL4 struct
    method Encode (line 619) | func (e *snappyL4) Encode(dst *tokens, src []byte) {

FILE: vendor/github.com/klauspost/compress/flate/token.go
  constant lengthShift (line 13) | lengthShift = 22
  constant offsetMask (line 14) | offsetMask  = 1<<lengthShift - 1
  constant typeMask (line 15) | typeMask    = 3 << 30
  constant literalType (line 16) | literalType = 0 << 30
  constant matchType (line 17) | matchType   = 1 << 30
  type token (line 70) | type token
    method typ (line 94) | func (t token) typ() uint32 { return uint32(t) & typeMask }
    method literal (line 97) | func (t token) literal() uint32 { return uint32(t - literalType) }
    method offset (line 100) | func (t token) offset() uint32 { return uint32(t) & offsetMask }
    method length (line 102) | func (t token) length() uint32 { return uint32((t - matchType) >> leng...
  type tokens (line 72) | type tokens struct
  function literalToken (line 78) | func literalToken(literal uint32) token { return token(literalType + lit...
  function matchToken (line 81) | func matchToken(xlength uint32, xoffset uint32) token {
  function matchTokend (line 85) | func matchTokend(xlength uint32, xoffset uint32) token {
  function lengthCode (line 104) | func lengthCode(len uint32) uint32 { return lengthCodes[len] }
  function offsetCode (line 107) | func offsetCode(off uint32) uint32 {

FILE: vendor/github.com/klauspost/cpuid/cpuid.go
  type Vendor (line 16) | type Vendor
  constant Other (line 19) | Other Vendor = iota
  constant Intel (line 20) | Intel
  constant AMD (line 21) | AMD
  constant VIA (line 22) | VIA
  constant Transmeta (line 23) | Transmeta
  constant NSC (line 24) | NSC
  constant KVM (line 25) | KVM
  constant MSVM (line 26) | MSVM
  constant VMware (line 27) | VMware
  constant XenHVM (line 28) | XenHVM
  constant CMOV (line 32) | CMOV        = 1 << iota
  constant NX (line 33) | NX
  constant AMD3DNOW (line 34) | AMD3DNOW
  constant AMD3DNOWEXT (line 35) | AMD3DNOWEXT
  constant MMX (line 36) | MMX
  constant MMXEXT (line 37) | MMXEXT
  constant SSE (line 38) | SSE
  constant SSE2 (line 39) | SSE2
  constant SSE3 (line 40) | SSE3
  constant SSSE3 (line 41) | SSSE3
  constant SSE4 (line 42) | SSE4
  constant SSE4A (line 43) | SSE4A
  constant SSE42 (line 44) | SSE42
  constant AVX (line 45) | AVX
  constant AVX2 (line 46) | AVX2
  constant FMA3 (line 47) | FMA3
  constant FMA4 (line 48) | FMA4
  constant XOP (line 49) | XOP
  constant F16C (line 50) | F16C
  constant BMI1 (line 51) | BMI1
  constant BMI2 (line 52) | BMI2
  constant TBM (line 53) | TBM
  constant LZCNT (line 54) | LZCNT
  constant POPCNT (line 55) | POPCNT
  constant AESNI (line 56) | AESNI
  constant CLMUL (line 57) | CLMUL
  constant HTT (line 58) | HTT
  constant HLE (line 59) | HLE
  constant RTM (line 60) | RTM
  constant RDRAND (line 61) | RDRAND
  constant RDSEED (line 62) | RDSEED
  constant ADX (line 63) | ADX
  constant SHA (line 64) | SHA
  constant AVX512F (line 65) | AVX512F
  constant AVX512DQ (line 66) | AVX512DQ
  constant AVX512IFMA (line 67) | AVX512IFMA
  constant AVX512PF (line 68) | AVX512PF
  constant AVX512ER (line 69) | AVX512ER
  constant AVX512CD (line 70) | AVX512CD
  constant AVX512BW (line 71) | AVX512BW
  constant AVX512VL (line 72) | AVX512VL
  constant AVX512VBMI (line 73) | AVX512VBMI
  constant MPX (line 74) | MPX
  constant ERMS (line 75) | ERMS
  constant RDTSCP (line 76) | RDTSCP
  constant CX16 (line 77) | CX16
  constant SGX (line 78) | SGX
  constant SSE2SLOW (line 81) | SSE2SLOW
  constant SSE3SLOW (line 82) | SSE3SLOW
  constant ATOM (line 83) | ATOM
  type CPUInfo (line 143) | type CPUInfo struct
    method Cmov (line 206) | func (c CPUInfo) Cmov() bool {
    method Amd3dnow (line 211) | func (c CPUInfo) Amd3dnow() bool {
    method Amd3dnowExt (line 216) | func (c CPUInfo) Amd3dnowExt() bool {
    method MMX (line 221) | func (c CPUInfo) MMX() bool {
    method MMXExt (line 227) | func (c CPUInfo) MMXExt() bool {
    method SSE (line 232) | func (c CPUInfo) SSE() bool {
    method SSE2 (line 237) | func (c CPUInfo) SSE2() bool {
    method SSE3 (line 242) | func (c CPUInfo) SSE3() bool {
    method SSSE3 (line 247) | func (c CPUInfo) SSSE3() bool {
    method SSE4 (line 252) | func (c CPUInfo) SSE4() bool {
    method SSE42 (line 257) | func (c CPUInfo) SSE42() bool {
    method AVX (line 263) | func (c CPUInfo) AVX() bool {
    method AVX2 (line 268) | func (c CPUInfo) AVX2() bool {
    method FMA3 (line 273) | func (c CPUInfo) FMA3() bool {
    method FMA4 (line 278) | func (c CPUInfo) FMA4() bool {
    method XOP (line 283) | func (c CPUInfo) XOP() bool {
    method F16C (line 288) | func (c CPUInfo) F16C() bool {
    method BMI1 (line 293) | func (c CPUInfo) BMI1() bool {
    method BMI2 (line 298) | func (c CPUInfo) BMI2() bool {
    method TBM (line 304) | func (c CPUInfo) TBM() bool {
    method Lzcnt (line 309) | func (c CPUInfo) Lzcnt() bool {
    method Popcnt (line 314) | func (c CPUInfo) Popcnt() bool {
    method HTT (line 319) | func (c CPUInfo) HTT() bool {
    method SSE2Slow (line 324) | func (c CPUInfo) SSE2Slow() bool {
    method SSE3Slow (line 329) | func (c CPUInfo) SSE3Slow() bool {
    method AesNi (line 335) | func (c CPUInfo) AesNi() bool {
    method Clmul (line 341) | func (c CPUInfo) Clmul() bool {
    method NX (line 346) | func (c CPUInfo) NX() bool {
    method SSE4A (line 351) | func (c CPUInfo) SSE4A() bool {
    method HLE (line 356) | func (c CPUInfo) HLE() bool {
    method RTM (line 361) | func (c CPUInfo) RTM() bool {
    method Rdrand (line 366) | func (c CPUInfo) Rdrand() bool {
    method Rdseed (line 371) | func (c CPUInfo) Rdseed() bool {
    method ADX (line 376) | func (c CPUInfo) ADX() bool {
    method SHA (line 381) | func (c CPUInfo) SHA() bool {
    method AVX512F (line 386) | func (c CPUInfo) AVX512F() bool {
    method AVX512DQ (line 391) | func (c CPUInfo) AVX512DQ() bool {
    method AVX512IFMA (line 396) | func (c CPUInfo) AVX512IFMA() bool {
    method AVX512PF (line 401) | func (c CPUInfo) AVX512PF() bool {
    method AVX512ER (line 406) | func (c CPUInfo) AVX512ER() bool {
    method AVX512CD (line 411) | func (c CPUInfo) AVX512CD() bool {
    method AVX512BW (line 416) | func (c CPUInfo) AVX512BW() bool {
    method AVX512VL (line 421) | func (c CPUInfo) AVX512VL() bool {
    method AVX512VBMI (line 426) | func (c CPUInfo) AVX512VBMI() bool {
    method MPX (line 431) | func (c CPUInfo) MPX() bool {
    method ERMS (line 436) | func (c CPUInfo) ERMS() bool {
    method RDTSCP (line 440) | func (c CPUInfo) RDTSCP() bool {
    method CX16 (line 444) | func (c CPUInfo) CX16() bool {
    method Atom (line 449) | func (c CPUInfo) Atom() bool {
    method Intel (line 454) | func (c CPUInfo) Intel() bool {
    method AMD (line 459) | func (c CPUInfo) AMD() bool {
    method Transmeta (line 464) | func (c CPUInfo) Transmeta() bool {
    method NSC (line 469) | func (c CPUInfo) NSC() bool {
    method VIA (line 474) | func (c CPUInfo) VIA() bool {
    method RTCounter (line 481) | func (c CPUInfo) RTCounter() uint64 {
    method Ia32TscAux (line 493) | func (c CPUInfo) Ia32TscAux() uint32 {
    method LogicalCPU (line 505) | func (c CPUInfo) LogicalCPU() int {
    method VM (line 516) | func (c CPUInfo) VM() bool {
    method cacheSize (line 688) | func (c *CPUInfo) cacheSize() {
  function init (line 176) | func init() {
  function Detect (line 188) | func Detect() {
  type Flags (line 525) | type Flags
    method String (line 529) | func (f Flags) String() string {
    method Strings (line 534) | func (f Flags) Strings() []string {
  function maxExtendedFunction (line 547) | func maxExtendedFunction() uint32 {
  function maxFunctionID (line 552) | func maxFunctionID() uint32 {
  function brandName (line 557) | func brandName() string {
  function threadsPerCore (line 569) | func threadsPerCore() int {
  function logicalCores (line 598) | func logicalCores() int {
  function familyModel (line 624) | func familyModel() (int, int) {
  function physicalCores (line 634) | func physicalCores() int {
  function vendorID (line 663) | func vendorID() Vendor {
  function cacheLine (line 673) | func cacheLine() int {
  type SGXSupport (line 752) | type SGXSupport struct
  function sgx (line 760) | func sgx(available bool) (rval SGXSupport) {
  function support (line 776) | func support() Flags {
  function valAsString (line 1002) | func valAsString(values ...uint32) []byte {

FILE: vendor/github.com/klauspost/cpuid/detect_intel.go
  function asmCpuid (line 7) | func asmCpuid(op uint32) (eax, ebx, ecx, edx uint32)
  function asmCpuidex (line 8) | func asmCpuidex(op, op2 uint32) (eax, ebx, ecx, edx uint32)
  function asmXgetbv (line 9) | func asmXgetbv(index uint32) (eax, edx uint32)
  function asmRdtscpAsm (line 10) | func asmRdtscpAsm() (eax, ebx, ecx, edx uint32)
  function initCPU (line 12) | func initCPU() {

FILE: vendor/github.com/klauspost/cpuid/detect_ref.go
  function initCPU (line 7) | func initCPU() {

FILE: vendor/github.com/klauspost/cpuid/private-gen.go
  function main (line 39) | func main() {
  function copyFile (line 139) | func copyFile(src, dst string) (err error) {
  function copyFileContents (line 170) | func copyFileContents(src, dst string) (err error) {
  type rewrite (line 193) | type rewrite
  function initRewrite (line 196) | func initRewrite(rewriteRule string) rewrite {
  function parseExpr (line 211) | func parseExpr(s, what string) ast.Expr {
  function rewriteFile (line 230) | func rewriteFile(pattern, replace ast.Expr, p *ast.File) *ast.File {
  function set (line 258) | func set(x, y reflect.Value) {
  function apply (line 290) | func apply(f func(reflect.Value) reflect.Value, val reflect.Value) refle...
  function isWildcard (line 325) | func isWildcard(s string) bool {
  function match (line 333) | func match(m map[string]reflect.Value, pattern, val reflect.Value) bool {
  function subst (line 421) | func subst(m map[string]reflect.Value, pattern reflect.Value, pos reflec...

FILE: vendor/github.com/klauspost/crc32/crc32.go
  constant Size (line 21) | Size = 4
  constant IEEE (line 27) | IEEE = 0xedb88320
  constant Castagnoli (line 32) | Castagnoli = 0x82f63b78
  constant Koopman (line 37) | Koopman = 0xeb31d82e
  type Table (line 41) | type Table
  function castagnoliInit (line 51) | func castagnoliInit() {
  type slicing8Table (line 60) | type slicing8Table
  function MakeTable (line 68) | func MakeTable(poly uint32) *Table {
  function makeTable (line 80) | func makeTable(poly uint32) *Table {
  function makeTable8 (line 97) | func makeTable8(poly uint32) *slicing8Table {
  type digest (line 111) | type digest struct
    method Size (line 126) | func (d *digest) Size() int { return Size }
    method BlockSize (line 128) | func (d *digest) BlockSize() int { return 1 }
    method Reset (line 130) | func (d *digest) Reset() { d.crc = 0 }
    method Write (line 168) | func (d *digest) Write(p []byte) (n int, err error) {
    method Sum32 (line 173) | func (d *digest) Sum32() uint32 { return d.crc }
    method Sum (line 175) | func (d *digest) Sum(in []byte) []byte {
  function New (line 119) | func New(tab *Table) hash.Hash32 { return &digest{0, tab} }
  function NewIEEE (line 124) | func NewIEEE() hash.Hash32 { return New(IEEETable) }
  function update (line 132) | func update(crc uint32, tab *Table, p []byte) uint32 {
  function updateSlicingBy8 (line 141) | func updateSlicingBy8(crc uint32, tab *slicing8Table, p []byte) uint32 {
  function Update (line 158) | func Update(crc uint32, tab *Table, p []byte) uint32 {
  function Checksum (line 182) | func Checksum(data []byte, tab *Table) uint32 { return Update(0, tab, da...
  function ChecksumIEEE (line 186) | func ChecksumIEEE(data []byte) uint32 { return updateIEEE(0, data) }

FILE: vendor/github.com/klauspost/crc32/crc32_amd64.go
  function haveSSE41 (line 14) | func haveSSE41() bool
  function haveSSE42 (line 15) | func haveSSE42() bool
  function haveCLMUL (line 16) | func haveCLMUL() bool
  function castagnoliSSE42 (line 21) | func castagnoliSSE42(crc uint32, p []byte) uint32
  function ieeeCLMUL (line 26) | func ieeeCLMUL(crc uint32, p []byte) uint32
  function updateCastagnoli (line 31) | func updateCastagnoli(crc uint32, p []byte) uint32 {
  function updateIEEE (line 42) | func updateIEEE(crc uint32, p []byte) uint32 {

FILE: vendor/github.com/klauspost/crc32/crc32_amd64p32.go
  function haveSSE42 (line 14) | func haveSSE42() bool
  function castagnoliSSE42 (line 19) | func castagnoliSSE42(crc uint32, p []byte) uint32
  function updateCastagnoli (line 23) | func updateCastagnoli(crc uint32, p []byte) uint32 {
  function updateIEEE (line 30) | func updateIEEE(crc uint32, p []byte) uint32 {

FILE: vendor/github.com/klauspost/crc32/crc32_generic.go
  function updateCastagnoli (line 12) | func updateCastagnoli(crc uint32, p []byte) uint32 {
  function updateIEEE (line 20) | func updateIEEE(crc uint32, p []byte) uint32 {

FILE: vendor/github.com/klauspost/pgzip/gunzip.go
  constant gzipID1 (line 30) | gzipID1     = 0x1f
  constant gzipID2 (line 31) | gzipID2     = 0x8b
  constant gzipDeflate (line 32) | gzipDeflate = 8
  constant flagText (line 33) | flagText    = 1 << 0
  constant flagHdrCrc (line 34) | flagHdrCrc  = 1 << 1
  constant flagExtra (line 35) | flagExtra   = 1 << 2
  constant flagName (line 36) | flagName    = 1 << 3
  constant flagComment (line 37) | flagComment = 1 << 4
  function makeReader (line 40) | func makeReader(r io.Reader) flate.Reader {
  type Header (line 56) | type Header struct
  type Reader (line 78) | type Reader struct
    method Reset (line 167) | func (z *Reader) Reset(r io.Reader) error {
    method Multistream (line 209) | func (z *Reader) Multistream(ok bool) {
    method readString (line 218) | func (z *Reader) readString() (string, error) {
    method read2 (line 246) | func (z *Reader) read2() (uint32, error) {
    method readHeader (line 254) | func (z *Reader) readHeader(save bool) error {
    method killReadAhead (line 323) | func (z *Reader) killReadAhead() error {
    method doReadAhead (line 346) | func (z *Reader) doReadAhead() {
    method Read (line 421) | func (z *Reader) Read(p []byte) (n int, err error) {
    method WriteTo (line 494) | func (z *Reader) WriteTo(w io.Writer) (n int64, err error) {
    method Close (line 562) | func (z *Reader) Close() error {
  type read (line 104) | type read struct
  function NewReader (line 112) | func NewReader(r io.Reader) (*Reader, error) {
  function NewReaderN (line 139) | func NewReaderN(r io.Reader, blockSize, blocks int) (*Reader, error) {
  function get4 (line 214) | func get4(p []byte) uint32 {

FILE: vendor/github.com/klauspost/pgzip/gzip.go
  constant defaultBlockSize (line 20) | defaultBlockSize = 250000
  constant tailSize (line 21) | tailSize         = 16384
  constant defaultBlocks (line 22) | defaultBlocks    = 16
  constant NoCompression (line 28) | NoCompression       = flate.NoCompression
  constant BestSpeed (line 29) | BestSpeed           = flate.BestSpeed
  constant BestCompression (line 30) | BestCompression     = flate.BestCompression
  constant DefaultCompression (line 31) | DefaultCompression  = flate.DefaultCompression
  constant ConstantCompression (line 32) | ConstantCompression = flate.ConstantCompression
  type Writer (line 37) | type Writer struct
    method SetConcurrency (line 70) | func (z *Writer) SetConcurrency(blockSize, blocks int) error {
    method pushError (line 118) | func (z *Writer) pushError(err error) {
    method init (line 123) | func (z *Writer) init(w io.Writer, level int) {
    method Reset (line 157) | func (z *Writer) Reset(w io.Writer) {
    method writeBytes (line 179) | func (z *Writer) writeBytes(b []byte) error {
    method writeString (line 194) | func (z *Writer) writeString(s string) (err error) {
    method compressCurrent (line 225) | func (z *Writer) compressCurrent(flush bool) {
    method checkError (line 259) | func (z *Writer) checkError() error {
    method Write (line 283) | func (z *Writer) Write(p []byte) (int, error) {
    method Flush (line 431) | func (z *Writer) Flush() error {
    method UncompressedSize (line 455) | func (z Writer) UncompressedSize() int {
    method Close (line 461) | func (z *Writer) Close() error {
  type result (line 57) | type result struct
  function NewWriter (line 94) | func NewWriter(w io.Writer) *Writer {
  function NewWriterLevel (line 105) | func NewWriterLevel(w io.Writer, level int) (*Writer, error) {
  function put2 (line 166) | func put2(p []byte, v uint16) {
  function put4 (line 171) | func put4(p []byte, v uint32) {
  function compressBlock (line 396) | func compressBlock(p, prevTail []byte, z Writer, r result) {

FILE: vendor/github.com/opencontainers/go-digest/algorithm.go
  type Algorithm (line 13) | type Algorithm
    method Available (line 43) | func (a Algorithm) Available() bool {
    method String (line 53) | func (a Algorithm) String() string {
    method Size (line 58) | func (a Algorithm) Size() int {
    method Set (line 67) | func (a *Algorithm) Set(value string) error {
    method Digester (line 85) | func (a Algorithm) Digester() Digester {
    method Hash (line 94) | func (a Algorithm) Hash() hash.Hash {
    method FromReader (line 115) | func (a Algorithm) FromReader(rd io.Reader) (Digest, error) {
    method FromBytes (line 126) | func (a Algorithm) FromBytes(p []byte) Digest {
    method FromString (line 142) | func (a Algorithm) FromString(s string) Digest {
  constant SHA256 (line 17) | SHA256 Algorithm = "sha256"
  constant SHA384 (line 18) | SHA384 Algorithm = "sha384"
  constant SHA512 (line 19) | SHA512 Algorithm = "sha512"
  constant Canonical (line 24) | Canonical = SHA256

FILE: vendor/github.com/opencontainers/go-digest/digest.go
  type Digest (line 22) | type Digest
    method Validate (line 83) | func (d Digest) Validate() error {
    method Algorithm (line 109) | func (d Digest) Algorithm() Algorithm {
    method Verifier (line 115) | func (d Digest) Verifier() Verifier {
    method Hex (line 124) | func (d Digest) Hex() string {
    method String (line 128) | func (d Digest) String() string {
    method sepIndex (line 132) | func (d Digest) sepIndex() int {
  function NewDigest (line 25) | func NewDigest(alg Algorithm, h hash.Hash) Digest {
  function NewDigestFromBytes (line 33) | func NewDigestFromBytes(alg Algorithm, p []byte) Digest {
  function NewDigestFromHex (line 38) | func NewDigestFromHex(alg, hex string) Digest {
  function Parse (line 61) | func Parse(s string) (Digest, error) {
  function FromReader (line 67) | func FromReader(rd io.Reader) (Digest, error) {
  function FromBytes (line 72) | func FromBytes(p []byte) Digest {
  function FromString (line 77) | func FromString(s string) Digest {

FILE: vendor/github.com/opencontainers/go-digest/digester.go
  type Digester (line 8) | type Digester interface
  type digester (line 14) | type digester struct
    method Hash (line 19) | func (d *digester) Hash() hash.Hash {
    method Digest (line 23) | func (d *digester) Digest() Digest {

FILE: vendor/github.com/opencontainers/go-digest/verifiers.go
  type Verifier (line 12) | type Verifier interface
  type hashVerifier (line 20) | type hashVerifier struct
    method Write (line 25) | func (hv hashVerifier) Write(p []byte) (n int, err error) {
    method Verified (line 29) | func (hv hashVerifier) Verified() bool {

FILE: vendor/github.com/opencontainers/image-spec/specs-go/v1/config.go
  type ImageConfig (line 18) | type ImageConfig struct
  type RootFS (line 51) | type RootFS struct
  type History (line 60) | type History struct
  type Image (line 78) | type Image struct

FILE: vendor/github.com/opencontainers/image-spec/specs-go/v1/descriptor.go
  type Descriptor (line 18) | type Descriptor struct

FILE: vendor/github.com/opencontainers/image-spec/specs-go/v1/manifest.go
  type Manifest (line 20) | type Manifest struct

FILE: vendor/github.com/opencontainers/image-spec/specs-go/v1/manifest_list.go
  type Platform (line 20) | type Platform struct
  type ManifestDescriptor (line 46) | type ManifestDescriptor struct
  type ManifestList (line 54) | type ManifestList struct

FILE: vendor/github.com/opencontainers/image-spec/specs-go/v1/mediatype.go
  constant MediaTypeDescriptor (line 19) | MediaTypeDescriptor = "application/vnd.oci.descriptor.v1+json"
  constant MediaTypeImageManifest (line 22) | MediaTypeImageManifest = "application/vnd.oci.image.manifest.v1+json"
  constant MediaTypeImageManifestList (line 25) | MediaTypeImageManifestList = "application/vnd.oci.image.manifest.list.v1...
  constant MediaTypeImageLayer (line 28) | MediaTypeImageLayer = "application/vnd.oci.image.layer.v1.tar+gzip"
  constant MediaTypeImageLayerNonDistributable (line 32) | MediaTypeImageLayerNonDistributable = "application/vnd.oci.image.layer.n...
  constant MediaTypeImageConfig (line 35) | MediaTypeImageConfig = "application/vnd.oci.image.config.v1+json"

FILE: vendor/github.com/opencontainers/image-spec/specs-go/version.go
  constant VersionMajor (line 21) | VersionMajor = 1
  constant VersionMinor (line 23) | VersionMinor = 0
  constant VersionPatch (line 25) | VersionPatch = 0
  constant VersionDev (line 28) | VersionDev = "-rc2"

FILE: vendor/github.com/opencontainers/image-spec/specs-go/versioned.go
  type Versioned (line 20) | type Versioned struct

FILE: vendor/github.com/spf13/pflag/flag.go
  type boolValue (line 117) | type boolValue
    method Set (line 124) | func (b *boolValue) Set(s string) error {
    method String (line 130) | func (b *boolValue) String() string { return fmt.Sprintf("%v", *b) }
  function newBoolValue (line 119) | func newBoolValue(val bool, p *bool) *boolValue {
  type intValue (line 133) | type intValue
    method Set (line 140) | func (i *intValue) Set(s string) error {
    method String (line 146) | func (i *intValue) String() string { return fmt.Sprintf("%v", *i) }
  function newIntValue (line 135) | func newIntValue(val int, p *int) *intValue {
  type int64Value (line 149) | type int64Value
    method Set (line 156) | func (i *int64Value) Set(s string) error {
    method String (line 162) | func (i *int64Value) String() string { return fmt.Sprintf("%v", *i) }
  function newInt64Value (line 151) | func newInt64Value(val int64, p *int64) *int64Value {
  type uintValue (line 165) | type uintValue
    method Set (line 172) | func (i *uintValue) Set(s string) error {
    method String (line 178) | func (i *uintValue) String() string { return fmt.Sprintf("%v", *i) }
  function newUintValue (line 167) | func newUintValue(val uint, p *uint) *uintValue {
  type uint64Value (line 181) | type uint64Value
    method Set (line 188) | func (i *uint64Value) Set(s string) error {
    method String (line 194) | func (i *uint64Value) String() string { return fmt.Sprintf("%v", *i) }
  function newUint64Value (line 183) | func newUint64Value(val uint64, p *uint64) *uint64Value {
  type stringValue (line 197) | type stringValue
    method Set (line 204) | func (s *stringValue) Set(val string) error {
    method String (line 209) | func (s *stringValue) String() string { return fmt.Sprintf("%s", *s) }
  function newStringValue (line 199) | func newStringValue(val string, p *string) *stringValue {
  type float64Value (line 212) | type float64Value
    method Set (line 219) | func (f *float64Value) Set(s string) error {
    method String (line 225) | func (f *float64Value) String() string { return fmt.Sprintf("%v", *f) }
  function newFloat64Value (line 214) | func newFloat64Value(val float64, p *float64) *float64Value {
  type durationValue (line 228) | type durationValue
    method Set (line 235) | func (d *durationValue) Set(s string) error {
    method String (line 241) | func (d *durationValue) String() string { return (*time.Duration)(d).S...
  function newDurationValue (line 230) | func newDurationValue(val time.Duration, p *time.Duration) *durationValue {
  type Value (line 245) | type Value interface
  type ErrorHandling (line 251) | type ErrorHandling
  constant ContinueOnError (line 254) | ContinueOnError ErrorHandling = iota
  constant ExitOnError (line 255) | ExitOnError
  constant PanicOnError (line 256) | PanicOnError
  type FlagSet (line 260) | type FlagSet struct
    method out (line 304) | func (f *FlagSet) out() io.Writer {
    method SetOutput (line 313) | func (f *FlagSet) SetOutput(output io.Writer) {
    method VisitAll (line 319) | func (f *FlagSet) VisitAll(fn func(*Flag)) {
    method HasFlags (line 325) | func (f *FlagSet) HasFlags() bool {
    method Visit (line 337) | func (f *FlagSet) Visit(fn func(*Flag)) {
    method Lookup (line 350) | func (f *FlagSet) Lookup(name string) *Flag {
    method Set (line 361) | func (f *FlagSet) Set(name, value string) error {
    method PrintDefaults (line 385) | func (f *FlagSet) PrintDefaults() {
    method FlagUsages (line 401) | func (f *FlagSet) FlagUsages() string {
    method NFlag (line 444) | func (f *FlagSet) NFlag() int { return len(f.actual) }
    method Arg (line 451) | func (f *FlagSet) Arg(i int) string {
    method NArg (line 465) | func (f *FlagSet) NArg() int { return len(f.args) }
    method Args (line 471) | func (f *FlagSet) Args() []string { return f.args }
    method BoolVar (line 478) | func (f *FlagSet) BoolVar(p *bool, name string, value bool, usage stri...
    method BoolVarP (line 483) | func (f *FlagSet) BoolVarP(p *bool, name, shorthand string, value bool...
    method Bool (line 500) | func (f *FlagSet) Bool(name string, value bool, usage string) *bool {
    method BoolP (line 507) | func (f *FlagSet) BoolP(name, shorthand string, value bool, usage stri...
    method IntVar (line 526) | func (f *FlagSet) IntVar(p *int, name string, value int, usage string) {
    method IntVarP (line 531) | func (f *FlagSet) IntVarP(p *int, name, shorthand string, value int, u...
    method Int (line 548) | func (f *FlagSet) Int(name string, value int, usage string) *int {
    method IntP (line 555) | func (f *FlagSet) IntP(name, shorthand string, value int, usage string...
    method Int64Var (line 574) | func (f *FlagSet) Int64Var(p *int64, name string, value int64, usage s...
    method Int64VarP (line 579) | func (f *FlagSet) Int64VarP(p *int64, name, shorthand string, value in...
    method Int64 (line 596) | func (f *FlagSet) Int64(name string, value int64, usage string) *int64 {
    method Int64P (line 603) | func (f *FlagSet) Int64P(name, shorthand string, value int64, usage st...
    method UintVar (line 622) | func (f *FlagSet) UintVar(p *uint, name string, value uint, usage stri...
    method UintVarP (line 627) | func (f *FlagSet) UintVarP(p *uint, name, shorthand string, value uint...
    method Uint (line 644) | func (f *FlagSet) Uint(name string, value uint, usage string) *uint {
    method UintP (line 651) | func (f *FlagSet) UintP(name, shorthand string, value uint, usage stri...
    method Uint64Var (line 670) | func (f *FlagSet) Uint64Var(p *uint64, name string, value uint64, usag...
    method Uint64VarP (line 675) | func (f *FlagSet) Uint64VarP(p *uint64, name, shorthand string, value ...
    method Uint64 (line 692) | func (f *FlagSet) Uint64(name string, value uint64, usage string) *uin...
    method Uint64P (line 699) | func (f *FlagSet) Uint64P(name, shorthand string, value uint64, usage ...
    method StringVar (line 718) | func (f *FlagSet) StringVar(p *string, name string, value string, usag...
    method StringVarP (line 723) | func (f *FlagSet) StringVarP(p *string, name, shorthand string, value ...
    method String (line 740) | func (f *FlagSet) String(name string, value string, usage string) *str...
    method StringP (line 747) | func (f *FlagSet) StringP(name, shorthand string, value string, usage ...
    method Float64Var (line 766) | func (f *FlagSet) Float64Var(p *float64, name string, value float64, u...
    method Float64VarP (line 771) | func (f *FlagSet) Float64VarP(p *float64, name, shorthand string, valu...
    method Float64 (line 788) | func (f *FlagSet) Float64(name string, value float64, usage string) *f...
    method Float64P (line 795) | func (f *FlagSet) Float64P(name, shorthand string, value float64, usag...
    method DurationVar (line 814) | func (f *FlagSet) DurationVar(p *time.Duration, name string, value tim...
    method DurationVarP (line 819) | func (f *FlagSet) DurationVarP(p *time.Duration, name, shorthand strin...
    method Duration (line 836) | func (f *FlagSet) Duration(name string, value time.Duration, usage str...
    method DurationP (line 843) | func (f *FlagSet) DurationP(name, shorthand string, value time.Duratio...
    method Var (line 866) | func (f *FlagSet) Var(value Value, name string, usage string) {
    method VarP (line 871) | func (f *FlagSet) VarP(value Value, name, shorthand, usage string) {
    method AddFlag (line 877) | func (f *FlagSet) AddFlag(flag *Flag) {
    method failf (line 925) | func (f *FlagSet) failf(format string, a ...interface{}) error {
    method usage (line 934) | func (f *FlagSet) usage() {
    method setFlag (line 944) | func (f *FlagSet) setFlag(flag *Flag, value string, origArg string) er...
    method parseLongArg (line 957) | func (f *FlagSet) parseLongArg(s string, args []string) (a []string, e...
    method parseShortArg (line 995) | func (f *FlagSet) parseShortArg(s string, args []string) (a []string, ...
    method parseArgs (line 1042) | func (f *FlagSet) parseArgs(args []string) (err error) {
    method Parse (line 1069) | func (f *FlagSet) Parse(arguments []string) error {
    method Parsed (line 1087) | func (f *FlagSet) Parsed() bool {
    method SetInterspersed (line 1123) | func (f *FlagSet) SetInterspersed(interspersed bool) {
    method Init (line 1130) | func (f *FlagSet) Init(name string, errorHandling ErrorHandling) {
  type Flag (line 279) | type Flag struct
  function sortFlags (line 289) | func sortFlags(flags map[string]*Flag) []*Flag {
  function VisitAll (line 331) | func VisitAll(fn func(*Flag)) {
  function Visit (line 345) | func Visit(fn func(*Flag)) {
  function Lookup (line 356) | func Lookup(name string) *Flag {
  function Set (line 379) | func Set(name, value string) error {
  function PrintDefaults (line 422) | func PrintDefaults() {
  function defaultUsage (line 427) | func defaultUsage(f *FlagSet) {
  function NFlag (line 447) | func NFlag() int { return len(commandLine.actual) }
  function Arg (line 460) | func Arg(i int) string {
  function NArg (line 468) | func NArg() int { return len(commandLine.args) }
  function Args (line 474) | func Args() []string { return commandLine.args }
  function BoolVar (line 489) | func BoolVar(p *bool, name string, value bool, usage string) {
  function BoolVarP (line 494) | func BoolVarP(p *bool, name, shorthand string, value bool, usage string) {
  function Bool (line 515) | func Bool(name string, value bool, usage string) *bool {
  function BoolP (line 520) | func BoolP(name, shorthand string, value bool, usage string) *bool {
  function IntVar (line 537) | func IntVar(p *int, name string, value int, usage string) {
  function IntVarP (line 542) | func IntVarP(p *int, name, shorthand string, value int, usage string) {
  function Int (line 563) | func Int(name string, value int, usage string) *int {
  function IntP (line 568) | func IntP(name, shorthand string, value int, usage string) *int {
  function Int64Var (line 585) | func Int64Var(p *int64, name string, value int64, usage string) {
  function Int64VarP (line 590) | func Int64VarP(p *int64, name, shorthand string, value int64, usage stri...
  function Int64 (line 611) | func Int64(name string, value int64, usage string) *int64 {
  function Int64P (line 616) | func Int64P(name, shorthand string, value int64, usage string) *int64 {
  function UintVar (line 633) | func UintVar(p *uint, name string, value uint, usage string) {
  function UintVarP (line 638) | func UintVarP(p *uint, name, shorthand string, value uint, usage string) {
  function Uint (line 659) | func Uint(name string, value uint, usage string) *uint {
  function UintP (line 664) | func UintP(name, shorthand string, value uint, usage string) *uint {
  function Uint64Var (line 681) | func Uint64Var(p *uint64, name string, value uint64, usage string) {
  function Uint64VarP (line 686) | func Uint64VarP(p *uint64, name, shorthand string, value uint64, usage s...
  function Uint64 (line 707) | func Uint64(name string, value uint64, usage string) *uint64 {
  function Uint64P (line 712) | func Uint64P(name, shorthand string, value uint64, usage string) *uint64 {
  function StringVar (line 729) | func StringVar(p *string, name string, value string, usage string) {
  function StringVarP (line 734) | func StringVarP(p *string, name, shorthand string, value string, usage s...
  function String (line 755) | func String(name string, value string, usage string) *string {
  function StringP (line 760) | func StringP(name, shorthand string, value string, usage string) *string {
  function Float64Var (line 777) | func Float64Var(p *float64, name string, value float64, usage string) {
  function Float64VarP (line 782) | func Float64VarP(p *float64, name, shorthand string, value float64, usag...
  function Float64 (line 803) | func Float64(name string, value float64, usage string) *float64 {
  function Float64P (line 808) | func Float64P(name, shorthand string, value float64, usage string) *floa...
  function DurationVar (line 825) | func DurationVar(p *time.Duration, name string, value time.Duration, usa...
  function DurationVarP (line 830) | func DurationVarP(p *time.Duration, name, shorthand string, value time.D...
  function Duration (line 851) | func Duration(name string, value time.Duration, usage string) *time.Dura...
  function DurationP (line 856) | func DurationP(name, shorthand string, value time.Duration, usage string...
  function Var (line 914) | func Var(value Value, name string, usage string) {
  function VarP (line 919) | func VarP(value Value, name, shorthand, usage string) {
  function Parse (line 1093) | func Parse() {
  function SetInterspersed (line 1099) | func SetInterspersed(interspersed bool) {
  function Parsed (line 1104) | func Parsed() bool {
  function NewFlagSet (line 1113) | func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {

FILE: vendor/go4.org/errorutil/highlight.go
  function HighlightBytePosition (line 32) | func HighlightBytePosition(f io.Reader, pos int64) (line, col int, highl...

FILE: vendor/golang.org/x/crypto/ssh/terminal/terminal.go
  type EscapeCodes (line 16) | type EscapeCodes struct
  type Terminal (line 39) | type Terminal struct
    method queue (line 218) | func (t *Terminal) queue(data []rune) {
    method moveCursorToPos (line 232) | func (t *Terminal) moveCursorToPos(pos int) {
    method move (line 266) | func (t *Terminal) move(up, down, left, right int) {
    method clearLineToRight (line 297) | func (t *Terminal) clearLineToRight() {
    method setLine (line 304) | func (t *Terminal) setLine(newLine []rune, newPos int) {
    method advanceCursor (line 317) | func (t *Terminal) advanceCursor(places int) {
    method eraseNPreviousChars (line 340) | func (t *Terminal) eraseNPreviousChars(n int) {
    method countToLeftWord (line 365) | func (t *Terminal) countToLeftWord() int {
    method countToRightWord (line 390) | func (t *Terminal) countToRightWord() int {
    method handleKey (line 430) | func (t *Terminal) handleKey(key rune) (line string, ok bool) {
    method addKeyToLine (line 567) | func (t *Terminal) addKeyToLine(key rune) {
    method writeLine (line 583) | func (t *Terminal) writeLine(line []rune) {
    method Write (line 596) | func (t *Terminal) Write(buf []byte) (n int, err error) {
    method ReadPassword (line 643) | func (t *Terminal) ReadPassword(prompt string) (line string, err error) {
    method ReadLine (line 660) | func (t *Terminal) ReadLine() (line string, err error) {
    method readLine (line 667) | func (t *Terminal) readLine() (line string, err error) {
    method SetPrompt (line 748) | func (t *Terminal) SetPrompt(prompt string) {
    method clearAndRepaintLinePlusNPrevious (line 755) | func (t *Terminal) clearAndRepaintLinePlusNPrevious(numPrevLines int) {
    method SetSize (line 776) | func (t *Terminal) SetSize(width, height int) error {
    method SetBracketedPasteMode (line 846) | func (t *Terminal) SetBracketedPasteMode(on bool) {
  function NewTerminal (line 101) | func NewTerminal(c io.ReadWriter, prompt string) *Terminal {
  constant keyCtrlD (line 114) | keyCtrlD     = 4
  constant keyCtrlU (line 115) | keyCtrlU     = 21
  constant keyEnter (line 116) | keyEnter     = '\r'
  constant keyEscape (line 117) | keyEscape    = 27
  constant keyBackspace (line 118) | keyBackspace = 127
  constant keyUnknown (line 119) | keyUnknown   = 0xd800 /* UTF-16 surrogate area */ + iota
  constant keyUp (line 120) | keyUp
  constant keyDown (line 121) | keyDown
  constant keyLeft (line 122) | keyLeft
  constant keyRight (line 123) | keyRight
  constant keyAltLeft (line 124) | keyAltLeft
  constant keyAltRight (line 125) | keyAltRight
  constant keyHome (line 126) | keyHome
  constant keyEnd (line 127) | keyEnd
  constant keyDeleteWord (line 128) | keyDeleteWord
  constant keyDeleteLine (line 129) | keyDeleteLine
  constant keyClearScreen (line 130) | keyClearScreen
  constant keyPasteStart (line 131) | keyPasteStart
  constant keyPasteEnd (line 132) | keyPasteEnd
  function bytesToKey (line 140) | func bytesToKey(b []byte, pasteActive bool) (rune, []byte) {
  function isPrintable (line 225) | func isPrintable(key rune) bool {
  constant maxLineLength (line 302) | maxLineLength = 4096
  function visualLength (line 408) | func visualLength(runes []rune) int {
  type pasteIndicatorError (line 829) | type pasteIndicatorError struct
    method Error (line 831) | func (pasteIndicatorError) Error() string {
  type stRingBuffer (line 855) | type stRingBuffer struct
    method Add (line 865) | func (s *stRingBuffer) Add(a string) {
    method NthPreviousEntry (line 883) | func (s *stRingBuffer) NthPreviousEntry(n int) (value string, ok bool) {

FILE: vendor/golang.org/x/crypto/ssh/terminal/util.go
  type State (line 26) | type State struct
  function IsTerminal (line 31) | func IsTerminal(fd int) bool {
  function MakeRaw (line 40) | func MakeRaw(fd int) (*State, error) {
  function GetState (line 58) | func GetState(fd int) (*State, error) {
  function Restore (line 69) | func Restore(fd int, state *State) error {
  function GetSize (line 75) | func GetSize(fd int) (width, height int, err error) {
  function ReadPassword (line 87) | func ReadPassword(fd int) ([]byte, error) {

FILE: vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go
  constant ioctlReadTermios (line 11) | ioctlReadTermios = syscall.TIOCGETA
  constant ioctlWriteTermios (line 12) | ioctlWriteTermios = syscall.TIOCSETA

FILE: vendor/golang.org/x/crypto/ssh/terminal/util_linux.go
  constant ioctlReadTermios (line 10) | ioctlReadTermios = 0x5401
  constant ioctlWriteTermios (line 11) | ioctlWriteTermios = 0x5402

FILE: vendor/golang.org/x/crypto/ssh/terminal/util_windows.go
  constant enableLineInput (line 26) | enableLineInput       = 2
  constant enableEchoInput (line 27) | enableEchoInput       = 4
  constant enableProcessedInput (line 28) | enableProcessedInput  = 1
  constant enableWindowInput (line 29) | enableWindowInput     = 8
  constant enableMouseInput (line 30) | enableMouseInput      = 16
  constant enableInsertMode (line 31) | enableInsertMode      = 32
  constant enableQuickEditMode (line 32) | enableQuickEditMode   = 64
  constant enableExtendedFlags (line 33) | enableExtendedFlags   = 128
  constant enableAutoPosition (line 34) | enableAutoPosition    = 256
  constant enableProcessedOutput (line 35) | enableProcessedOutput = 1
  constant enableWrapAtEolOutput (line 36) | enableWrapAtEolOutput = 2
  type short (line 48) | type short
  type word (line 49) | type word
  type coord (line 51) | type coord struct
  type smallRect (line 55) | type smallRect struct
  type consoleScreenBufferInfo (line 61) | type consoleScreenBufferInfo struct
  type State (line 70) | type State struct
  function IsTerminal (line 75) | func IsTerminal(fd int) bool {
  function MakeRaw (line 84) | func MakeRaw(fd int) (*State, error) {
  function GetState (line 100) | func GetState(fd int) (*State, error) {
  function Restore (line 111) | func Restore(fd int, state *State) error {
  function GetSize (line 117) | func GetSize(fd int) (width, height int, err error) {
  function ReadPassword (line 129) | func ReadPassword(fd int) ([]byte, error) {

FILE: vendor/gopkg.in/inf.v0/dec.go
  type Dec (line 83) | type Dec struct
    method Scale (line 127) | func (x *Dec) Scale() Scale {
    method Unscaled (line 135) | func (x *Dec) Unscaled() (u int64, ok bool) {
    method UnscaledBig (line 143) | func (x *Dec) UnscaledBig() *big.Int {
    method SetScale (line 151) | func (z *Dec) SetScale(scale Scale) *Dec {
    method SetUnscaled (line 158) | func (z *Dec) SetUnscaled(unscaled int64) *Dec {
    method SetUnscaledBig (line 165) | func (z *Dec) SetUnscaledBig(unscaled *big.Int) *Dec {
    method Set (line 172) | func (z *Dec) Set(x *Dec) *Dec {
    method Sign (line 186) | func (x *Dec) Sign() int {
    method Neg (line 191) | func (z *Dec) Neg(x *Dec) *Dec {
    method Cmp (line 203) | func (x *Dec) Cmp(y *Dec) int {
    method Abs (line 209) | func (z *Dec) Abs(x *Dec) *Dec {
    method Add (line 217) | func (z *Dec) Add(x, y *Dec) *Dec {
    method Sub (line 226) | func (z *Dec) Sub(x, y *Dec) *Dec {
    method Mul (line 235) | func (z *Dec) Mul(x, y *Dec) *Dec {
    method Round (line 243) | func (z *Dec) Round(x *Dec, s Scale, r Rounder) *Dec {
    method QuoRound (line 256) | func (z *Dec) QuoRound(x, y *Dec, s Scale, r Rounder) *Dec {
    method quo (line 260) | func (z *Dec) quo(x, y *Dec, s scaler, r Rounder) *Dec {
    method QuoExact (line 282) | func (z *Dec) QuoExact(x, y *Dec) *Dec {
    method quoRem (line 297) | func (z *Dec) quoRem(x, y *Dec, s Scale, useRem bool,
    method rescale (line 398) | func (x *Dec) rescale(newScale Scale) *Dec {
    method String (line 426) | func (x *Dec) String() string {
    method Format (line 462) | func (x *Dec) Format(s fmt.State, ch rune) {
    method scan (line 470) | func (z *Dec) scan(r io.RuneScanner) (*Dec, error) {
    method SetString (line 525) | func (z *Dec) SetString(s string) (*Dec, bool) {
    method Scan (line 544) | func (z *Dec) Scan(s fmt.ScanState, ch rune) error {
    method GobEncode (line 576) | func (x *Dec) GobEncode() ([]byte, error) {
    method GobDecode (line 586) | func (z *Dec) GobDecode(buf []byte) error {
    method MarshalText (line 604) | func (x *Dec) MarshalText() ([]byte, error) {
    method UnmarshalText (line 609) | func (z *Dec) UnmarshalText(data []byte) error {
  type Scale (line 89) | type Scale
  constant scaleSize (line 91) | scaleSize = 4
  type scaler (line 95) | type scaler interface
  function NewDec (line 116) | func NewDec(unscaled int64, scale Scale) *Dec {
  function NewDecBig (line 122) | func NewDecBig(unscaled *big.Int, scale Scale) *Dec {
  type sclr (line 336) | type sclr struct
    method Scale (line 338) | func (s sclr) Scale(x, y *Dec) Scale {
  type scaleQuoExact (line 342) | type scaleQuoExact struct
    method Scale (line 344) | func (sqe scaleQuoExact) Scale(x, y *Dec) Scale {
  function factor (line 356) | func factor(n *big.Int, p *big.Int) int {
  function factor2 (line 371) | func factor2(n *big.Int) int {
  function upscale (line 379) | func upscale(a, b *Dec) (*Dec, *Dec) {
  function exp10 (line 391) | func exp10(x Scale) *big.Int {
  function appendZeros (line 415) | func appendZeros(s []byte, n Scale) []byte {
  constant decGobVersion (line 554) | decGobVersion byte = 1
  function scaleBytes (line 556) | func scaleBytes(s Scale) []byte {
  function scale (line 567) | func scale(b []byte) (s Scale) {

FILE: vendor/gopkg.in/inf.v0/rounder.go
  type Rounder (line 13) | type Rounder
  type rounder (line 33) | type rounder interface
  type rndr (line 54) | type rndr struct
    method UseRemainder (line 59) | func (r rndr) UseRemainder() bool {
    method Round (line 63) | func (r rndr) Round(z, quo *Dec, remNum, remDen *big.Int) *Dec {
  function roundHalf (line 69) | func roundHalf(f func(c int, odd uint) (roundUp bool)) func(z, q *Dec, r...
  function init (line 97) | func init() {
Condensed preview — 181 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (963K chars).
[
  {
    "path": ".gitignore",
    "chars": 372,
    "preview": "# Compiled Object files, Static and Dynamic libs (Shared Objects)\n*.o\n*.a\n*.so\n\n# Folders\n_obj\n_test\n\n# Architecture spe"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 7856,
    "preview": "## v0.17.2\n\nThis is a bugfix release to ensure compatibility with newer go-1.10 toolchain.\n\n - lib/internal: fix tar hea"
  },
  {
    "path": "Documentation/devel/release.md",
    "chars": 3272,
    "preview": "# docker2aci release guide\n\nHow to perform a release of docker2aci.\nThis guide is probably unnecessarily verbose, so imp"
  },
  {
    "path": "LICENSE",
    "chars": 11325,
    "preview": "Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licens"
  },
  {
    "path": "MAINTAINERS",
    "chars": 139,
    "preview": "Alban Crequy <alban@kinvolk.io> (@alban)\nIago López Galeiras <iago@kinvolk.io> (@iaguis)\nKrzesimir Nowak <krzesimir@kinv"
  },
  {
    "path": "README.md",
    "chars": 5166,
    "preview": "# docker2aci - Convert docker images to ACI\n\n[![Build Status](https://semaphoreci.com/api/v1/projects/4472761c-2b88-41f2"
  },
  {
    "path": "build.sh",
    "chars": 976,
    "preview": "#!/usr/bin/env bash\nset -e\n\n# Gets the directory that this script is stored in.\n# https://stackoverflow.com/questions/59"
  },
  {
    "path": "glide.yaml",
    "chars": 714,
    "preview": "package: github.com/appc/docker2aci\nimport:\n- package: github.com/appc/spec\n  version: 0.8.10\n  subpackages:\n  - aci\n  -"
  },
  {
    "path": "lib/common/common.go",
    "chars": 7263,
    "preview": "// Copyright 2016 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "lib/common/common_test.go",
    "chars": 5949,
    "preview": "// Copyright 2017 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "lib/conversion_store.go",
    "chars": 3113,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "lib/docker2aci.go",
    "chars": 14567,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "lib/internal/backend/file/file.go",
    "chars": 14610,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "lib/internal/backend/repository/repository.go",
    "chars": 6867,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "lib/internal/backend/repository/repository1.go",
    "chars": 10652,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "lib/internal/backend/repository/repository2.go",
    "chars": 17881,
    "preview": "// Copyright 2016 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "lib/internal/docker/docker.go",
    "chars": 3879,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "lib/internal/internal.go",
    "chars": 24251,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "lib/internal/internal_test.go",
    "chars": 2963,
    "preview": "// Copyright 2017 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "lib/internal/tarball/tarfile.go",
    "chars": 1362,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "lib/internal/tarball/walk.go",
    "chars": 1276,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "lib/internal/types/docker_types.go",
    "chars": 3811,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "lib/internal/typesV2/docker_types.go",
    "chars": 3595,
    "preview": "// Copyright 2016 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "lib/internal/util/util.go",
    "chars": 2481,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "lib/tests/common.go",
    "chars": 3169,
    "preview": "package test\n\nimport (\n\t\"archive/tar\"\n\t\"bytes\"\n\t\"crypto/sha256\"\n\t\"encoding/hex\"\n\t\"encoding/json\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"pa"
  },
  {
    "path": "lib/tests/server.go",
    "chars": 3323,
    "preview": "package test\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"os\"\n\t\"path\"\n\t\"strings\"\n\t\"testing\"\n)\n\nfunc RunDock"
  },
  {
    "path": "lib/tests/v22_test.go",
    "chars": 10227,
    "preview": "package test\n\nimport (\n\t\"testing\"\n\n\t\"archive/tar\"\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"path\"\n\t\"reflect\"\n\t\"strings\"\n\t\"time\"\n\n\tdock"
  },
  {
    "path": "lib/version.go",
    "chars": 724,
    "preview": "// Copyright 2016 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "main.go",
    "chars": 6107,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "pkg/log/log.go",
    "chars": 1261,
    "preview": "// Copyright 2016 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "scripts/bump-release",
    "chars": 1256,
    "preview": "#!/bin/bash -e\n#\n# Attempt to bump the docker2aci release to the specified version by replacing\n# all occurrences of the"
  },
  {
    "path": "scripts/glide-update",
    "chars": 404,
    "preview": "#!/usr/bin/env bash\nset -e\n\nif ! [[ \"$0\" =~ \"scripts/glide-update\"  ]]; then\n  echo \"must be run from repository root\"\n "
  },
  {
    "path": "tests/README.md",
    "chars": 698,
    "preview": "# docker2aci tests\n\n## Semaphore\n\nThe tests run on the [Semaphore](https://semaphoreci.com/) CI system.\n\nThe tests are e"
  },
  {
    "path": "tests/fixture-test-depsloop/check.sh",
    "chars": 264,
    "preview": "#!/bin/sh\n\nDOCKER2ACI=../bin/docker2aci\nTESTDIR=$1\nTESTNAME=$2\n\ntimeout 10s ${DOCKER2ACI} \"${TESTDIR}/${TESTNAME}/${TEST"
  },
  {
    "path": "tests/fixture-test-invalidlayerid/check.sh",
    "chars": 257,
    "preview": "#!/bin/sh\n\nDOCKER2ACI=../bin/docker2aci\nTESTDIR=$1\nTESTNAME=$2\n\nsudo ${DOCKER2ACI} \"${TESTDIR}/${TESTNAME}/${TESTNAME}.d"
  },
  {
    "path": "tests/rkt-v1.1.0.md5sum",
    "chars": 59,
    "preview": "MD5 (rkt-v1.1.0.tar.gz) = d3d9d62429e53d8f631dbec93e4e719f\n"
  },
  {
    "path": "tests/test-basic/Dockerfile",
    "chars": 134,
    "preview": "FROM busybox\nCOPY check.sh /\nRUN echo file1 > file1 ; ln file1 file2\nRUN echo file3 > file3\nRUN echo file4 > file4\nCMD /"
  },
  {
    "path": "tests/test-basic/check.sh",
    "chars": 391,
    "preview": "#!/bin/sh\nset -e\nset -x\n\ngrep -q file1 file1\ngrep -q file1 file2\ngrep -q file3 file3\ngrep -q file4 file4\nif [ \"$CHECK\" !"
  },
  {
    "path": "tests/test-pwl/Dockerfile",
    "chars": 84,
    "preview": "FROM gcr.io/google_containers/nginx:1.7.9\nCOPY check.sh /\nENTRYPOINT /check.sh 2>&1\n"
  },
  {
    "path": "tests/test-pwl/check.sh",
    "chars": 55,
    "preview": "#!/bin/sh\nset -e\nset -x\n\nls -l /var/run\necho \"SUCCESS\"\n"
  },
  {
    "path": "tests/test-whiteouts/Dockerfile",
    "chars": 1163,
    "preview": "FROM busybox\nCOPY check.sh /\n\nRUN echo yes > layer0-file1 ; ln layer0-file1 layer0-file2 ; ln layer0-file1 layer0-file3\n"
  },
  {
    "path": "tests/test-whiteouts/check.sh",
    "chars": 1256,
    "preview": "#!/bin/sh\nset -e\nset -x\n\ngrep -q yes layer0-file1\ngrep -q yes layer0-file2\ngrep -q yes layer0-file3\n\ntest ! -e layer1-fi"
  },
  {
    "path": "tests/test.sh",
    "chars": 3138,
    "preview": "#!/bin/bash\n\nset -e\n\n# Gets the parent of the directory that this script is stored in.\n# https://stackoverflow.com/quest"
  },
  {
    "path": "vendor/github.com/appc/spec/LICENSE",
    "chars": 11325,
    "preview": "Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licens"
  },
  {
    "path": "vendor/github.com/appc/spec/aci/build.go",
    "chars": 2954,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/aci/doc.go",
    "chars": 687,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/aci/file.go",
    "chars": 5597,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/aci/layout.go",
    "chars": 4527,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/aci/writer.go",
    "chars": 2341,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/pkg/acirenderer/acirenderer.go",
    "chars": 7638,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/pkg/acirenderer/resolve.go",
    "chars": 2553,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/pkg/device/device_linux.go",
    "chars": 1073,
    "preview": "// Copyright 2016 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/pkg/device/device_posix.go",
    "chars": 1236,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/pkg/tarheader/doc.go",
    "chars": 731,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/pkg/tarheader/pop_darwin.go",
    "chars": 998,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/pkg/tarheader/pop_linux.go",
    "chars": 993,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/pkg/tarheader/pop_posix.go",
    "chars": 1394,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/pkg/tarheader/tarheader.go",
    "chars": 869,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/schema/common/common.go",
    "chars": 1334,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/schema/doc.go",
    "chars": 1129,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/schema/image.go",
    "chars": 3128,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/schema/kind.go",
    "chars": 1037,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/schema/pod.go",
    "chars": 4987,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/schema/types/acidentifier.go",
    "chars": 4633,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/schema/types/ackind.go",
    "chars": 1574,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/schema/types/acname.go",
    "chars": 4211,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/schema/types/annotations.go",
    "chars": 2405,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/schema/types/app.go",
    "chars": 2677,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/schema/types/date.go",
    "chars": 1673,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/schema/types/dependencies.go",
    "chars": 1462,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/schema/types/doc.go",
    "chars": 785,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/schema/types/environment.go",
    "chars": 2557,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/schema/types/errors.go",
    "chars": 1406,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/schema/types/event_handler.go",
    "chars": 1432,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/schema/types/exec.go",
    "chars": 1088,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/schema/types/hash.go",
    "chars": 2431,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/schema/types/isolator.go",
    "chars": 5689,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/schema/types/isolator_linux_specific.go",
    "chars": 12403,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/schema/types/isolator_resources.go",
    "chars": 5679,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/schema/types/isolator_unix.go",
    "chars": 1859,
    "preview": "// Copyright 2016 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/schema/types/labels.go",
    "chars": 6354,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/schema/types/mountpoint.go",
    "chars": 2163,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/schema/types/port.go",
    "chars": 3579,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/schema/types/resource/amount.go",
    "chars": 8849,
    "preview": "/*\nCopyright 2014 The Kubernetes Authors All rights reserved.\n\nLicensed under the Apache License, Version 2.0 (the \"Lice"
  },
  {
    "path": "vendor/github.com/appc/spec/schema/types/resource/math.go",
    "chars": 7866,
    "preview": "/*\nCopyright 2014 The Kubernetes Authors All rights reserved.\n\nLicensed under the Apache License, Version 2.0 (the \"Lice"
  },
  {
    "path": "vendor/github.com/appc/spec/schema/types/resource/quantity.go",
    "chars": 22597,
    "preview": "/*\nCopyright 2014 The Kubernetes Authors All rights reserved.\n\nLicensed under the Apache License, Version 2.0 (the \"Lice"
  },
  {
    "path": "vendor/github.com/appc/spec/schema/types/resource/scale_int.go",
    "chars": 2543,
    "preview": "/*\nCopyright 2015 The Kubernetes Authors All rights reserved.\n\nLicensed under the Apache License, Version 2.0 (the \"Lice"
  },
  {
    "path": "vendor/github.com/appc/spec/schema/types/resource/suffix.go",
    "chars": 5311,
    "preview": "/*\nCopyright 2014 The Kubernetes Authors All rights reserved.\n\nLicensed under the Apache License, Version 2.0 (the \"Lice"
  },
  {
    "path": "vendor/github.com/appc/spec/schema/types/semver.go",
    "chars": 2297,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/schema/types/url.go",
    "chars": 1619,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/schema/types/user_annotations.go",
    "chars": 741,
    "preview": "// Copyright 2016 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/schema/types/user_labels.go",
    "chars": 731,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/schema/types/uuid.go",
    "chars": 2166,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/schema/types/volume.go",
    "chars": 5678,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/appc/spec/schema/version.go",
    "chars": 1139,
    "preview": "// Copyright 2015 The appc Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/coreos/go-semver/LICENSE",
    "chars": 11358,
    "preview": "\n                                 Apache License\n                           Version 2.0, January 2004\n                  "
  },
  {
    "path": "vendor/github.com/coreos/go-semver/example.go",
    "chars": 329,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"github.com/coreos/go-semver/semver\"\n\t\"os\"\n)\n\nfunc main() {\n\tvA, err := semver.NewVersion"
  },
  {
    "path": "vendor/github.com/coreos/go-semver/semver/semver.go",
    "chars": 5256,
    "preview": "// Copyright 2013-2015 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not"
  },
  {
    "path": "vendor/github.com/coreos/go-semver/semver/sort.go",
    "chars": 947,
    "preview": "// Copyright 2013-2015 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not"
  },
  {
    "path": "vendor/github.com/coreos/ioprogress/LICENSE",
    "chars": 1085,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2014 Mitchell Hashimoto\n\nPermission is hereby granted, free of charge, to any perso"
  },
  {
    "path": "vendor/github.com/coreos/ioprogress/draw.go",
    "chars": 3671,
    "preview": "package ioprogress\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n\n\t\"golang.org/x/crypto/ssh/terminal\"\n)\n\n// DrawFunc is the ca"
  },
  {
    "path": "vendor/github.com/coreos/ioprogress/reader.go",
    "chars": 2386,
    "preview": "package ioprogress\n\nimport (\n\t\"io\"\n\t\"time\"\n)\n\n// Reader is an implementation of io.Reader that draws the progress of\n// "
  },
  {
    "path": "vendor/github.com/coreos/pkg/LICENSE",
    "chars": 11325,
    "preview": "Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licens"
  },
  {
    "path": "vendor/github.com/coreos/pkg/NOTICE",
    "chars": 126,
    "preview": "CoreOS Project\nCopyright 2014 CoreOS, Inc\n\nThis product includes software developed at CoreOS, Inc.\n(http://www.coreos.c"
  },
  {
    "path": "vendor/github.com/coreos/pkg/progressutil/iocopy.go",
    "chars": 4735,
    "preview": "// Copyright 2016 CoreOS Inc\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "vendor/github.com/coreos/pkg/progressutil/progressbar.go",
    "chars": 7242,
    "preview": "// Copyright 2016 CoreOS Inc\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "vendor/github.com/docker/distribution/LICENSE",
    "chars": 11325,
    "preview": "Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licens"
  },
  {
    "path": "vendor/github.com/docker/distribution/blobs.go",
    "chars": 9602,
    "preview": "package distribution\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/docker/distribution/r"
  },
  {
    "path": "vendor/github.com/docker/distribution/digestset/set.go",
    "chars": 6745,
    "preview": "package digestset\n\nimport (\n\t\"errors\"\n\t\"sort\"\n\t\"strings\"\n\t\"sync\"\n\n\tdigest \"github.com/opencontainers/go-digest\"\n)\n\nvar ("
  },
  {
    "path": "vendor/github.com/docker/distribution/doc.go",
    "chars": 310,
    "preview": "// Package distribution will define the interfaces for the components of\n// docker distribution. The goal is to allow us"
  },
  {
    "path": "vendor/github.com/docker/distribution/errors.go",
    "chars": 3279,
    "preview": "package distribution\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/opencontainers/go-digest\"\n)\n\n// ErrAccessDenied"
  },
  {
    "path": "vendor/github.com/docker/distribution/manifests.go",
    "chars": 4283,
    "preview": "package distribution\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"mime\"\n\n\t\"github.com/opencontainers/go-digest\"\n)\n\n// Manifest represen"
  },
  {
    "path": "vendor/github.com/docker/distribution/reference/helpers.go",
    "chars": 1148,
    "preview": "package reference\n\nimport \"path\"\n\n// IsNameOnly returns true if reference only contains a repo name.\nfunc IsNameOnly(ref"
  },
  {
    "path": "vendor/github.com/docker/distribution/reference/normalize.go",
    "chars": 4951,
    "preview": "package reference\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/docker/distribution/digestset\"\n\t\"github.com/openco"
  },
  {
    "path": "vendor/github.com/docker/distribution/reference/reference.go",
    "chars": 11170,
    "preview": "// Package reference provides a general type to represent any way of referencing images within the registry.\n// Its main"
  },
  {
    "path": "vendor/github.com/docker/distribution/reference/regexp.go",
    "chars": 5266,
    "preview": "package reference\n\nimport \"regexp\"\n\nvar (\n\t// alphaNumericRegexp defines the alpha numeric atom, typically a\n\t// compone"
  },
  {
    "path": "vendor/github.com/docker/distribution/registry.go",
    "chars": 3328,
    "preview": "package distribution\n\nimport (\n\t\"context\"\n\n\t\"github.com/docker/distribution/reference\"\n)\n\n// Scope defines the set of it"
  },
  {
    "path": "vendor/github.com/docker/distribution/tags.go",
    "chars": 959,
    "preview": "package distribution\n\nimport (\n\t\"context\"\n)\n\n// TagService provides access to information about tagged objects.\ntype Tag"
  },
  {
    "path": "vendor/github.com/klauspost/compress/LICENSE",
    "chars": 1479,
    "preview": "Copyright (c) 2012 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or with"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/copy.go",
    "chars": 905,
    "preview": "// Copyright 2012 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/crc32_amd64.go",
    "chars": 1031,
    "preview": "//+build !noasm\n//+build !appengine\n\n// Copyright 2015, Klaus Post, see LICENSE for details.\n\npackage flate\n\nimport (\n\t\""
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/crc32_amd64.s",
    "chars": 3599,
    "preview": "//+build !noasm\n//+build !appengine\n\n// Copyright 2015, Klaus Post, see LICENSE for details.\n\n// func crc32sse(a []byte)"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/crc32_noasm.go",
    "chars": 667,
    "preview": "//+build !amd64 noasm appengine\n\n// Copyright 2015, Klaus Post, see LICENSE for details.\n\npackage flate\n\nfunc init() {\n\t"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/deflate.go",
    "chars": 38120,
    "preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Copyright (c) 2015 Klaus Post\n// Use of this source code is go"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/dict_decoder.go",
    "chars": 6177,
    "preview": "// Copyright 2016 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/gen.go",
    "chars": 7022,
    "preview": "// Copyright 2012 The Go Authors.  All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/huffman_bit_writer.go",
    "chars": 18858,
    "preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/huffman_code.go",
    "chars": 9922,
    "preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/inflate.go",
    "chars": 20684,
    "preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/reverse_bits.go",
    "chars": 1995,
    "preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/snappy.go",
    "chars": 27791,
    "preview": "// Copyright 2011 The Snappy-Go Authors. All rights reserved.\n// Modified for deflate by Klaus Post (c) 2015.\n// Use of "
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/token.go",
    "chars": 4204,
    "preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/klauspost/cpuid/LICENSE",
    "chars": 1078,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2015 Klaus Post\n\nPermission is hereby granted, free of charge, to any person obtain"
  },
  {
    "path": "vendor/github.com/klauspost/cpuid/cpuid.go",
    "chars": 27614,
    "preview": "// Copyright (c) 2015 Klaus Post, released under MIT License. See LICENSE file.\n\n// Package cpuid provides information a"
  },
  {
    "path": "vendor/github.com/klauspost/cpuid/cpuid_386.s",
    "chars": 939,
    "preview": "// Copyright (c) 2015 Klaus Post, released under MIT License. See LICENSE file.\n\n// +build 386,!gccgo\n\n// func asmCpuid("
  },
  {
    "path": "vendor/github.com/klauspost/cpuid/cpuid_amd64.s",
    "chars": 945,
    "preview": "// Copyright (c) 2015 Klaus Post, released under MIT License. See LICENSE file.\n\n//+build amd64,!gccgo\n\n// func asmCpuid"
  },
  {
    "path": "vendor/github.com/klauspost/cpuid/detect_intel.go",
    "chars": 445,
    "preview": "// Copyright (c) 2015 Klaus Post, released under MIT License. See LICENSE file.\n\n// +build 386,!gccgo amd64,!gccgo\n\npack"
  },
  {
    "path": "vendor/github.com/klauspost/cpuid/detect_ref.go",
    "chars": 449,
    "preview": "// Copyright (c) 2015 Klaus Post, released under MIT License. See LICENSE file.\n\n// +build !amd64,!386 gccgo\n\npackage cp"
  },
  {
    "path": "vendor/github.com/klauspost/cpuid/generate.go",
    "chars": 51,
    "preview": "package cpuid\n\n//go:generate go run private-gen.go\n"
  },
  {
    "path": "vendor/github.com/klauspost/cpuid/private-gen.go",
    "chars": 12413,
    "preview": "// +build ignore\n\npackage main\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"go/ast\"\n\t\"go/parser\"\n\t\"go/printer\"\n\t\"go/token\"\n\t\"io\"\n\t\"io/iou"
  },
  {
    "path": "vendor/github.com/klauspost/crc32/LICENSE",
    "chars": 1509,
    "preview": "Copyright (c) 2012 The Go Authors. All rights reserved.\nCopyright (c) 2015 Klaus Post\n\nRedistribution and use in source "
  },
  {
    "path": "vendor/github.com/klauspost/crc32/crc32.go",
    "chars": 5169,
    "preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/klauspost/crc32/crc32_amd64.go",
    "chars": 1594,
    "preview": "// Copyright 2011 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/klauspost/crc32/crc32_amd64.s",
    "chars": 4566,
    "preview": "// Copyright 2011 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/klauspost/crc32/crc32_amd64p32.go",
    "chars": 991,
    "preview": "// Copyright 2011 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/klauspost/crc32/crc32_amd64p32.s",
    "chars": 1195,
    "preview": "// Copyright 2011 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/klauspost/crc32/crc32_generic.go",
    "chars": 845,
    "preview": "// Copyright 2011 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/klauspost/pgzip/LICENSE",
    "chars": 1078,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2014 Klaus Post\n\nPermission is hereby granted, free of charge, to any person obtain"
  },
  {
    "path": "vendor/github.com/klauspost/pgzip/gunzip.go",
    "chars": 13217,
    "preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/klauspost/pgzip/gzip.go",
    "chars": 12184,
    "preview": "// Copyright 2010 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/opencontainers/go-digest/LICENSE.code",
    "chars": 10760,
    "preview": "\n                                 Apache License\n                           Version 2.0, January 2004\n                  "
  },
  {
    "path": "vendor/github.com/opencontainers/go-digest/LICENSE.docs",
    "chars": 20004,
    "preview": "Attribution-ShareAlike 4.0 International\n\n=======================================================================\n\nCreat"
  },
  {
    "path": "vendor/github.com/opencontainers/go-digest/algorithm.go",
    "chars": 4094,
    "preview": "package digest\n\nimport (\n\t\"crypto\"\n\t\"fmt\"\n\t\"hash\"\n\t\"io\"\n)\n\n// Algorithm identifies and implementation of a digester by a"
  },
  {
    "path": "vendor/github.com/opencontainers/go-digest/digest.go",
    "chars": 4052,
    "preview": "package digest\n\nimport (\n\t\"fmt\"\n\t\"hash\"\n\t\"io\"\n\t\"regexp\"\n\t\"strings\"\n)\n\n// Digest allows simple protection of hex formatte"
  },
  {
    "path": "vendor/github.com/opencontainers/go-digest/digester.go",
    "chars": 586,
    "preview": "package digest\n\nimport \"hash\"\n\n// Digester calculates the digest of written data. Writes should go directly\n// to the re"
  },
  {
    "path": "vendor/github.com/opencontainers/go-digest/doc.go",
    "chars": 1632,
    "preview": "// Package digest provides a generalized type to opaquely represent message\n// digests and their operations within the r"
  },
  {
    "path": "vendor/github.com/opencontainers/go-digest/verifiers.go",
    "chars": 720,
    "preview": "package digest\n\nimport (\n\t\"hash\"\n\t\"io\"\n)\n\n// Verifier presents a general verification interface to be used with message\n"
  },
  {
    "path": "vendor/github.com/opencontainers/image-spec/LICENSE",
    "chars": 10767,
    "preview": "\n                                 Apache License\n                           Version 2.0, January 2004\n                  "
  },
  {
    "path": "vendor/github.com/opencontainers/image-spec/specs-go/v1/config.go",
    "chars": 3705,
    "preview": "// Copyright 2016 The Linux Foundation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
  },
  {
    "path": "vendor/github.com/opencontainers/image-spec/specs-go/v1/descriptor.go",
    "chars": 957,
    "preview": "// Copyright 2016 The Linux Foundation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
  },
  {
    "path": "vendor/github.com/opencontainers/image-spec/specs-go/v1/manifest.go",
    "chars": 1184,
    "preview": "// Copyright 2016 The Linux Foundation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
  },
  {
    "path": "vendor/github.com/opencontainers/image-spec/specs-go/v1/manifest_list.go",
    "chars": 2281,
    "preview": "// Copyright 2016 The Linux Foundation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
  },
  {
    "path": "vendor/github.com/opencontainers/image-spec/specs-go/v1/mediatype.go",
    "chars": 1613,
    "preview": "// Copyright 2016 The Linux Foundation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
  },
  {
    "path": "vendor/github.com/opencontainers/image-spec/specs-go/version.go",
    "chars": 1134,
    "preview": "// Copyright 2016 The Linux Foundation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
  },
  {
    "path": "vendor/github.com/opencontainers/image-spec/specs-go/versioned.go",
    "chars": 1034,
    "preview": "// Copyright 2016 The Linux Foundation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
  },
  {
    "path": "vendor/github.com/spf13/pflag/LICENSE",
    "chars": 1531,
    "preview": "Copyright (c) 2012 Alex Ogier. All rights reserved.\nCopyright (c) 2012 The Go Authors. All rights reserved.\n\nRedistribut"
  },
  {
    "path": "vendor/github.com/spf13/pflag/flag.go",
    "chars": 38324,
    "preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/go4.org/LICENSE",
    "chars": 11358,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "vendor/go4.org/errorutil/highlight.go",
    "chars": 1611,
    "preview": "/*\nCopyright 2011 Google Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file"
  },
  {
    "path": "vendor/golang.org/x/crypto/LICENSE",
    "chars": 1479,
    "preview": "Copyright (c) 2009 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or with"
  },
  {
    "path": "vendor/golang.org/x/crypto/PATENTS",
    "chars": 1303,
    "preview": "Additional IP Rights Grant (Patents)\n\n\"This implementation\" means the copyrightable works distributed by\nGoogle as part "
  },
  {
    "path": "vendor/golang.org/x/crypto/ssh/terminal/terminal.go",
    "chars": 20992,
    "preview": "// Copyright 2011 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/golang.org/x/crypto/ssh/terminal/util.go",
    "chars": 4025,
    "preview": "// Copyright 2011 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go",
    "chars": 332,
    "preview": "// Copyright 2013 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/golang.org/x/crypto/ssh/terminal/util_linux.go",
    "chars": 457,
    "preview": "// Copyright 2013 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/golang.org/x/crypto/ssh/terminal/util_windows.go",
    "chars": 4423,
    "preview": "// Copyright 2011 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/gopkg.in/inf.v0/LICENSE",
    "chars": 1522,
    "preview": "Copyright (c) 2012 Péter Surányi. Portions Copyright (c) 2009 The Go\nAuthors. All rights reserved.\n\nRedistribution and u"
  },
  {
    "path": "vendor/gopkg.in/inf.v0/dec.go",
    "chars": 16611,
    "preview": "// Package inf (type inf.Dec) implements \"infinite-precision\" decimal\n// arithmetic.\n// \"Infinite precision\" describes t"
  },
  {
    "path": "vendor/gopkg.in/inf.v0/rounder.go",
    "chars": 3872,
    "preview": "package inf\n\nimport (\n\t\"math/big\"\n)\n\n// Rounder represents a method for rounding the (possibly infinite decimal)\n// resu"
  }
]

// ... and 2 more files (download for full content)

About this extraction

This page contains the full source code of the appc/docker2aci GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 181 files (863.6 KB), approximately 246.8k tokens, and a symbol index with 1736 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!