This commit is contained in:
holger krekel
2023-12-09 17:45:26 +01:00
parent 00a203c9aa
commit d3ca037ebf
11 changed files with 66 additions and 79 deletions

View File

@@ -25,7 +25,12 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: run init.sh
run: ./scripts/init.sh - name: create venv
- name: run test.sh run: python3 -m venv
run: ./scripts/test.sh
- name: install packages into venv
run: venv/bin/pip install chatmaild deploy_chatmail
- name: run tests
- run: venv/bin/cmdeploy test

View File

@@ -36,26 +36,22 @@ DNS domain name (FQDN), for example `chat.example.org`.
3. Create chatmail configuration file `chatmail.ini`: 3. Create chatmail configuration file `chatmail.ini`:
``` ```
cmdeploy init chatmail.ini CHATMAIL_DOMAIN cmdeploy init CHATMAIL_DOMAIN
``` ```
4. Deploy to the remote chatmail server, pointing to the chatmail config file: 4. Deploy to the remote chatmail server:
``` ```
cmdeploy install chatmail.ini cmdeploy run
``` ```
5. To output a DNS zone file from which you can transfer DNS records 5. To output a DNS zone file from which you can transfer DNS records
to your DNS provider for your `CHATMAIL_DOMAIN` to your DNS provider:
``` ```
cmdeploy dns chatmail.ini cmdeploy dnszone
``` ```
to generate a DNS zone file from which you can transfer records to your
DNS provider.
### Refining the web pages ### Refining the web pages

View File

@@ -1,5 +1,3 @@
from pathlib import Path
from fnmatch import fnmatch
import iniconfig import iniconfig
@@ -23,3 +21,31 @@ class Config:
def _getbytefile(self): def _getbytefile(self):
return open(self._inipath, "rb") return open(self._inipath, "rb")
def write_initial_config(inipath, mailname):
from importlib.resources import files
inidir = files(__package__).joinpath("ini")
content = inidir.joinpath("chatmail.ini.f").read_text().format(mailname=mailname)
if mailname.endswith(".testrun.org"):
override_inipath = inidir.joinpath("override-testrun.ini")
privacy = iniconfig.IniConfig(override_inipath)["privacy"]
lines = []
for line in content.split("\n"):
for key, value in privacy.items():
value_lines = value.strip().split("\n")
if not line.startswith(f"{key} =") or not value_lines:
continue
if len(value_lines) == 1:
lines.append(f"{key} = {value}")
else:
lines.append(f"{key} =")
for vl in value_lines:
lines.append(f" {vl}")
break
else:
lines.append(line)
content = "\n".join(lines)
inipath.write_text(content)

View File

@@ -7,7 +7,6 @@ from email.parser import BytesParser
from email import policy from email import policy
from email.utils import parseaddr from email.utils import parseaddr
from aiosmtpd.smtp import SMTP
from aiosmtpd.controller import Controller from aiosmtpd.controller import Controller
from smtplib import SMTP as SMTPClient from smtplib import SMTP as SMTPClient

View File

@@ -4,6 +4,7 @@ along with command line option and subcommand parsing.
""" """
import importlib.resources import importlib.resources
import argparse import argparse
import shutil
import subprocess import subprocess
import os import os
from pathlib import Path from pathlib import Path
@@ -11,7 +12,7 @@ from pathlib import Path
import iniconfig import iniconfig
from termcolor import colored from termcolor import colored
from chatmaild.config import read_config from chatmaild.config import read_config, write_initial_config
class Out: class Out:
@@ -52,6 +53,7 @@ def add_subcommand(subparsers, func):
doc = func.__doc__.strip() doc = func.__doc__.strip()
p = subparsers.add_parser(name, description=doc, help=doc) p = subparsers.add_parser(name, description=doc, help=doc)
p.set_defaults(func=func) p.set_defaults(func=func)
add_config_option(p)
return p return p
@@ -63,15 +65,13 @@ def get_parser():
) )
init_parser = add_subcommand(subparsers, init_cmd) init_parser = add_subcommand(subparsers, init_cmd)
add_config_option(init_parser)
init_parser.add_argument( init_parser.add_argument(
"chatmail_domain", "chatmail_domain",
action="store", action="store",
help="fully qualified DNS domain name for your chatmail instance", help="fully qualified DNS domain name for your chatmail instance",
) )
install_parser = add_subcommand(subparsers, install_cmd) install_parser = add_subcommand(subparsers, run_cmd)
add_config_option(install_parser)
install_parser.add_argument( install_parser.add_argument(
"--dry-run", "--dry-run",
dest="dry_run", dest="dry_run",
@@ -80,46 +80,24 @@ def get_parser():
) )
add_subcommand(subparsers, webdev_cmd) add_subcommand(subparsers, webdev_cmd)
add_subcommand(subparsers, test_cmd)
return parser return parser
def write_initial_config(inipath, mailname, out):
inidir = importlib.resources.files(__package__).joinpath("ini")
content = inidir.joinpath("chatmail.ini.f").read_text().format(mailname=mailname)
if mailname.endswith(".testrun.org"):
override_inipath = inidir.joinpath("override-testrun.ini")
privacy = iniconfig.IniConfig(override_inipath)["privacy"]
lines = []
for line in content.split("\n"):
for key, value in privacy.items():
value_lines = value.strip().split("\n")
if not line.startswith(f"{key} =") or not value_lines:
continue
if len(value_lines) == 1:
lines.append(f"{key} = {value}")
else:
lines.append(f"{key} =")
for vl in value_lines:
lines.append(f" {vl}")
break
else:
lines.append(line)
content = "\n".join(lines)
inipath.write_text(content)
out(f"written {inipath} for chatmail domain {mailname}")
def init_cmd(args, out): def init_cmd(args, out):
"""Initialize chatmail config file.""" """Initialize chatmail config file."""
if args.chatmail_ini.exists(): if args.chatmail_ini.exists():
out.red(f"Path exists, not modifying: {args.chatmail_ini}") out.red(f"Path exists, not modifying: {args.chatmail_ini}")
raise SystemExit(1) raise SystemExit(1)
write_initial_config(args.chatmail_ini, args.chatmail_domain, out) write_initial_config(args.chatmail_ini, args.chatmail_domain)
out.green(f"created config file for {args.chatmail_domain} in {args.chatmail_ini}")
def install_cmd(args, out): def run_cmd(args, out):
"""Install or update chatmail services on the remote server.""" """Deploy chatmail services on the remote server."""
import pyinfra import pyinfra
try: try:
@@ -147,6 +125,17 @@ def webdev_cmd(args, out):
main() main()
def test_cmd(args, out):
"""run Run web development loop for static local web pages."""
tox = shutil.which("tox")
subprocess.check_call([tox, "-c", "chatmaild"])
subprocess.check_call([tox, "-c", "deploy-chatmail"])
pytest_path = shutil.which("tox")
subprocess.check_call([pytest_path, "tests/online", "-rs", "-x", "-vrx", "--durations=5"])
def main(args=None): def main(args=None):
"""Provide main entry point for 'xdcget' CLI invocation.""" """Provide main entry point for 'xdcget' CLI invocation."""
parser = get_parser() parser = get_parser()

View File

@@ -1,9 +0,0 @@
#!/usr/bin/env bash
echo -----------------------------------------
echo deploying to $CHATMAIL_DOMAIN
echo -----------------------------------------
venv/bin/pyinfra --ssh-user root "$CHATMAIL_DOMAIN" \
deploy-chatmail/src/deploy_chatmail/deploy.py run chatmail.ini

View File

@@ -1,9 +0,0 @@
#!/bin/sh
set -e
python3 -m venv venv
pip=venv/bin/pip
$pip install pyinfra pytest build 'setuptools>=68' tox
$pip install -e deploy-chatmail
$pip install -e chatmaild
venv/bin/deploy-chatmail init $*

View File

@@ -1,9 +0,0 @@
#!/usr/bin/env bash
echo -----------------------------------------
echo starting local webdev
echo -----------------------------------------
venv/bin/python3 -m deploy_chatmail.www

View File

@@ -409,12 +409,11 @@ class CMUser:
@pytest.fixture @pytest.fixture
def make_config(tmp_path): def make_config(tmp_path):
from deploy_chatmail.cmdeploy import main from chatmaild.config import read_config, write_initial_config
from chatmaild.config import read_config
inipath = tmp_path.joinpath("chatmail.ini") inipath = tmp_path.joinpath("chatmail.ini")
def make_conf(mailname): def make_conf(mailname):
main(["init", "--config", str(inipath), mailname]) write_initial_config(inipath, mailname=mailname)
return read_config(inipath) return read_config(inipath)
return make_conf return make_conf