Coder Social home page Coder Social logo

envdiff's Introduction

envdiff

Generates smart environment diffs.

The envdiff tool compares two environments, and tries to be smart where it can. For example, it can detect appends or prepends to lists like PATH.

Given two environments A and B, envdiff computes C such that:

(export A; export C) == export B

Examples here.

Installing

You will need to have the go tool installed, then:

go get -u github.com/rhcarvalho/envdiff

Now envdiff should be in your PATH.

Using

envdiff takes two arguments that should contain a list of newline or null-byte separated environment variables.

Examples:

  1. Detecting new variables:
$ envdiff TERM=xterm $'TERM=xterm\nFOO=bar'
FOO=bar
  1. Detecting removed variables:
$ envdiff $'TERM=xterm\nFOO=bar' TERM=xterm
FOO=
  1. Detecting changing of a list:
$ envdiff PATH=/bin:/sbin PATH=/usr/bin/:/usr/sbin:/bin:/sbin
PATH=/usr/bin/:/usr/sbin:$PATH

How to reverse-engineer a Software Collection for Docker images

By detecting environment changes introduced by enabling certain Software Collections (SCL) and writing a Dockerfile ENV instruction that has the same effect, one can create Docker images that have the given collections enabled by default.

For example, if you install a Ruby collection in a CentOS image, you might as well want to have the ruby binary in your PATH. A user of your image need not to know about SCL or have to do any extra steps to be able to run a line like:

docker run --rm scl-enabled-ruby-image ruby -e 'puts "Hello World!"'

Great, how do I do that with envdiff? There's really only one required step!

  1. Point envdiff at your target image:
$ envdiff -o docker scl openshift/ruby-20-centos7
# -- generated by https://github.com/rhcarvalho/envdiff, do not edit manually --
# The ENV instruction below is equivalent to:
#   scl enable nodejs010 ror40 ruby200 v8314
ENV MANPATH=/opt/rh/v8314/root/usr/share/man:/opt/rh/ruby200/root/usr/share/man:/opt/rh/ror40/root/usr/share/man:/opt/rh/v8314/root/usr/share/man:/opt/rh/nodejs010/root/usr/share/man: \
    LIBRARY_PATH=/opt/rh/v8314/root/usr/lib64:/opt/rh/v8314/root/usr/lib64 \
    X_SCLS=nodejs010 ror40 v8314  \
    LD_LIBRARY_PATH=/opt/rh/v8314/root/usr/lib64:/opt/rh/ruby200/root/usr/lib64:/opt/rh/ror40/root/usr/lib64:/opt/rh/v8314/root/usr/lib64:/opt/rh/nodejs010/root/usr/lib64 \
    CPATH=/opt/rh/v8314/root/usr/include:/opt/rh/v8314/root/usr/include \
    PATH=/opt/rh/v8314/root/usr/bin:/opt/rh/ruby200/root/usr/bin:/opt/rh/ror40/root/usr/bin:/opt/rh/v8314/root/usr/bin:/opt/rh/nodejs010/root/usr/bin:/usr/local/bin:/usr/bin \
    PYTHONPATH=/opt/rh/v8314/root/usr/lib/python2.7/site-packages:/opt/rh/v8314/root/usr/lib/python2.7/site-packages:/opt/rh/nodejs010/root/usr/lib/python2.7/site-packages \
    GEM_PATH=/opt/rh/ror40/root/usr/share/gems:/opt/app-root/src/.gem/ruby:/opt/rh/ruby200/root/usr/share/gems:/opt/rh/ruby200/root/usr/local/share/gems \
    PKG_CONFIG_PATH=/opt/rh/v8314/root/usr/lib64/pkgconfig:/opt/rh/ruby200/root/usr/lib64/pkgconfig:/opt/rh/ror40/root/usr/lib64/pkgconfig:/opt/rh/v8314/root/usr/lib64/pkgconfig
# -- end of generated instruction --
  1. (Optional) You may want to redirect the output straight into a Dockerfile:
envdiff -o docker scl openshift/ruby-20-centos7 >> Dockerfile

If you want to print the environment in shell format, omit the -o docker flag:

$ envdiff scl openshift/python-34-centos7
# scl enable rh-python34
MANPATH=/opt/rh/rh-python34/root/usr/share/man:
X_SCLS=rh-python34
LD_LIBRARY_PATH=/opt/rh/rh-python34/root/usr/lib64
PATH=/opt/rh/rh-python34/root/usr/bin:/usr/local/bin:/usr/bin
XDG_DATA_DIRS=/opt/rh/rh-python34/root/usr/share
PKG_CONFIG_PATH=/opt/rh/rh-python34/root/usr/lib64/pkgconfig

How does the scl mode works?

What is envdiff doing to generate an environment that transforms an initial environment into one with collections enabled?
You can go read the code, it's all in the scl.go file, or follow along.

First, we need to discover what collections are installed. This can be accomplished with scl --list in a container.

Second, we need two environments: one without any collections enabled, and another one will all collections enabled.

To get a clean environment, we run bash -c env in a temporary container. We wrap the call to env in a Bash shell to be closer to what we get by enabling collections. To make sure that the environment is clean no matter what is in the image, we unset all environment variables set in the image when creating a container.

To get the environment with all collections enabled, it is scl enable collection1 collection2 ... env. In other words, we run env to dump the environment with all collections from the first step being enabled. Since scl has a shebang that points to /bin/bash, this time we don't wrap the env call like in the previous step.

The last step is to do what envdiff is made to do: compare two environments. Producing output as a Dockerfile ENV instruction makes it convenient to modify existing Dockerfiles to permanently enable collections.

envdiff's People

Contributors

rhcarvalho avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar

envdiff's Issues

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.