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

Improve the config setup

parent 62e8696d
No related branches found
No related tags found
1 merge request!17Update playbooks
Pipeline #18605 passed
# This is the default ansible "inventory" file.
# This is the "defaut" freva deployment configuration file.
#
# - The files syntax follows the `toml` markup language (https://toml.io)
# - Comments begin with the "#" character
# - Blank lines are ignored
# - Groups of hosts are delimited by [header] elements
# - The groups define different deployment steps
# - Additional configuration for each group is set in the confg section
# of each header -> [header.config]
# - You can enter hostnames or ip addresses
# - A hostname/ip can be a member of multiple groups
# On this hostnames the freva web frontend will be deployed
## The first part of this configuration defines general configuration that
## is common among all deployment steps.
## Set the path to the public certfificate files that is used to make password
## queries to the vault server or used as web certfificate. If you leave this
## key empty a new certfificate will be created
cert_file = ""
# The the project name that should be used for this freva instance
project_name = ""
[web]
# Set the hostnames where all services (database, solr, vault) will be
# deployed
# Set the hostnames where all services web ui will be deployed
hosts = ""
# If you have multiple hosts following a pattern you can specify
# them like this:
##hosts = "alpha.example.org,beta.example.org,192.168.1.100,192.168.1.110"
##hosts = "www[001:006].example.com"
## hosts = "alpha.example.org,beta.example.org,192.168.1.100,192.168.1.110"
## hosts = "www[001:006].example.com"
# Ex 3: A collection of database servers in the "dbservers" group
## Ex : A collection of database servers in the "dbservers" group
## Here"s another example of host ranges, this time there are no
## leading 0s:
##hosts = "db-[99:101]-node.example.com"
## hosts = "db-[99:101]-node.example.com"
[solr]
## Set the hostnames running the apache solr service
hosts = ""
## Set the hostnames running the mariadb service
[db]
## Set the hostnames running the mariadb service
hosts = ""
[core]
### Set the hostnames where the command line interface of freva will be installed
### The following hostnames will run the mariadb server
hosts = ""
......@@ -54,6 +69,10 @@ db = ""
#ansible_python_interpreter = ""
##If you need a different user name you can set it here:
#ansible_python_interpreter="/usr/bin/python3"
##Indicate whether or not to empty any pre-existing folders/docker volumes.
##(Useful for a truely fresh start) (default: False)
wipe = false
[solr.config]
## Config variables for the solr service
port = 8983
......@@ -62,8 +81,12 @@ core = "files"
mem = "4g"
## Ansible needs a python3 interpreter, which can be set for custom python3 instances
#ansible_python_interpreter = ""
##If you need a different user name you can set it here:
## If you need a different user name you can set it here:
#ansible_user = "username"
##Indicate whether or not to empty any pre-existing folders/docker volumes.
##(Useful for a truely fresh start) (default: False)
wipe = false
[core.config]
## List of user(s) that can alter the configuration of the freva cmd line interface
......@@ -103,6 +126,9 @@ arch = "Linux-x86_64"
## The core deployment needs git, if git is not in the default PATH vraiable
## you can set the path to the git executable
#git_path = ""
##Indicate whether or not to empty any pre-existing folders/docker volumes.
##(Useful for a truely fresh start) (default: False)
wipe = false
[web.config]
......@@ -127,11 +153,10 @@ about_us_text = ""
## Set a list of email addresses for contacts
contacts = ""
## Now set postal address
address = ["Project name",
"German Climate Computing Centre (DKRZ)",
"Bundesstr. 45a",
"20146 Hamburg",
"Germany."]
address = "Project name, German Climate Computing Centre (DKRZ), Bundesstr. 45a, 20146 Hamburg, Germany."
##Indicate whether or not to empty any pre-existing folders/docker volumes.
##(Useful for a truely fresh start) (default: False)
wipe = false
## Here you can set a lengthy project description.
## You can also set a path to a filename that contains the information.
## Instead of text you can set a path to a file containing the text, like a html file.
......@@ -139,14 +164,13 @@ homepage_text = "Bal bla bla."
## Set a one line blurb of the project
hompage_heading = "Short description of the project."
## Set the name of the project/institution
institution_name = "FreVa"
institution_name = "Freva"
## Set the slurm scheduler host
scheduler_host = ["mistal.dkrz.de"]
scheduler_host = ["levante.dkrz.de"]
## Settings for ldap
## Ldap server name(s)
auth_ldap_server_uri = ["ldap://mldap0.hpc.dkrz.de",
"ldap://mldap1.hpc.dkrz.de"]
auth_ldap_server_uri = "ldap://mldap0.hpc.dkrz.de,ldap://mldap1.hpc.dkrz.de"
## Set the group that will be allowed to log on
allowed_group = "test_group"
## Set the ldap search user base
......
......@@ -17,7 +17,6 @@ def parse_args(argv: list[str] | None) -> argparse.Namespace:
description="Deploy freva and its services on different machines.",
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
ap.add_argument("project_name", type=str, help="Name of the project")
ap.add_argument(
"--server-map",
type=str,
......@@ -43,30 +42,6 @@ def parse_args(argv: list[str] | None) -> argparse.Namespace:
choices=["services", "web", "core", "db", "solr", "backup"],
help="The services/code stack to be deployed",
)
ap.add_argument(
"--cert",
"--cert_file",
"--cert-file",
type=Path,
default=None,
help="Path to public certificate file. If none is given, "
"default, a file will be created.",
)
ap.add_argument(
"--domain",
type=str,
help="Domain name of your organisation to create a uniq identifier.",
default="dkrz",
)
ap.add_argument(
"--wipe",
action="store_true",
default=False,
help=(
"This option will empty any pre-existing folders/docker volumes. "
"(Useful for a truely fresh start)"
),
)
ap.add_argument(
"--ask-pass",
help="Connect to server via ssh passwd instead of public key.",
......@@ -101,11 +76,8 @@ def cli(argv: list[str] | None = None) -> None:
server_map = guess_map_server(args.server_map, mandatory=False)
set_log_level(args.verbose)
with DeployFactory(
args.project_name,
steps=args.steps,
cert_file=args.cert,
config_file=args.config,
wipe=args.wipe,
) as DF:
DF.play(server_map, args.ask_pass, args.verbose)
......
......@@ -39,15 +39,13 @@ class DeployFactory:
The path to the public cert file that is injected to the web container.
config_file: os.PathLike, default: None
Path to any existing deployment configuration file.
wipe: bool, default: False
Delete any existing deployment resources, such as docker volumes.
Examples
--------
>>> from freva_deployment import DeployFactory as DF
>>> deploy = DF("xces", steps=["solr"], ask_pass=True)
>>> deploy.play()
>>> deploy = DF(steps=["solr"])
>>> deploy.play(ask_pass=True)
"""
step_order: tuple[str, ...] = ("vault", "db", "solr", "core", "web")
......@@ -55,11 +53,8 @@ class DeployFactory:
def __init__(
self,
project_name: str,
steps: list[str] | None = None,
cert_file: str | None = None,
config_file: Path | str | None = None,
wipe: bool = False,
) -> None:
self._config_keys: list[str] = []
......@@ -69,13 +64,14 @@ class DeployFactory:
self.eval_conf_file: Path = Path(self._td.name) / "evaluation_system.conf"
self.web_conf_file: Path = Path(self._td.name) / "freva_web.toml"
self._db_pass: str = ""
self.project_name = project_name
self._steps = steps or ["services", "core", "web"]
self.wipe = wipe
self._cert_file = cert_file or ""
self._inv_tmpl = Path(config_file or config_dir / "inventory.toml")
self._cfg_tmpl = self.aux_dir / "evaluation_system.conf.tmpl"
self.cfg = self._read_cfg()
self._cert_file = self.cfg.pop("cert_file", "")
self.project_name = self.cfg.pop("project_name", None)
if not self.project_name:
raise ValueError("You must set a project name")
@property
def private_key_file(self) -> str:
......@@ -343,7 +339,6 @@ class DeployFactory:
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")
or "/usr/bin/python3"
......@@ -362,7 +357,7 @@ class DeployFactory:
config[step]["hosts"] = self.cfg[step]["hosts"]
config[step]["vars"] = {}
for key, value in self.cfg[step]["config"].items():
if key not in ("root_passwd",):
if key not in ("root_passwd", "wipe"):
new_key = f"{step}_{key}"
else:
new_key = key
......
......@@ -44,9 +44,7 @@ def tui() -> None:
return
setup = main_app.setup
if setup:
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:
with DeployFactory(**setup) as DF:
DF.play(server_map, ask_pass, verbosity)
......@@ -204,6 +204,17 @@ class WebScreen(BaseForm):
),
True,
),
wipe=(
self.add_widget_intelligent(
npyscreen.CheckBox,
max_height=2,
value=cfg.get("wipe", False),
editable=True,
name=(f"{self.num}Delete existing data?"),
scroll_exit=True,
),
True,
),
branch=(
self.add_widget_intelligent(
npyscreen.TitleText,
......@@ -449,6 +460,17 @@ class DBScreen(BaseForm):
),
True,
),
wipe=(
self.add_widget_intelligent(
npyscreen.CheckBox,
max_height=2,
value=cfg.get("wipe", False),
editable=True,
name=(f"{self.num}Delete existing data?"),
scroll_exit=True,
),
True,
),
user=(
self.add_widget_intelligent(
npyscreen.TitleText,
......@@ -515,6 +537,17 @@ class SolrScreen(BaseForm):
),
True,
),
wipe=(
self.add_widget_intelligent(
npyscreen.CheckBox,
max_height=2,
value=cfg.get("wipe", False),
editable=True,
name=(f"{self.num}Delete existing data?"),
scroll_exit=True,
),
True,
),
mem=(
self.add_widget_intelligent(
npyscreen.TitleCombo,
......@@ -597,18 +630,16 @@ class RunForm(npyscreen.FormMultiPageAction):
msg = f"Public certificate file `{cert_file}` {is_file} must exist or empty."
npyscreen.notify_confirm(msg, title="ERROR")
return
if cert_file:
cert_file = str(Path(cert_file).expanduser().absolute())
self.cert_file.value = cert_file
save_file = self.parentApp.save_config_to_file(write_toml_file=True)
if isinstance(save_file, Path):
save_file = str(save_file)
if cert_file:
cert_file = str(Path(cert_file).expanduser().absolute())
self.parentApp.setup = {
"project_name": self.project_name.value,
"server_map": self.server_map.value,
"steps": list(set(self.parentApp.steps)),
"config_file": save_file or None,
"cert_file": cert_file or None,
"wipe": bool(self.wipe.value),
"ask_pass": bool(self.use_ssh_pw.value),
}
self.parentApp.exit_application(msg="Do you want to continue?")
......@@ -633,7 +664,6 @@ class RunForm(npyscreen.FormMultiPageAction):
def _add_widgets(self) -> None:
"""Add the widgets to the form."""
wipe = self.parentApp._read_cache("wipe", False)
ssh_pw = self.parentApp._read_cache("ssh_pw", True)
self.project_name = self.add_widget_intelligent(
npyscreen.TitleText,
......@@ -655,14 +685,6 @@ class RunForm(npyscreen.FormMultiPageAction):
name=f"{self.num}Select a public certificate file, defaults to `<project_name>.crt`",
value=str(self.parentApp.cert_file or ""),
)
self.wipe = self.add_widget_intelligent(
npyscreen.CheckBox,
max_height=2,
value=wipe,
editable=True,
name=f"{self.num}Delete all existing data on docker volumes (wipe)",
scroll_exit=True,
)
self.use_ssh_pw = self.add_widget_intelligent(
npyscreen.CheckBox,
max_height=2,
......
......@@ -161,27 +161,23 @@ class MainApp(npyscreen.NPSAppManaged):
save_file = str(Path(save_file).expanduser().absolute())
else:
save_file = None
cert_file = self._setup_form.cert_file.value
cert_file = self.cert_file
if cert_file:
cert_file = str(Path(cert_file).expanduser().absolute())
else:
cert_file = None
cert_file = ""
project_name = self._setup_form.project_name.value
wipe = self._setup_form.wipe.value
server_map = self._setup_form.server_map.value
ssh_pw = self._setup_form.use_ssh_pw.value
if isinstance(wipe, list):
wipe = bool(wipe[0])
if isinstance(ssh_pw, list):
ssh_pw = bool(ssh_pw[0])
config = {
"save_file": save_file,
"steps": self.steps,
"cert_file": cert_file,
"project_name": project_name,
"wipe": wipe,
"ssh_pw": ssh_pw,
"server_map": server_map,
"cert_file": cert_file,
"config": self.config,
}
with open(self.cache_dir / "freva_deployment.json", "w") as f:
......@@ -199,6 +195,8 @@ class MainApp(npyscreen.NPSAppManaged):
for key, config in settings["config"].items():
config_tmpl[step]["config"][key] = config
save_file.parent.mkdir(exist_ok=True, parents=True)
config_tmpl["cert_file"] = cert_file
config_tmpl["project_name"] = project_name
with open(save_file, "w") as f:
toml_string = tomlkit.dumps(config_tmpl)
f.write(toml_string)
......
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