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.
@@ -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()
@@ -0,0 +1,10 @@
1
+ class Error(Exception):
2
+ pass
3
+
4
+
5
+ class SquashError(Error):
6
+ code = 1
7
+
8
+
9
+ class SquashUnnecessaryError(SquashError):
10
+ code = 2