Giter VIP home page Giter VIP logo

lstags's Introduction

CircleCI Go Report Card Coverage Status

L/S tags

Utility and API to manipulate (analyze, synchronize and aggregate) images across different Docker registries.

Example invocation

$ lstags alpine~/^3\\./
<STATE>      <DIGEST>                                   <(local) ID>    <Created At>          <TAG>
ABSENT       sha256:9363d03ef12c8c25a2def8551e609f146   n/a             2017-09-13T16:32:00   alpine:3.1
CHANGED      sha256:9866438860a1b28cd9f0c944e42d3f6cd   39be345c901f    2017-09-13T16:32:05   alpine:3.2
ABSENT       sha256:ae4d16d132e3c93dd09aec45e4c13e9d7   n/a             2017-09-13T16:32:10   alpine:3.3
CHANGED      sha256:0d82f2f4b464452aac758c77debfff138   f64255f97787    2017-09-13T16:32:15   alpine:3.4
PRESENT      sha256:129a7f8c0fae8c3251a8df9370577d9d6   074d602a59d7    2017-09-13T16:32:20   alpine:3.5
PRESENT      sha256:f006ecbb824d87947d0b51ab8488634bf   76da55c8019d    2017-09-13T16:32:26   alpine:3.6

NB! You can specify many images to operate on, e.g: lstags nginx~/^1\\.13/ mesosphere/chronos alpine~/^3\\./

Why would someone use this?

You could use lstags, if you ...

  • ... aggregate images from different external registries into your own registry for speed and locality reasons.
  • ... compare images present locally with the registry ones (e.g.: know if image tagged "latest" was re-pushed).
  • ... continuously pull Docker images from some public or private registry to speed-up Docker run on your system.

How?

... pull Ubuntu 14.04 & 16.04, all the Alpine images and Debian "stretch" to have the latest software to play with:

lstags --pull ubuntu~/^1[46]\\.04$/ alpine debian~/stretch/

... pull and re-push CoreOS-related images from quay.io to your own registry (in case these hipsters will break everything):

lstags -P /quay -r registry.company.io quay.io/coreos/hyperkube quay.io/coreos/flannel

NB! In case you use private registry with authentication, make sure your Docker client knows how to authenticate against it! lstags will reuse credentials saved by Docker client in its config.json file, one usually found at ~/.docker/config.json

Possible image states

lstags distinguishes five states of Docker image:

  • ABSENT - present in registry, but absent locally
  • PRESENT - present in registry, present locally, with local and remote digests being equal
  • CHANGED - present in registry, present locally, but with different local and remote digests
  • LOCAL_ONLY - present locally, absent in registry
  • NOT_FOUND - absent in registry, absent locally, probably does not exist at all

Authentication

You can either:

  • rely on lstags discovering credentials "automagically" 🎩
  • load credentials from any Docker JSON config file specified

Assume tags

Sometimes registry may contain tags not exposed to any kind of search though still existing. lstags is unable to discover these tags, but if you need to pull or push them, you may "assume" they exist and make lstags blindly try to pull these tags from the registry. To inject assumed tags into the registry query you need to extend repository specification with a = followed by a comma-separated list of tags you want to assume.

e.g. we assume tags v1.6.1 and v1.7.0 exist like this: lstags quay.io/calico/cni=v1.6.1,v1.7.0

Repository specification

Full repository specification looks like this:

[REGISTRY[:PORT]/]REPOSITORY[~/FILTER_REGEXP/][=TAG1,TAG2,TAGn]

You may provide infinite number of repository specifications to lstags

Push prefix

When you [re]push images to your "push" registry, you can control the destination repository path prefix:

  • by default, repository path prefix will be auto-generated from the source registry hostname, e.g.:
    • alpine ▢️ /registry/hub/docker/com/
    • localhost:5000/nginx ▢️ /localhost/
    • registry.company.com/hype/kubernetes ▢️ /registry/company/com/
  • passing --push-prefix=/ will push images "as is", with no additional repository path prefix
  • passing --push-prefix=/my/prefix/ will push images appending /my/prefix/ to the repository path
  • specifying /my/prefix without trailing slash is OK, as long as path would still be formatted correctly by API ✨
  • passing --push-prefix="" would trigger "default" behavior with prefix being auto-generated

To fail or not to fail?

By default application exits after encountering any errors. To make it more tolerant to subsequent failures, you may use CLI option -N, --do-not-fail or set environment variable DO_NOT_FAIL=true before running application. HINT: Option -d, --daemon-mode always implies activation of --do-not-fail.

YAML

πŸ’‘ You can load repositories from the YAML file just like you do it from the command line arguments:

lstags -f file.yaml

A valid YAML file looks like this (mandatory lstags root key is here to be able to use "shared" YAMLs):

lstags:
  repositories:
    - busybox
    - nginx:stable
    - mesosphere/marathon-lb~/^v1/
    - quay.io/coreos/awscli=master,latest,edge
    - gcr.io/google-containers/hyperkube~/^v1\.(9|10)\./

NB! lstags can load repositories from YAML or from CLI args, but not from both at the same time!

Install: Binaries

https://github.com/ivanilves/lstags/releases

Install: Wrapper

git clone [email protected]:ivanilves/lstags.git
cd lstags
sudo make wrapper
lstags -h

A special wrapper script will be installed to manage lstags invocation and updates. 😎

Install: From source

git clone [email protected]:ivanilves/lstags.git
cd lstags
dep ensure
go build
./lstags -h

NB! I assume you have current versions of Go & dep installed and also have set up GOPATH correctly.

Using it with Docker

docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock ivanilves/lstags
Usage:
  lstags [OPTIONS] REPO1 REPO2 REPOn...

Application Options:
  -j, --docker-json=          JSON file with credentials (default:
                              ~/.docker/config.json) [$DOCKER_JSON]
  -p, --pull                  Pull Docker images matched by filter (will use
                              local Docker deamon) [$PULL]
  -P, --push                  Push Docker images matched by filter to some
                              registry (See 'push-registry') [$PUSH]
  -r, --push-registry=        [Re]Push pulled images to a specified remote
                              registry [$PUSH_REGISTRY]

--- OUTPUT WAS CUT HERE TO SAVE SPACE ---

Analyze an image

docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock ivanilves/lstags alpine~/^3\\./
ANALYZE alpine
FETCHED alpine
-
<STATE>   <DIGEST>                                  <(local) ID>    <Created At>            <TAG>
CHANGED   sha256:b40e202395eaec699f2d0c5e01e6d6cb8  76da55c8019d    2017-10-25T23:19:51Z    alpine:3.6
ABSENT    sha256:d95da16498d5d6fb4b907cbe013f95032  n/a             2017-10-25T23:20:18Z    alpine:3.1
ABSENT    sha256:cb275b62f789b211114f28b391fca3cc2  n/a             2017-10-25T23:20:32Z    alpine:3.2
ABSENT    sha256:27af7da847283a947c008592f2b2cd6d2  n/a             2017-10-25T23:20:45Z    alpine:3.3
CHANGED   sha256:246bbbaa81b28837b64cb9dfc574de958  1a19a71e5d38    2017-10-25T23:20:59Z    alpine:3.4
CHANGED   sha256:aa96c8dc3815c44d4aceaf1ee7903ce58  37c7be7a096b    2017-10-25T23:21:13Z    alpine:3.5
-

Development

You are very welcome to open pull requests to this repository! πŸ˜‰

⚠️ CI build will fail, if your commit messages are not semantic!

To maximize our collaboration efficiency we would humbly ask you to follow these recommendations:

  • Please add reasonable description (what?/why?/etc) to your pull request ❗
  • Your code should pass CI (CircleCI) and a [pretty liberal] code review πŸ”
  • If code adds or changes some logic, it should be covered by a unit test :neckbeard:
  • Please, put meaningful and semantic messages on your commits πŸ™

NB! Not a requirement, but a GIF included in PR description would make our world a happier place!

'NORELEASE' branches and commits

We have automatic release system. Every PR merge will create a new application release with a changelog generated from PR branch commits. For the most cases it is OK. However, if you work with things that do not need to be released (e.g. non user-facing changes), you have following options:

  • If you don't want to create release from your PR, make it from branch containing "NORELEASE" keyword in its name.
  • If you want to prevent single commit from appearing in a changelog, please start commit message with "NORELEASE".

⚠️ We don't build RPMs/DEBs/etc, as we see no need for it. We ship lstags as a single binary or as a Docker container.

API

You may use lstags either as a standalone CLI or as a Golang package inside your own application.

Set up and build PoC application with our v1 API:

make poc-app APP_PATH=../lstags-api
cd ../lstags-api
go build
# run "./lstags-api" binary to see PoC in action (examine main.go first to ensure no "rm -rf /" is there)
  • This installs all necessary dependencies and sets up PoC application at the path ../lstags-api/
  • We assume you already have recent Golang version installed on your system https://golang.org/dl/

GoDoc

NB! Far more complete API usage example could be found in main.go πŸ˜‰

lstags's People

Contributors

afrimberger avatar cablespaghetti avatar ivanilves avatar jacobstr avatar lukeb2e avatar sfudeus avatar solidnerd avatar vonrabbe avatar zealic avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lstags's Issues

Problem with private registry with port number

Hi, It's a very useful tool. However I found a mismatch problem when our private registry is hosted on a port e.g. 5000. An example as below.

$ docker images
my.registry.com:5000/my_image                 my_tag          abfaa2fbade0        10 months ago       97MB

$ lstags my.registry.com:5000/my_image
<STATE>      <DIGEST>                                      <(local) ID>    <Created At>              <TAG>
LOCAL-ONLY   sha256:85b750cd33aa29ffce453f63984f4f6c9      abfaa2fbade0    2016-11-30T03:37:55-08:00 my.registry.com:5000/my_image:5000/my_image
ABSENT       sha256:85b750cd33aa29ffce453f63984f4f6c9      n/a             2016-11-30T03:37:55-08:00 my.registry.com:5000/my_image:my_tag

It seems the colon before the port number caused the wrong parsing result somewhere.

Thanks!

Better world: First refactor of the lstags

We have reached the state when we need to:

  • stop adding new functionality for a while.
  • work more on automated testing, code quality and various fixes.
  • add performance, benefit more of concurrency Golang gives us [almost] for free.

TODO

  • Add black-box shell tests for "image pull" functionality.
  • Fix lame ("double"?) help messages.
  • Make registry and operations event more concurrent.
  • Fix authenticated pull.

GIF

Filter images by tag (regex)

Something like --filter /^v.*/

  • Maybe applicable multiple times. Connect with and or or (?)
  • Maybe allowing to apply specified filters on selected repos only.

Whitebox End-to-End job

Enforce our blackbox integration testing with a whitebox end2end job which will:

  • start local registry
  • pull image from public registry
  • push it to local registry
  • verify it was pulled/pushed correctly

We may also consider 2 tests one pull and one for pull/push.

Pull and push dry-run flag

A pull (-p) dry run would show which images would be pulled.
A push (-P) dry run would show which images would a) be pulled and b) when the -r (external repo flag is given which images would be pushed to it.

This would allow for users to see issues like missing tags in a "plan" phase before running the actual pull/pull and push.

If this is wanted, depending on my time in the next weeks, I would be up to create a PR with this logic implemented.

index out of range error

Just trying to get things up and running–

$ lstags --version
VERSION: v30-d15b77b
$ lstags alpine~/^3\\./
panic: runtime error: index out of range

goroutine 1 [running]:
github.com/ivanilves/lstags/docker/config.Load(0x1360289, 0x15, 0x0, 0x0, 0x0)
	/home/travis/gopath/src/github.com/ivanilves/lstags/docker/config/config.go:79 +0x4fe
main.main()
	/home/travis/gopath/src/github.com/ivanilves/lstags/main.go:98 +0x8d

Package tests

We have main.go tested but what about packages?

Could we also have some testing for packages?

yaml file support

we need to support configuration loading from yaml file as it is more scm/git friendly

Elaborare dependency vendoring

Doing it "hard way" like we do it now is stable, but stupid.

Repo became huge: 57mb currently 😱

If we fear remote repo deletion, we should fork all remote repos and point dependencies to our forks.

We need CI

Some simple Travis thing would be enough πŸ˜‰

We need tests

Currently we have no tests, which makes our code a ⏳ πŸ’£

`api` package (to be imported by others)

To become a better utility and also to become a package/library we need to separate core logic into a api package, so the main will become really bare and easy to understand. Also other people could include api as a Golang package [not just using CLI] with this.

Todo

  • Provide API PoC #112
  • Provide reliable integration tests for API #119
  • Refactor API to get rid of PoC state #117
  • Provide versioning of API (so developers may develop safely) #114
  • Provide basic API documentation
  • Build a PoC application using v1 lstags API
  • Reach out to the new potential stakeholders

CI: Integration testing

We need integration testing for lstags.

Cases like:

  • Working against public registry
  • Working against private registry
  • Using different types of authentication
  • ...

Unable to compare local and remote digests

Unable to compare local and remote digests, cause they are always different.

More research required on this topic, as long as w/o solving this issue, the whole lstags idea is useless.

Kubernetes: Helm chart

Maybe we need to provide Kubernetes chart, some cron job to sync local docker images with registry?

Faster CI

Now we have more tests and every CI run is around 5-7min.

We need to take it back to ~2-3min so development will be joyful again! πŸš€

Options include:

  • Parallelize regular & Docker build
  • Run less tests for the PR, more for master merges
  • Speed-up existing tests
  • Remove some existing tests

CI: Automatic releases

We need automatic releases with our CI.

This means on every merged PR, we will need to:

  • Bump release tag
  • Build binaries for Linux and MacOSX
  • Upload binaries to Dropbox or whatever

"norelease" branches

IMO we need some mechanism to show that the PR we merge should not create a release.

For example, a refactor PR, which should be tested as any other PR, but should not be released cause it provides no value for user.

List multiple images

We need to be able to list multiple images. Like:

lstags alpine nginx containers.company.io

Add Documentation

Add some basic README.md with utility description and a couple of examples

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.