Skip to content
Snippets Groups Projects
Commit 62e8696d authored by Martin Bergemann's avatar Martin Bergemann :speech_balloon:
Browse files

Improve tui

parent 69ace900
No related branches found
No related tags found
1 merge request!17Update playbooks
Pipeline #18601 passed
......@@ -120,7 +120,7 @@ class DeployFactory:
self.cfg["db"]["config"]["keyfile"] = self.public_key_file
self.cfg["db"]["config"]["private_keyfile"] = self.private_key_file
for key in ("name", "user", "db"):
self.cfg["db"]["config"].setdefault(key, "freva")
self.cfg["db"]["config"][key] = self.cfg["db"]["config"].get(key) or "freva"
db_host = self.cfg["db"]["config"].get("host", "")
if not db_host:
self.cfg["db"]["config"]["host"] = host
......@@ -135,7 +135,9 @@ class DeployFactory:
"""prepare the apache solr service."""
self._config_keys.append("solr")
for key, default in dict(core="files", mem="4g", port=8983).items():
self.cfg["solr"]["config"].setdefault(key, default)
self.cfg["solr"]["config"][key] = (
self.cfg["solr"]["config"].get(key) or default
)
self.cfg["solr"]["config"]["email"] = ",".join(
self.cfg["web"]["config"].get("contacts", [])
)
......@@ -143,22 +145,29 @@ class DeployFactory:
def _prep_core(self) -> None:
"""prepare the core deployment."""
self._config_keys.append("core")
self.cfg["core"]["config"].setdefault("admins", getuser())
self.cfg["core"]["config"]["admins"] = (
self.cfg["core"]["config"].get("admins") or getuser()
)
if not self.cfg["core"]["config"]["admins"]:
self.cfg["core"]["config"]["admins"] = getuser()
self.cfg["core"]["config"].setdefault("branch", "freva-dev")
self.cfg["core"]["config"]["branch"] = (
self.cfg["core"]["config"].get("branch") or "freva-dev"
)
install_dir = self.cfg["core"]["config"]["install_dir"]
root_dir = self.cfg["core"]["config"].get("root_dir", "")
if not root_dir:
self.cfg["core"]["config"]["root_dir"] = install_dir
self.cfg["core"]["config"]["keyfile"] = self.public_key_file
self.cfg["core"]["config"]["private_keyfile"] = self.private_key_file
self.cfg["core"]["config"].setdefault("git_path", "git")
git_exe = self.cfg["core"]["config"].get("git_path")
self.cfg["core"]["config"]["git_path"] = git_exe or "git"
def _prep_web(self) -> None:
"""prepare the web deployment."""
self._config_keys.append("web")
self.cfg["web"]["config"].setdefault("branch", "master")
self.cfg["web"]["config"]["branch"] = (
self.cfg["web"]["config"].get("branch") or "main"
)
self._prep_core()
admin = self.cfg["core"]["config"]["admins"]
if not isinstance(admin, str):
......@@ -331,13 +340,14 @@ class DeployFactory:
config[step]["vars"][f"{step}_hostname"] = self.cfg[step]["hosts"]
config[step]["vars"][f"{step}_name"] = f"{self.project_name}-{step}"
config[step]["vars"]["asset_dir"] = str(asset_dir)
config[step]["vars"]["ansible_user"] = self.cfg[step]["config"].get(
"ansible_user", getuser()
config[step]["vars"]["ansible_user"] = (
self.cfg[step]["config"].get("ansible_user") or getuser()
)
config[step]["vars"]["wipe"] = self.wipe
config[step]["vars"][f"{step}_ansible_python_interpreter"] = self.cfg[step][
"config"
].get("ansible_python_interpreter", "/usr/bin/python3")
config[step]["vars"][f"{step}_ansible_python_interpreter"] = (
self.cfg[step]["config"].get("ansible_python_interpreter")
or "/usr/bin/python3"
)
dump_file = self._get_files_copy(step)
if dump_file:
config[step]["vars"][f"{step}_dump"] = str(dump_file)
......
......@@ -47,5 +47,6 @@ def tui() -> None:
project_name = setup.pop("project_name")
server_map = setup.pop("server_map")
ask_pass = setup.pop("ask_pass")
print(setup)
with DeployFactory(project_name, **setup) as DF:
DF.play(server_map, ask_pass, verbosity)
......@@ -28,7 +28,13 @@ class FileSelector(npyscreen.FileSelector):
else:
self.file_extentions = file_extentions
super().__init__(*args, **kwargs)
self.how_exited_handers[npyscreen.wgwidget.EXITED_ESCAPE] = self.exit_editing
self.how_exited_handers[npyscreen.wgwidget.EXITED_ESCAPE] = self.exit
def exit(self) -> None:
"""Exit the dialogue."""
self.wCommand.value = ""
self.value = ""
self.exit_editing()
def update_grid(self) -> None:
if self.value:
......@@ -36,40 +42,34 @@ class FileSelector(npyscreen.FileSelector):
if not os.path.exists(self.value):
self.value = os.getcwd()
if os.path.isdir(self.value):
working_dir = self.value
working_dir = Path(self.value)
else:
working_dir = os.path.dirname(self.value)
working_dir = Path(self.value).parent
self.wStatus1.value = working_dir
file_list = []
if os.path.abspath(os.path.join(working_dir, "..")) != os.path.abspath(
working_dir
):
file_list.append("..")
file_list, dir_list = [], []
if working_dir.parent != working_dir:
dir_list.append("..")
try:
file_list.extend(
[os.path.join(working_dir, fn) for fn in os.listdir(working_dir)]
)
for fn in working_dir.glob("*"):
rel_path = str(fn.relative_to(working_dir))
if not rel_path.startswith("."):
if fn.is_dir():
dir_list.append(str(fn) + os.sep)
elif fn.suffix in self.file_extentions:
file_list.append(str(fn))
except OSError:
npyscreen.notify_wait(
title="Error", message="Could not read specified directory."
)
# DOES NOT CURRENTLY WORK - EXCEPT FOR THE WORKING DIRECTORY. REFACTOR.
new_file_list = []
for f in file_list:
f = os.path.normpath(f)
if os.path.isdir(f):
new_file_list.append(f + os.sep)
else:
if Path(f).suffix in self.file_extentions:
new_file_list.append(f)
file_list = new_file_list
del new_file_list
# sort Filelist
file_list.sort()
file_list.sort(key=str.casefold)
dir_list.sort(key=str.casefold)
if self.sort_by_extension:
file_list.sort(key=self.get_extension)
file_list.sort(key=os.path.isdir, reverse=True)
self.wMain.set_grid_values_from_flat_list(file_list, reset_cursor=False)
self.wMain.set_grid_values_from_flat_list(
dir_list + file_list, reset_cursor=False
)
self.display()
......@@ -93,6 +93,8 @@ def selectFile(starting_value: str = "", *args, **keywords):
class BaseForm(npyscreen.FormMultiPageWithMenus, npyscreen.FormWithMenus):
"""Base class for forms."""
_num: int = 0
def get_config(self, key) -> dict[str, str | bool | list[str]]:
"""Read the configuration for a step."""
try:
......@@ -102,6 +104,9 @@ class BaseForm(npyscreen.FormMultiPageWithMenus, npyscreen.FormWithMenus):
except (KeyError, AttributeError, TypeError):
cfg = {"config": {}}
cfg.setdefault("config", {})
for k, values in cfg["config"].items():
if values is None:
cfg["config"][k] = ""
return cfg["config"]
def get_host(self, key) -> str:
......@@ -114,6 +119,12 @@ class BaseForm(npyscreen.FormMultiPageWithMenus, npyscreen.FormWithMenus):
host = [v.strip() for v in host.split(",") if v.strip()]
return ",".join(host)
@property
def num(self) -> str:
"""Calculate the number for enumerations of any input field."""
self._num += 1
return f"{self._num}. "
def check_config(
self,
notify: bool = True,
......
This diff is collapsed.
......@@ -19,10 +19,18 @@ from .deploy_forms import WebScreen, DBScreen, SolrScreen, CoreScreen, RunForm
class MainApp(npyscreen.NPSAppManaged):
config: dict[str, Any] = dict()
@property
def steps(self) -> list[str]:
"""Get the deploy steps."""
steps = []
for step, form_obj in self._forms.items():
if form_obj.use.value and step not in steps:
steps.append(step)
return steps
def onStart(self) -> None:
"""When Application starts, set up the Forms that will be used."""
self.cache_dir.mkdir(exist_ok=True, parents=True)
self.steps: list[str] = []
self.setup: dict[str, Any] = {}
self._steps_lookup = {
"core": "MAIN",
......@@ -83,8 +91,6 @@ class MainApp(npyscreen.NPSAppManaged):
cfg = form_obj.check_config(notify=stop_at_missing)
if cfg is None and stop_at_missing:
return self._steps_lookup[step]
if form_obj.use.value:
self.steps.append(step)
self.config[step] = cfg
return None
......@@ -96,7 +102,7 @@ class MainApp(npyscreen.NPSAppManaged):
break
try:
self.check_missing_config(stop_at_missing=False)
self.save_config_to_file(exclude=["steps"])
self.save_config_to_file()
except Exception:
pass
......@@ -137,13 +143,29 @@ class MainApp(npyscreen.NPSAppManaged):
self._update_config(the_selected_file)
self.save_config_to_file()
def save_config_to_file(
self, write_toml_file: bool = False, exclude: list[str] | None = None
) -> Path | None:
def save_config_to_file(self, **kwargs) -> Path | None:
"""Save the status of the tui to file."""
try:
return self._save_config_to_file(**kwargs)
except Exception as error:
npyscreen.notify_confirm(
title="Error",
message=f"Couldn't save config:\n{error.__str__()}",
)
return None
def _save_config_to_file(self, write_toml_file: bool = False) -> Path | None:
cache_file = self.cache_dir / ".temp_file.toml"
save_file = Path(self._setup_form.inventory_file.value)
cert_file = Path(self._setup_form.cert_file.value)
save_file = self._setup_form.inventory_file.value
if save_file:
save_file = str(Path(save_file).expanduser().absolute())
else:
save_file = None
cert_file = self._setup_form.cert_file.value
if cert_file:
cert_file = str(Path(cert_file).expanduser().absolute())
else:
cert_file = None
project_name = self._setup_form.project_name.value
wipe = self._setup_form.wipe.value
server_map = self._setup_form.server_map.value
......@@ -152,11 +174,10 @@ class MainApp(npyscreen.NPSAppManaged):
wipe = bool(wipe[0])
if isinstance(ssh_pw, list):
ssh_pw = bool(ssh_pw[0])
exclude = exclude or []
config = {
"save_file": str(save_file.expanduser().absolute()),
"steps": list(set(self.steps)),
"cert_file": str(cert_file.expanduser().absolute()),
"save_file": save_file,
"steps": self.steps,
"cert_file": cert_file,
"project_name": project_name,
"wipe": wipe,
"ssh_pw": ssh_pw,
......@@ -167,8 +188,7 @@ class MainApp(npyscreen.NPSAppManaged):
json.dump({k: v for (k, v) in config.items()}, f, indent=3)
if write_toml_file is False:
return None
save_file = save_file or cache_file
save_file = Path(save_file).expanduser().absolute()
save_file = Path(save_file or cache_file)
try:
with open(asset_dir / "config" / "inventory.toml") as f:
config_tmpl = cast(Dict[str, Any], tomlkit.load(f))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment