-
Notifications
You must be signed in to change notification settings - Fork 57
Expand file tree
/
Copy pathdocker-rebase
More file actions
executable file
·87 lines (79 loc) · 3.18 KB
/
docker-rebase
File metadata and controls
executable file
·87 lines (79 loc) · 3.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#!/bin/bash
# Script to convert a docker container to an image without history
# Copyright (C) 2014 docbill@gmail.com
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# This is an alternative to docker commit that will create a new image
# without history. Rebuilding the Dockerfile from an existing container is
# tricky. Currently the CMD is not parsed correctly, but it is probably close
# enough to work with most containers. There are probably other errors as
# as well, as docker history is an in-precise way to learn the original
# docker commands.
if [ -z "$1" -o -z "$2" ]
then
echo "$0 CONTAINER REPOSITORY[:TAG]" 1>&2
echo " "
echo "$0 is an alternative to docker commit to create new image without"
echo "all the revision history."
exit 1
fi
# This is a sad story. Since a container name and an image name can be the
# same we have to use docker ps to find the container id. That is not as easy
# as it seems if you want to be "fool proof".
re=$((docker ps -a -q --no-trunc --before="$1" ;docker ps -a -q --no-trunc --since="$1")|sort -u|tr '\n' '|')
containerId=$(docker ps --no-trunc -a -q | egrep -v "^($re)\$")
imageId=$(docker inspect --format '{{.Image}}' "$containerId")
if [ -n "$imageId" ]
then
echo "Exporting and importing the container to a new image"
from=$(docker export "$containerId" | docker import -)
echo " ---> $from"
if [ -z "$from" ]
then
echo "Failed to export and import $containerId" 1>&2
exit 1
fi
# Inspect the existing image to create a Dockerfile
(
echo "From $from"
(
docker history --no-trunc "$imageId" | \
sed -n -e 's,.*/bin/sh -c #(nop) \(MAINTAINER .*[^ ]\) *0 B,\1,p' | \
head -1
)
(
format='{{range $e := .Config.Env}}
ENV {{$e}}
{{end}}{{range $e,$v := .Config.ExposedPorts}}
EXPOSE {{$e}}
{{end}}{{range $e,$v := .Config.Volumes}}
VOLUME {{$e}}
{{end}}{{with .Config.User}}USER {{.}}{{end}}
{{with .Config.WorkingDir}}WORKDIR {{.}}{{end}}
{{with .Config.Entrypoint}}ENTRYPOINT {{json .}}{{end}}
{{with .Config.Cmd}}CMD {{json .}}{{end}}
{{with .Config.OnBuild}}ONBUILD {{json .}}{{end}}'
docker inspect --format="$format" "$imageId" | \
sed -e 's,^\(ENV [^=]*\)=,\1 ,' \
-e 's,^\(EXPOSE [0-9]*\)/tcp,\1,' | \
awk '{if (tolower($1) ~/env/) {v=$3;for(i=4;i<=NF;i++){v=v"\\ "$i};E[$2]=v} else print} END {r="ENV ";for (i in E) r=r" "i"="E[i];print r}'
)
) | docker build --force-rm -t "$2" -
status=$?
# We only successfully remove the image if the build failed.
docker rmi "$from" 2>>/dev/null
exit $status
else
echo "Failed to to find image id" 1>&2
exit 1
fi