Skip to content

Commit a5be193

Browse files
authored
Merge pull request #271 from ThePorgs/dev
Release 5.1.0
2 parents b15d838 + 23a9510 commit a5be193

21 files changed

+682
-157
lines changed

exegol-images

Submodule exegol-images updated 41 files

exegol/config/ConstantConfig.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from pathlib import Path
22

3-
__version__ = "5.0.2"
3+
__version__ = "5.1.0"
44

55

66
class ConstantConfig:
@@ -11,7 +11,6 @@ class ConstantConfig:
1111
# Exegol documentation link
1212
landing: str = "https://exegol.com"
1313
documentation: str = "https://docs.exegol.com"
14-
discord: str = "https://discord.gg/cXThyp7D6P"
1514
# OS Dir full root path of exegol project
1615
src_root_path_obj: Path = Path(__file__).parent.parent.parent.resolve()
1716
# Path of the entrypoint.sh

exegol/config/UserConfig.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ def __init__(self) -> None:
3434
# Shell logging
3535
self.shell_logging_method: str = "asciinema"
3636
self.shell_logging_compress: bool = True
37+
self.always_enable_shell_logging: bool = False
3738
# Desktop
3839
self.desktop_default_enable: bool = False
3940
self.desktop_default_localhost: bool = True
@@ -92,6 +93,9 @@ def _build_file_content(self) -> str:
9293
9394
# Change the configuration of the shell logging functionality
9495
shell_logging:
96+
# Always enable shell logging
97+
always_enable: {self.always_enable_shell_logging}
98+
9599
#Choice of the method used to record the sessions (script or asciinema)
96100
logging_method: {self.shell_logging_method}
97101
@@ -178,6 +182,7 @@ def _process_data(self) -> None:
178182
shell_logging_data = config_data.get("shell_logging", {})
179183
self.shell_logging_method = self._load_config_str(shell_logging_data, 'logging_method', self.shell_logging_method, choices=self.shell_logging_method_options)
180184
self.shell_logging_compress = self._load_config_bool(shell_logging_data, 'enable_log_compression', self.shell_logging_compress)
185+
self.always_enable_shell_logging = self._load_config_bool(shell_logging_data, 'always_enable', self.always_enable_shell_logging)
181186

182187
# Desktop section
183188
desktop_data = config_data.get("desktop", {})
@@ -213,6 +218,7 @@ def get_configs(self) -> List[str]:
213218
f"Auto-remove images: {boolFormatter(self.auto_remove_images)}",
214219
f"Auto-update fs: {boolFormatter(self.auto_update_workspace_fs)}",
215220
f"Default start shell: [blue]{self.default_start_shell}[/blue]",
221+
f"Always enable Shell logging: [blue]{boolFormatter(self.always_enable_shell_logging)}[/blue]",
216222
f"Shell logging method: [blue]{self.shell_logging_method}[/blue]",
217223
f"Shell logging compression: {boolFormatter(self.shell_logging_compress)}",
218224
f"Desktop enabled by default: {boolFormatter(self.desktop_default_enable)}",

exegol/console/ExegolProgress.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ async def __aenter__(self) -> "ExegolProgress":
2828
try:
2929
super(ExegolProgress, self).__enter__()
3030
return self
31-
except Exception:
31+
except Exception as e:
3232
ConsoleLock.release()
33-
raise
33+
raise e
3434

3535
async def __aexit__(self, exc_type, exc_val, exc_tb) -> None:
3636
try:

exegol/console/ExegolStatus.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ async def __aenter__(self) -> "ExegolStatus":
1313
try:
1414
self.__enter__()
1515
return self
16-
except Exception:
16+
except Exception as e:
1717
ConsoleLock.release()
18-
raise
18+
raise e
1919

2020
async def __aexit__(self, exc_type, exc_val, exc_tb) -> None:
2121
try:

exegol/console/TUI.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ async def buildDockerImage(build_stream: Generator) -> None:
121121
logfile = None
122122
if ParametersManager().build_log is not None:
123123
# Opening log file in line buffering mode (1) to support tail -f [file]
124-
logfile = open(ParametersManager().build_log, 'a', buffering=1)
124+
logfile = open(ParametersManager().build_log, 'a', buffering=1, encoding="utf-8")
125125
# Follow stream
126126
for line in build_stream:
127127
stream_text = line.get("stream", '')

exegol/console/cli/ExegolCompleter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def ImageCompleter(prefix: str, parsed_args: Namespace, **kwargs) -> Tuple[str,
3333
data = [img_cache.name for img_cache in DataCache().get_images_data().data if img_cache.source == "remote"]
3434
else:
3535
data = [img_cache.name for img_cache in DataCache().get_images_data().data]
36-
except Exception as e:
36+
except Exception:
3737
data = []
3838
if len(data) == 0:
3939
# Fallback with default data if the cache is not initialized yet

exegol/console/cli/actions/ExegolParameters.py

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
from exegol.console.cli.ExegolCompleter import HybridContainerImageCompleter, VoidCompleter, BuildProfileCompleter
1+
from typing import Optional
2+
3+
from exegol.console.cli.ExegolCompleter import HybridContainerImageCompleter, VoidCompleter, BuildProfileCompleter, ImageCompleter
24
from exegol.console.cli.actions.Command import Command, Option, GroupArg
35
from exegol.console.cli.actions.GenericParameters import ContainerCreation, ContainerSpawnShell, ContainerMultiSelector, ContainerSelector, ImageSelector, ImageMultiSelector, ContainerStart
46
from exegol.manager.ExegolManager import ExegolManager
@@ -148,14 +150,56 @@ def __init__(self) -> None:
148150

149151
self._usages = {
150152
"Install or update interactively an exegol image": "exegol update",
151-
"Install or update the [bright_blue]full[/bright_blue] image": "exegol update [bright_blue]full[/bright_blue]"
153+
"Install or update the [bright_blue]full[/bright_blue] image": "exegol update [bright_blue]full[/bright_blue]",
152154
}
153155

154156
def __call__(self, *args, **kwargs):
155157
logger.debug("Running update module")
156158
return ExegolManager.update
157159

158160

161+
class Upgrade(Command, ContainerMultiSelector):
162+
"""Upgrade an Exegol container"""
163+
164+
def __init__(self) -> None:
165+
Command.__init__(self)
166+
ContainerMultiSelector.__init__(self, self.groupArgs)
167+
168+
self.force_mode = Option("-F", "--force",
169+
dest="force_mode",
170+
action="store_true",
171+
help="Upgrade container without interactive user confirmation.")
172+
173+
self.no_backup = Option("--no-backup",
174+
dest="no_backup",
175+
action="store_true",
176+
help="Remove the outdated container after the upgrade instead of renaming it.")
177+
178+
self.image_tag: Optional[Option] = Option("--image",
179+
dest="image_tag",
180+
action="store",
181+
help="Upgrade the container to another Exegol image using its tag",
182+
completer=ImageCompleter)
183+
184+
# Create group parameter for container selection
185+
self.groupArgs.append(GroupArg({"arg": self.image_tag, "required": False},
186+
{"arg": self.no_backup, "required": False},
187+
{"arg": self.force_mode, "required": False},
188+
title="[bold cyan]Upgrade[/bold cyan] [blue]specific options[/blue]"))
189+
190+
self._usages = {
191+
"Upgrade an exegol container": "exegol upgrade",
192+
"Upgrade the [blue]ctf[/blue] container": "exegol upgrade [blue]ctf[/blue]",
193+
"Upgrade the [blue]test[/blue] container to the [bright_blue]full[/bright_blue] image": "exegol upgrade --image [bright_blue]full[/bright_blue] [blue]test[/blue]",
194+
"Upgrade [blue]lab[/blue] and [blue]test[/blue] containers without interactive user confirmation": "exegol upgrade -F [blue]lab[/blue] [blue]test[/blue]",
195+
"Upgrade every outdated container": "exegol upgrade --all",
196+
}
197+
198+
def __call__(self, *args, **kwargs):
199+
logger.debug("Running upgrade module")
200+
return ExegolManager.upgrade
201+
202+
159203
class Uninstall(Command, ImageMultiSelector):
160204
"""Remove Exegol [default not bold]image(s)[/default not bold]"""
161205

exegol/console/cli/actions/GenericParameters.py

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,20 @@ def __init__(self, groupArgs: List[GroupArg]):
6464
"If the container already exists, the variable will be present only in the current shell",
6565
completer=EnvironCompleter)
6666

67+
self.capabilities = Option("--cap",
68+
dest="capabilities",
69+
metavar='CAPABILITY', # Do not display available choices
70+
action="append",
71+
default=[],
72+
choices={"NET_ADMIN", "NET_BROADCAST", "SYS_MODULE", "SYS_PTRACE", "SYS_RAWIO",
73+
"SYS_ADMIN", "LINUX_IMMUTABLE", "MAC_ADMIN", "SYSLOG", "ALL"},
74+
help="[orange3](dangerous)[/orange3] Capabilities allow to add [orange3]specific[/orange3] privileges to the container "
75+
"(e.g. need to mount volumes, perform low-level operations on the network, etc).")
76+
6777
# Create group parameter for container options at start
6878
groupArgs.append(GroupArg({"arg": self.envs, "required": False},
69-
title="[blue]Container start options[/blue]"))
79+
{"arg": self.capabilities, "required": False},
80+
title=f"[blue]Container creation or start options[/blue]"))
7081

7182

7283
class ContainerSpawnShell(ContainerStart):
@@ -103,7 +114,7 @@ def __init__(self, groupArgs: List[GroupArg]):
103114
groupArgs.append(GroupArg({"arg": self.log, "required": False},
104115
{"arg": self.log_method, "required": False},
105116
{"arg": self.log_compress, "required": False},
106-
title="[blue]Container creation Shell logging options[/blue]"))
117+
title="[blue]Container shell logging options[/blue]"))
107118

108119
ContainerStart.__init__(self, groupArgs)
109120

@@ -219,15 +230,6 @@ def __init__(self, groupArgs: List[GroupArg]):
219230
action="store",
220231
help="Set a custom hostname to the exegol container (default: exegol-<name>)",
221232
completer=VoidCompleter)
222-
self.capabilities = Option("--cap",
223-
dest="capabilities",
224-
metavar='CAP', # Do not display available choices
225-
action="append",
226-
default=[],
227-
choices={"NET_ADMIN", "NET_BROADCAST", "SYS_MODULE", "SYS_PTRACE", "SYS_RAWIO",
228-
"SYS_ADMIN", "LINUX_IMMUTABLE", "MAC_ADMIN", "SYSLOG"},
229-
help="[orange3](dangerous)[/orange3] Capabilities allow to add [orange3]specific[/orange3] privileges to the container "
230-
"(e.g. need to mount volumes, perform low-level operations on the network, etc).")
231233
self.privileged = Option("--privileged",
232234
dest="privileged",
233235
action="store_true",
@@ -252,7 +254,6 @@ def __init__(self, groupArgs: List[GroupArg]):
252254
{"arg": self.volumes, "required": False},
253255
{"arg": self.ports, "required": False},
254256
{"arg": self.hostname, "required": False},
255-
{"arg": self.capabilities, "required": False},
256257
{"arg": self.privileged, "required": False},
257258
{"arg": self.devices, "required": False},
258259
{"arg": self.X11, "required": False},
@@ -267,13 +268,13 @@ def __init__(self, groupArgs: List[GroupArg]):
267268
dest="vpn",
268269
default=None,
269270
action="store",
270-
help="Setup an OpenVPN connection at the container creation (example: --vpn /home/user/vpn/conf.ovpn)",
271+
help="Setup an OpenVPN (.ovpn) or WireGuard (.conf) connection at the container creation (example: --vpn /home/user/vpn/client.ovpn)",
271272
completer=FilesCompleter(["ovpn"], directories=True))
272273
self.vpn_auth = Option("--vpn-auth",
273274
dest="vpn_auth",
274275
default=None,
275276
action="store",
276-
help="Enter the credentials with a file (first line: username, second line: password) to establish the VPN connection automatically (example: --vpn-auth /home/user/vpn/auth.txt)")
277+
help="Enter the credentials with a file (first line: username, second line: password) to establish the OpenVPN connection automatically (example: --vpn-auth /home/user/vpn/auth.txt)")
277278

278279
groupArgs.append(GroupArg({"arg": self.vpn, "required": False},
279280
{"arg": self.vpn_auth, "required": False},
@@ -294,4 +295,4 @@ def __init__(self, groupArgs: List[GroupArg]):
294295
completer=DesktopConfigCompleter)
295296
groupArgs.append(GroupArg({"arg": self.desktop, "required": False},
296297
{"arg": self.desktop_config, "required": False},
297-
title="[blue]Container creation Desktop options[/blue] [spring_green1](beta)[/spring_green1]"))
298+
title="[blue]Container creation Desktop options[/blue]"))

0 commit comments

Comments
 (0)