Skip to content

Commit 5eceb91

Browse files
committed
Add typer cli interface
In addition to docopt also support the typer commandline interface. This is relevant for kiwi versions that has moved to typer. OSInside/kiwi#2751
1 parent c1e8bc3 commit 5eceb91

File tree

4 files changed

+281
-1
lines changed

4 files changed

+281
-1
lines changed

kiwi_boxed_plugin/cli.py

Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
# Copyright (c) 2024 SUSE LLC. All rights reserved.
2+
#
3+
# This file is part of kiwi-boxed-build.
4+
#
5+
# kiwi-boxed-build is free software: you can redistribute it and/or modify
6+
# it under the terms of the GNU General Public License as published by
7+
# the Free Software Foundation, either version 3 of the License, or
8+
# (at your option) any later version.
9+
#
10+
# kiwi-boxed-build is distributed in the hope that it will be useful,
11+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
# GNU General Public License for more details.
14+
#
15+
# You should have received a copy of the GNU General Public License
16+
# along with kiwi-boxed-build. If not, see <http://www.gnu.org/licenses/>
17+
#
18+
import typer
19+
from pathlib import Path
20+
# Enable for testing
21+
# from unittest.mock import MagicMock
22+
from typing import (
23+
Annotated, Optional
24+
)
25+
26+
typers = {
27+
'boxbuild': typer.Typer(
28+
add_completion=False
29+
)
30+
}
31+
32+
system = typers['boxbuild']
33+
34+
35+
@system.command(
36+
context_settings={
37+
'allow_extra_args': True,
38+
'ignore_unknown_options': True
39+
}
40+
)
41+
def kiwi(
42+
ctx: typer.Context
43+
):
44+
"""
45+
List of command parameters as supported by the kiwi-ng
46+
build command. The information given here is passed
47+
along to the kiwi-ng system build command running in
48+
the virtual machine or container.
49+
"""
50+
Cli = ctx.obj
51+
# Enable for testing
52+
# if not Cli:
53+
# Cli = MagicMock(subcommand_args={'boxbuild':{}})
54+
option = None
55+
for kiwi_arg in ctx.args:
56+
if kiwi_arg.startswith('-'):
57+
Cli.subcommand_args['boxbuild'][kiwi_arg] = True
58+
elif option:
59+
Cli.subcommand_args['boxbuild'][option] = kiwi_arg
60+
option = kiwi_arg
61+
Cli.global_args['command'] = 'boxbuild'
62+
Cli.global_args['system'] = True
63+
Cli.cli_ok = True
64+
65+
66+
@system.callback(
67+
help='build a system image in a self contained VM or container',
68+
subcommand_metavar='kiwi [OPTIONS]'
69+
)
70+
def boxbuild(
71+
ctx: typer.Context,
72+
box: Annotated[
73+
Optional[str], typer.Option(
74+
help='<name> Name of the box to use for the build process.'
75+
)
76+
] = None,
77+
list_boxes: Annotated[
78+
Optional[bool], typer.Option(
79+
'--list-boxes',
80+
help='show available build boxes.'
81+
)
82+
] = False,
83+
box_memory: Annotated[
84+
Optional[str], typer.Option(
85+
help='<vmgb> Number of GBs to reserve as main memory '
86+
'for the virtual machine. By default 8GB will be used.'
87+
)
88+
] = None,
89+
box_console: Annotated[
90+
Optional[str], typer.Option(
91+
help='<ttyname> Name of console in the kernel settings '
92+
'for the virtual machine. By default set to hvc0.'
93+
)
94+
] = None,
95+
box_smp_cpus: Annotated[
96+
Optional[int], typer.Option(
97+
help='<number> Number of CPUs to use in the SMP setup. '
98+
'By default 4 CPUs will be used.'
99+
)
100+
] = 4,
101+
box_debug: Annotated[
102+
Optional[bool], typer.Option(
103+
'--box-debug',
104+
help='In debug mode the started virtual machine will be kept open.'
105+
)
106+
] = False,
107+
container: Annotated[
108+
Optional[bool], typer.Option(
109+
'--container',
110+
help='Build in container instead of a VM. Options related to '
111+
'building in a VM will have no effect.'
112+
)
113+
] = False,
114+
kiwi_version: Annotated[
115+
Optional[str], typer.Option(
116+
help='<version> Specify a KIWI version to use for '
117+
'the build. The referenced KIWI will be fetched from '
118+
'pip and replaces the box installed KIWI version. '
119+
'Note: If --no-snapshot is used in combination '
120+
'with this option, the change of the KIWI version will '
121+
'be permanently stored in the used box.'
122+
)
123+
] = None,
124+
shared_path: Annotated[
125+
Optional[Path], typer.Option(
126+
help='<path> Optional host path to share with the box. '
127+
'The same path as it is present on the host will also '
128+
'be available inside of the box during build time.'
129+
)
130+
] = None,
131+
no_update_check: Annotated[
132+
Optional[bool], typer.Option(
133+
'--no-update-check',
134+
help='Skip check for available box update. The option '
135+
'has no effect if the selected box does not yet exist '
136+
'on the host.'
137+
)
138+
] = False,
139+
no_snapshot: Annotated[
140+
Optional[bool], typer.Option(
141+
'--no-snapshot',
142+
help='Run box with snapshot mode switched off. This '
143+
'causes the box disk file to be modified by the build '
144+
'process and allows to keep a persistent package cache '
145+
'as part of the box. The option can be used to increase '
146+
'the build performance due to data stored in the box '
147+
'which does not have to be reloaded from the network. '
148+
'On the contrary this option invalidates the immutable '
149+
'box attribute and should be used with care. On update '
150+
'of the box all data stored will be wiped. To prevent '
151+
'this combine the option with the --no-update-check option.'
152+
)
153+
] = False,
154+
no_accel: Annotated[
155+
Optional[bool], typer.Option(
156+
'--no-accel',
157+
help='Run box without hardware acceleration. By default '
158+
'KVM acceleration is activated'
159+
)
160+
] = False,
161+
qemu_9p_sharing: Annotated[
162+
Optional[bool], typer.Option(
163+
'--9p-sharing',
164+
help='Select 9p backend to use for sharing data '
165+
'between the host and the box.'
166+
)
167+
] = False,
168+
virtiofs_sharing: Annotated[
169+
Optional[bool], typer.Option(
170+
'--virtiofs-sharing',
171+
help='Select virtiofsd backend to use for sharing data '
172+
'between the host and the box.'
173+
)
174+
] = False,
175+
sshfs_sharing: Annotated[
176+
Optional[bool], typer.Option(
177+
'--sshfs-sharing',
178+
help='Select sshfs backend to use for sharing data '
179+
'between the host and the box.'
180+
)
181+
] = False,
182+
ssh_key: Annotated[
183+
Optional[str], typer.Option(
184+
help='<name> Name of ssh key to authorize for '
185+
'connection. By default id_rsa is used.'
186+
)
187+
] = 'id_rsa',
188+
ssh_port: Annotated[
189+
Optional[int], typer.Option(
190+
help='<port> Port number to use to forward the '
191+
'guest SSH port to the host By default 10022 is used.'
192+
)
193+
] = 10022,
194+
x86_64: Annotated[
195+
Optional[bool], typer.Option(
196+
'--x86_64',
197+
help='Select box for the x86_64 architecture. If no '
198+
'architecture is selected the host architecture is '
199+
'used for selecting the box. The selected box '
200+
'architecture also specifies the target architecture '
201+
'for the image build with that box.'
202+
)
203+
] = False,
204+
aarch64: Annotated[
205+
Optional[bool], typer.Option(
206+
'--aarch64',
207+
help='Select box for the aarch64 architecture. If no '
208+
'architecture is selected the host architecture is '
209+
'used for selecting the box. The selected box '
210+
'architecture also specifies the target architecture '
211+
'for the image build with that box.'
212+
)
213+
] = False,
214+
machine: Annotated[
215+
Optional[str], typer.Option(
216+
help='<qemu_machine> Machine name used '
217+
'by QEMU. By default no specific value is used here '
218+
'and qemu selects its default machine type. For cross '
219+
'arch builds or for system architectures for which '
220+
'QEMU defines no default like for Arm, it is required '
221+
'to specify a machine name. If you do not care about '
222+
'reproducing the idiosyncrasies of a particular bit '
223+
'of hardware, the best option is to use the virt '
224+
'machine type.'
225+
)
226+
] = None,
227+
cpu: Annotated[
228+
Optional[str], typer.Option(
229+
help='<qemu_cpu> CPU type used by QEMU. By default '
230+
'the host CPU type is used which is only a good '
231+
'selection if the host and the selected box are from '
232+
'the same architecture. On cross arch builds it is '
233+
'required to specify the CPU emulation the box should use'
234+
)
235+
] = None
236+
):
237+
Cli = ctx.obj
238+
# Enable for testing
239+
# if not Cli:
240+
# Cli = MagicMock(subcommand_args={'boxbuild':{}})
241+
Cli.subcommand_args['boxbuild'] = {
242+
'--box': box,
243+
'--list-boxes': list_boxes,
244+
'--box-memory': box_memory,
245+
'--box-console': box_console,
246+
'--box-smp-cpus': box_smp_cpus,
247+
'--box-debug': box_debug,
248+
'--container': container,
249+
'--kiwi-version': kiwi_version,
250+
'--shared-path': shared_path,
251+
'--no-update-check': no_update_check,
252+
'--no-snapshot': no_snapshot,
253+
'--no-accel': no_accel,
254+
'--9p-sharing': qemu_9p_sharing,
255+
'--virtiofs-sharing': virtiofs_sharing,
256+
'--sshfs-sharing': sshfs_sharing,
257+
'--ssh-key': ssh_key,
258+
'--ssh-port': ssh_port,
259+
'--x86_64': x86_64,
260+
'--aarch64': aarch64,
261+
'--machine': machine,
262+
'--cpu': cpu,
263+
'help': False
264+
}
265+
# Enable for testing
266+
print(Cli.subcommand_args)
267+
268+
269+
# Enable for testing
270+
# if __name__ == "__main__":
271+
# system()

package/python-kiwi_boxed_plugin-spec-template

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,12 @@ Requires: kiwi >= 9.21.21
109109
Requires: python%{python3_pkgversion}-kiwi >= 9.21.21
110110
%endif
111111
Requires: python%{python3_pkgversion} >= 3.9
112-
Requires: python%{python3_pkgversion}-docopt
112+
%if ! (0%{?fedora} >= 41 || 0%{?rhel} >= 10)
113+
Requires: python%{python3_pkgversion}-docopt >= 0.6.2
114+
%else
115+
Requires: python%{python3_pkgversion}-docopt-ng
116+
%endif
117+
Recommends: python%{python3_pkgversion}-typer
113118
Requires: python%{python3_pkgversion}-requests
114119
Requires: python%{python3_pkgversion}-progressbar2
115120
%if 0%{?ubuntu} || 0%{?debian}

pyproject.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ system_boxbuild = "kiwi_boxed_plugin.tasks.system_boxbuild"
5959

6060
[tool.poetry.group.test]
6161
[tool.poetry.group.test.dependencies]
62+
# for local plugin cli testing
63+
typer = ">=0.15.2"
6264
# python unit testing framework
6365
pytest = ">=6.2.0"
6466
pytest-cov = "*"

test/unit/.coveragerc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
[run]
22
omit =
33
*/version.py
4+
*/cli.py
45

56
[report]
67
omit =
78
*/version.py
9+
*/cli.py

0 commit comments

Comments
 (0)