Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?

In a fresh checkout:

cat provision
# #!/bin/bash
#
# echo step 1 >> /report.log
# echo step 2 >> /report.log

docker build -t entrypoint-exp01 .
# ...
# Successfully built 99d3f9da9f83

docker run entrypoint-exp01
# -------[report log]-------
# step 1
# step 2

docker run -i -t entrypoint-exp01 bash
# root@a22bd6074c5c:/#

Mounting the context on /context/shadow does not affect anything:

docker run -v $(pwd)/:/context/shadow/ entrypoint-exp01
# -------[report log]-------
# step 1
# step 2

Now, apply append-only changes to the provisioner script:

cat provision
# #!/bin/bash
#
# echo step 1 >> /report.log
# echo step 2 >> /report.log
# echo step 3 >> /report.log

Mounting the context on /context/shadow will take care of the changes:

docker run -v $(pwd)/:/context/shadow/ entrypoint-exp01
# Applying provisioner updates ...
# Provisioner updates applied ...
# -------[report log]-------
# step 1
# step 2
# step 3

Interactive shells work fine too:

docker run -i -t -v $(pwd)/:/context/shadow/ entrypoint-exp01 bash
# Applying provisioner updates ...
# Provisioner updates applied ...
# root@ad99ad29a01e:/#

So state is properly updated without a rebuild.

Now, apply diverging changes:

cat provision
# #!/bin/bash
#
# echo step 0 >> /report.log
# echo step 1 >> /report.log
# echo step 2 >> /report.log
# echo step 3 >> /report.log

docker run -v $(pwd)/:/context/shadow/ entrypoint-exp01
# Build and shadow provisioner have diverged; you must rebuild the image!

OK, now we need to rebuild:

docker build -t entrypoint-exp01 .
# ...
# Successfully built 25177a791c6f

docker run entrypoint-exp01
# ------[report log]-------
# step 0
# step 1
# step 2
# step 3
FROM ubuntu:12.04
# ...
# some steps that change the state, for simplicity:
RUN echo '-------[report log]-------' > /report.log
CMD ["cat", "/report.log"]
# set up the shadow context
RUN mkdir -p /context/build
ADD . /context/build/
RUN cp -rf /context/build/. /context/shadow/
ENTRYPOINT ["/context/shadow/entrypoint"]
# make final changes to state:
RUN /context/build/provision
#!/usr/bin/env python
import sys,subprocess
build_path = '/context/build/provision'
shadow_path = '/context/shadow/provision'
with open(build_path, 'r') as f:
build = f.read()
with open(shadow_path, 'r') as f:
shadow = f.read()
if shadow[0:len(build)] == build:
# append-only change
diff = shadow[len(build):]
else:
print 'Build and shadow provisioners have diverged; you must rebuild the image!'
sys.exit(1)
if len(diff) > 0:
try:
sys.stderr.write('Applying provisioner updates ...\n')
subprocess.check_call(diff, shell=True)
sys.stderr.write('Provisioner updates applied ...\n')
except subprocess.CalledProcessError as e:
sys.exit(e.returncode)
if len(sys.argv) > 1:
try:
subprocess.check_call(' '.join(sys.argv[1:]), shell=True)
except subprocess.CalledProcessError as e:
sys.exit(e.returncode)
#!/bin/bash
echo step 1 >> /report.log
echo step 2 >> /report.log
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.