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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
|
diff --git a/bdebstrap b/bdebstrap
index 3034c8f..bf32fb3 100755
--- a/bdebstrap
+++ b/bdebstrap
@@ -51,6 +51,7 @@ MMDEBSTRAP_OPTS = {
"customize-hooks": list,
"dpkgopts": list,
"essential-hooks": list,
+ "extract-hooks": list,
"format": str,
"hostname": str,
"install-recommends": bool,
@@ -74,7 +75,7 @@ class Mmdebstrap:
def construct_parameters(self, output_dir, simulate=False):
"""Construct the parameter for mmdebstrap from a given dictionary."""
- # pylint: disable=too-many-branches
+ # pylint: disable=too-many-branches,too-many-statements
cmd = ["mmdebstrap"]
log_level = self.logger.getEffectiveLevel()
if log_level >= logging.ERROR:
@@ -107,6 +108,8 @@ class Mmdebstrap:
cmd.append(f"--architectures={','.join(mmdebstrap['architectures'])}")
if "setup-hooks" in mmdebstrap:
cmd += [f"--setup-hook={hook}" for hook in mmdebstrap["setup-hooks"]]
+ if "extract-hooks" in mmdebstrap:
+ cmd += [f"--extract-hook={hook}" for hook in mmdebstrap["extract-hooks"]]
cmd.append(f'--essential-hook=mkdir -p "$1{OUTPUT_DIR}"')
if "essential-hooks" in mmdebstrap:
cmd += [f"--essential-hook={hook}" for hook in mmdebstrap["essential-hooks"]]
@@ -364,6 +367,15 @@ def parse_args(args): # pylint: disable=too-many-statements
"thus cannot be chroot-ed into."
),
)
+ parser.add_argument(
+ "--extract-hook",
+ metavar="COMMAND",
+ action="append",
+ help=(
+ "Execute arbitrary COMMAND after the Essential:yes packages have been extracted "
+ "but before installing them."
+ ),
+ )
parser.add_argument(
"--essential-hook",
metavar="COMMAND",
@@ -484,6 +496,7 @@ def parse_args(args): # pylint: disable=too-many-statements
args.dpkgopt = sanitize_list(args.dpkgopt)
args.keyring = sanitize_list(args.keyring)
args.setup_hook = sanitize_list(args.setup_hook)
+ args.extract_hook = sanitize_list(args.extract_hook)
args.essential_hook = sanitize_list(args.essential_hook)
args.customize_hook = sanitize_list(args.customize_hook)
args.cleanup_hook = sanitize_list(args.cleanup_hook)
@@ -589,6 +602,8 @@ class Config(dict):
self._append_mmdebstrap_option("setup-hooks", args.setup_hook)
if args.essential_hook:
self._append_mmdebstrap_option("essential-hooks", args.essential_hook)
+ if args.extract_hook:
+ self._append_mmdebstrap_option("extract-hooks", args.extract_hook)
if args.customize_hook:
self._append_mmdebstrap_option("customize-hooks", args.customize_hook)
if args.cleanup_hook:
diff --git a/bdebstrap.1.md b/bdebstrap.1.md
index 83a0eba..7611537 100644
--- a/bdebstrap.1.md
+++ b/bdebstrap.1.md
@@ -1,5 +1,5 @@
---
-date: 2022-11-06
+date: 2023-11-09
footer: bdebstrap
header: "bdebstrap's Manual"
layout: page
@@ -28,8 +28,9 @@ bdebstrap - YAML config based multi-mirror Debian chroot creation tool
[**\--hostname** *HOSTNAME*] [**\--install-recommends**]
[**\--packages**|**\--include** *PACKAGES*] [**\--components** *COMPONENTS*]
[**\--architectures** *ARCHITECTURES*]
-[**\--setup-hook** *COMMAND*] [**\--essential-hook** *COMMAND*]
-[**\--customize-hook** *COMMAND*] [**\--cleanup-hook** *COMMAND*]
+[**\--setup-hook** *COMMAND*] [**\--extract-hook** *COMMAND*]
+[**\--essential-hook** *COMMAND*] [**\--customize-hook** *COMMAND*]
+[**\--cleanup-hook** *COMMAND*]
[**\--suite** *SUITE*] [**\--target** *TARGET*] [**\--mirrors** *MIRRORS*]
[*SUITE* [*TARGET* [*MIRROR*...]]]
@@ -151,6 +152,11 @@ output directory as *config.yaml*.
executables and thus cannot be chroot-ed into. This option can be specified
multiple times.
+**\--extract-hook** *COMMAND*
+: Execute arbitrary *COMMAND* after the Essential:yes packages have been
+ installed but before installing them. This option can be specified multiple
+ times.
+
**\--essential-hook** *COMMAND*
: Execute arbitrary *COMMAND* after the Essential:yes packages have been
installed, but before installing the remaining packages. This option can be
@@ -261,6 +267,12 @@ be specified:
into. See **HOOKS** in mmdebstrap(1) for more information and examples.
Additional setup hooks can be specified with **\--setup-hook**.
+**extract-hooks**
+: list of extract hooks (string). Execute arbitrary commands after the
+ Essential:yes packages have been installed but before installing them. See
+ **HOOKS** in mmdebstrap(1) for more information and examples. Additional
+ extract hooks can be specified with **\--extract-hook**.
+
**essential-hooks**
: list of essential hooks (string). Execute arbitrary commands after the
Essential:yes packages have been installed, but before installing the
diff --git a/tests/test_config.py b/tests/test_config.py
index d3135ff..01dba6b 100644
--- a/tests/test_config.py
+++ b/tests/test_config.py
@@ -57,6 +57,7 @@ class TestArguments(unittest.TestCase):
"--customize-hook=",
"--dpkgopt=",
"--essential-hook=",
+ "--extract-hook=",
"--keyring=",
"--mirrors=",
"--packages=",
@@ -75,6 +76,7 @@ class TestArguments(unittest.TestCase):
"customize_hook",
"dpkgopt",
"essential_hook",
+ "extract_hook",
"keyring",
"mirrors",
"packages",
@@ -90,6 +92,7 @@ class TestArguments(unittest.TestCase):
"customize_hook": [],
"dpkgopt": [],
"essential_hook": [],
+ "extract_hook": [],
"keyring": [],
"mirrors": [],
"packages": [],
@@ -112,6 +115,7 @@ class TestArguments(unittest.TestCase):
"dpkgopt": None,
"env": {},
"essential_hook": None,
+ "extract_hook": None,
"force": False,
"format": None,
"hostname": None,
diff --git a/tests/test_mmdebstrap.py b/tests/test_mmdebstrap.py
index e2bad1f..11b4952 100644
--- a/tests/test_mmdebstrap.py
+++ b/tests/test_mmdebstrap.py
@@ -96,6 +96,7 @@ class TestMmdebstrap(unittest.TestCase):
'chroot "$0" update-alternatives --set editor /usr/bin/vim.basic'
],
"essential-hooks": ["copy-in /etc/bash.bashrc /etc"],
+ "extract-hooks": ['find "$1" -xtype l'],
"hostname": "example",
"setup-hooks": [],
"suite": "buster",
@@ -107,6 +108,7 @@ class TestMmdebstrap(unittest.TestCase):
mmdebstrap.construct_parameters("/output"),
[
"mmdebstrap",
+ '--extract-hook=find "$1" -xtype l',
'--essential-hook=mkdir -p "$1/tmp/bdebstrap-output"',
"--essential-hook=copy-in /etc/bash.bashrc /etc",
'--customize-hook=chroot "$0" update-alternatives --set editor /usr/bin/vim.basic',
|