docker-squash 1.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- docker_squash/__init__.py +1 -0
- docker_squash/cli.py +163 -0
- docker_squash/errors.py +10 -0
- docker_squash/image.py +1130 -0
- docker_squash/lib/__init__.py +0 -0
- docker_squash/lib/common.py +81 -0
- docker_squash/squash.py +170 -0
- docker_squash/v1_image.py +87 -0
- docker_squash/v2_image.py +425 -0
- docker_squash/version.py +1 -0
- docker_squash-1.3.0.dist-info/METADATA +242 -0
- docker_squash-1.3.0.dist-info/RECORD +16 -0
- docker_squash-1.3.0.dist-info/WHEEL +5 -0
- docker_squash-1.3.0.dist-info/entry_points.txt +2 -0
- docker_squash-1.3.0.dist-info/licenses/LICENSE +21 -0
- docker_squash-1.3.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from docker_squash.version import __version__ # noqa: F401
|
docker_squash/cli.py
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
import logging
|
|
5
|
+
import sys
|
|
6
|
+
|
|
7
|
+
from docker_squash import squash
|
|
8
|
+
from docker_squash.errors import SquashError
|
|
9
|
+
from docker_squash.version import __version__
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# Source: http://stackoverflow.com/questions/1383254/logging-streamhandler-and-standard-streams
|
|
13
|
+
class SingleLevelFilter(logging.Filter):
|
|
14
|
+
def __init__(self, passlevel, reject):
|
|
15
|
+
self.passlevel = passlevel
|
|
16
|
+
self.reject = reject
|
|
17
|
+
|
|
18
|
+
def filter(self, record):
|
|
19
|
+
if self.reject:
|
|
20
|
+
return record.levelno != self.passlevel
|
|
21
|
+
else:
|
|
22
|
+
return record.levelno == self.passlevel
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class MyParser(argparse.ArgumentParser):
|
|
26
|
+
# noinspection PyMethodMayBeStatic
|
|
27
|
+
def str2bool(self, v: str) -> bool:
|
|
28
|
+
if isinstance(v, bool):
|
|
29
|
+
return v
|
|
30
|
+
if v.lower() in ("yes", "true", "t", "y", "1"):
|
|
31
|
+
return True
|
|
32
|
+
elif v.lower() in ("no", "false", "f", "n", "0"):
|
|
33
|
+
return False
|
|
34
|
+
else:
|
|
35
|
+
raise argparse.ArgumentTypeError("Boolean value expected.")
|
|
36
|
+
|
|
37
|
+
def error(self, message):
|
|
38
|
+
self.print_help()
|
|
39
|
+
sys.stderr.write("\nError: %s\n" % message)
|
|
40
|
+
sys.exit(2)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class CLI(object):
|
|
44
|
+
def __init__(self):
|
|
45
|
+
handler_out = logging.StreamHandler(sys.stdout)
|
|
46
|
+
handler_err = logging.StreamHandler(sys.stderr)
|
|
47
|
+
|
|
48
|
+
handler_out.addFilter(SingleLevelFilter(logging.INFO, False))
|
|
49
|
+
handler_err.addFilter(SingleLevelFilter(logging.INFO, True))
|
|
50
|
+
|
|
51
|
+
self.log = logging.getLogger()
|
|
52
|
+
formatter = logging.Formatter(
|
|
53
|
+
"%(asctime)s %(filename)s:%(lineno)-10s %(levelname)-5s %(message)s"
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
handler_out.setFormatter(formatter)
|
|
57
|
+
handler_err.setFormatter(formatter)
|
|
58
|
+
|
|
59
|
+
self.log.addHandler(handler_out)
|
|
60
|
+
self.log.addHandler(handler_err)
|
|
61
|
+
|
|
62
|
+
def run(self):
|
|
63
|
+
parser = MyParser(description="Docker layer squashing tool")
|
|
64
|
+
|
|
65
|
+
parser.add_argument(
|
|
66
|
+
"-v", "--verbose", action="store_true", help="Verbose output"
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
parser.add_argument(
|
|
70
|
+
"--version",
|
|
71
|
+
action="version",
|
|
72
|
+
help="Show version and exit",
|
|
73
|
+
version=__version__,
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
parser.add_argument("image", help="Image to be squashed")
|
|
77
|
+
parser.add_argument(
|
|
78
|
+
"-f",
|
|
79
|
+
"--from-layer",
|
|
80
|
+
help="Number of layers to squash or ID of the layer (or image ID or image name) to squash from. In case the provided value is an integer, specified number of layers will be squashed. Every layer in the image will be squashed if the parameter is not provided.",
|
|
81
|
+
)
|
|
82
|
+
parser.add_argument(
|
|
83
|
+
"-t",
|
|
84
|
+
"--tag",
|
|
85
|
+
help="Specify the tag to be used for the new image. If not specified no tag will be applied",
|
|
86
|
+
)
|
|
87
|
+
parser.add_argument(
|
|
88
|
+
"-m",
|
|
89
|
+
"--message",
|
|
90
|
+
default="",
|
|
91
|
+
help="Specify a commit message (comment) for the new image.",
|
|
92
|
+
)
|
|
93
|
+
parser.add_argument(
|
|
94
|
+
"-c",
|
|
95
|
+
"--cleanup",
|
|
96
|
+
action="store_true",
|
|
97
|
+
help="Remove source image from Docker after squashing",
|
|
98
|
+
)
|
|
99
|
+
parser.add_argument(
|
|
100
|
+
"--tmp-dir",
|
|
101
|
+
help="Temporary directory to be created and used. This will NOT be deleted afterwards for easier debugging.",
|
|
102
|
+
)
|
|
103
|
+
parser.add_argument(
|
|
104
|
+
"--output-path",
|
|
105
|
+
help="Path where the image may be stored after squashing.",
|
|
106
|
+
)
|
|
107
|
+
parser.add_argument(
|
|
108
|
+
"--load-image",
|
|
109
|
+
type=parser.str2bool,
|
|
110
|
+
const=True,
|
|
111
|
+
nargs="?",
|
|
112
|
+
default=True,
|
|
113
|
+
help="Whether to load the image into Docker daemon after squashing",
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
args = parser.parse_args()
|
|
117
|
+
|
|
118
|
+
if args.verbose:
|
|
119
|
+
self.log.setLevel(logging.DEBUG)
|
|
120
|
+
else:
|
|
121
|
+
self.log.setLevel(logging.INFO)
|
|
122
|
+
|
|
123
|
+
self.log.debug("Running version %s", __version__)
|
|
124
|
+
try:
|
|
125
|
+
squash.Squash(
|
|
126
|
+
log=self.log,
|
|
127
|
+
image=args.image,
|
|
128
|
+
from_layer=args.from_layer,
|
|
129
|
+
tag=args.tag,
|
|
130
|
+
comment=args.message,
|
|
131
|
+
output_path=args.output_path,
|
|
132
|
+
load_image=args.load_image,
|
|
133
|
+
tmp_dir=args.tmp_dir,
|
|
134
|
+
cleanup=args.cleanup,
|
|
135
|
+
).run()
|
|
136
|
+
except KeyboardInterrupt:
|
|
137
|
+
self.log.error("Program interrupted by user, exiting...")
|
|
138
|
+
sys.exit(1)
|
|
139
|
+
except Exception:
|
|
140
|
+
e = sys.exc_info()[1]
|
|
141
|
+
|
|
142
|
+
if args.verbose:
|
|
143
|
+
self.log.exception(e)
|
|
144
|
+
else:
|
|
145
|
+
self.log.error(str(e))
|
|
146
|
+
|
|
147
|
+
self.log.error(
|
|
148
|
+
"Execution failed, consult logs above. If you think this is our fault, please file an issue: https://github.com/goldmann/docker-squash/issues, thanks!"
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
if isinstance(e, SquashError):
|
|
152
|
+
sys.exit(e.code)
|
|
153
|
+
|
|
154
|
+
sys.exit(1)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def run():
|
|
158
|
+
cli = CLI()
|
|
159
|
+
cli.run()
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
if __name__ == "__main__":
|
|
163
|
+
run()
|