Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add setup command and systemd service #27

Merged
merged 4 commits into from
Jan 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added changelog.d/25.fixed
Empty file.
45 changes: 22 additions & 23 deletions cobbler-tftp.spec
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,12 @@
# Please submit bugfixes or comments via https://bugs.opensuse.org/
#

%if 0%{?suse_version} > 1500
%bcond_without libalternatives
%else
%bcond_with libalternatives
%endif

%define python_package_name cobbler_tftp

%define pythons python3
%{?sle15_python_module_pythons}
Name: cobbler-tftp
Version: 0.0.0+git.1705312236.c60217f
Version:
Release: 0
Summary: The TFTP server daemon for Cobbler
License: GPL-2.0-or-later
Expand All @@ -34,6 +29,7 @@ Source0: %{name}-%{version}.tar.gz

%if 0%{?suse_version}
BuildRequires: python-rpm-macros
BuildRequires: systemd-rpm-macros
%endif

BuildRequires: fdupes
Expand All @@ -42,6 +38,13 @@ BuildRequires: %{python_module pip}
BuildRequires: %{python_module setuptools}
BuildRequires: %{python_module setuptools_scm}
BuildRequires: %{python_module wheel}
BuildRequires: %{python_module fbtftp}
BuildRequires: %{python_module python-daemon}
BuildRequires: %{python_module PyYAML}
BuildRequires: %{python_module click}
BuildRequires: %{python_module importlib-metadata}
BuildRequires: %{python_module importlib-resources}
BuildRequires: %{python_module schema}

Requires: python3-fbtftp
Requires: python3-python-daemon
Expand All @@ -50,15 +53,7 @@ Requires: python3-click
Requires: python3-importlib-metadata
Requires: python3-importlib-resources
Requires: python3-schema
%if %{with libalternatives}
Requires: alts
BuildRequires: alts
%else
Requires(post): update-alternatives
Requires(postun): update-alternatives
%endif
BuildArch: noarch
%python_subpackages

%description
Cobbler-TFTP is a lightweight CLI application written in Python that serves as a stateless TFTP server.
Expand All @@ -73,25 +68,29 @@ cp -r %{_sourcedir}/cobbler-tftp-%{version}/.git %{_builddir}/cobbler-tftp-%{ver

%install
%pyproject_install
%python_clone -a %{buildroot}%{_bindir}/cobbler-tftp
%python_expand %fdupes %{buildroot}%{$python_sitelib}
%python_expand PYTHONPATH=%{buildroot}%{$python_sitelib} %{buildroot}%{_bindir}/cobbler-tftp setup --systemd-dir=%{_unitdir} --install-prefix=%{buildroot}
%fdupes %{buildroot}%{_prefix}

%pre
%python_libalternatives_reset_alternative cobbler-tftp
%service_add_pre cobbler-tftp.service

%post
%python_install_alternative cobbler-tftp
%service_add_post cobbler-tftp.service

%preun
%service_del_preun cobbler-tftp.service

%postun
%python_uninstall_alternative cobbler-tftp
%service_del_postun cobbler-tftp.service

%files %{python_files}
%files
%license LICENSE
%doc README.md
%python_alternative %{_bindir}/cobbler-tftp
%{_bindir}/cobbler-tftp-%{python_bin_suffix}
%{_bindir}/cobbler-tftp
%{python_sitelib}/%{python_package_name}
%{python_sitelib}/%{python_package_name}-*.dist-info
%config /etc/cobbler-tftp
%{_unitdir}/cobbler-tftp.service

%changelog

76 changes: 75 additions & 1 deletion src/cobbler_tftp/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"""

import os
import sys
from pathlib import Path
from signal import SIGCHLD, SIGTERM
from typing import List, Optional
Expand All @@ -16,8 +17,14 @@
except ImportError: # use backport for Python versions older than 3.8
import importlib_metadata

try:
from importlib.resources import files
except ImportError:
from importlib_resources import files

from cobbler_tftp.server import run_server
from cobbler_tftp.settings import SettingsFactory
from cobbler_tftp.utils import copy_file

try:
__version__ = importlib_metadata.version("cobbler_tftp")
Expand Down Expand Up @@ -57,7 +64,11 @@ def cli(ctx):
help="Enable or disable auto migration of settings.",
)
@click.option(
"--config", "-c", type=click.Path(), help="Set location of configuration file."
"--config",
"-c",
default="/etc/cobbler-tftp/settings.yml",
type=click.Path(),
help="Set location of configuration file.",
)
@click.option(
"--settings",
Expand Down Expand Up @@ -149,7 +160,70 @@ def stop(config: Optional[str], pid_file: Optional[str]):
pid_file_path.unlink()


@cli.command()
@click.option(
"--systemd-dir",
type=click.Path(),
default="/etc/systemd/system",
help="Where to install systemd unit files",
)
@click.option(
"--config-dir",
type=click.Path(),
default="/etc/cobbler-tftp",
help="Where to install the configuration files for cobbler-tftp",
)
@click.option(
"--systemd/--no-systemd",
is_flag=True,
default=True,
help="Whether to install systemd unit files or not",
)
@click.option(
"--install-prefix",
type=click.Path(),
default=None,
help="Installation prefix for the file locations that will be ignored during runtime",
)
def setup(
systemd_dir: str,
config_dir: str,
systemd: bool,
install_prefix: Optional[str],
):
"""
Install configuration files and systemd unit files into the specified directories
"""
if install_prefix is not None:
systemd_path = Path(install_prefix, systemd_dir.strip("/"))
config_path = Path(install_prefix, config_dir.strip("/"))
else:
systemd_path = Path(systemd_dir)
config_path = Path(config_dir)
config_dir = str(config_path.absolute())
try:
config_path.mkdir(parents=True, exist_ok=True)
source_path = files("cobbler_tftp.settings.data")
if systemd:
systemd_path.mkdir(parents=True, exist_ok=True)
copy_file(source_path, systemd_path, "cobbler-tftp.service")
copy_file(
source_path,
config_path,
"settings.yml",
[("/etc/cobbler-tftp", config_dir)],
)
copy_file(source_path, config_path, "logging.conf")
except PermissionError as err:
click.echo(err, err=True)
click.echo(
"Try changing the --systemd-dir/--config-dir parameters or running as root."
)
sys.exit(1)


cli.add_command(start)
cli.add_command(version)
cli.add_command(print_default_config)
cli.add_command(stop)
cli.add_command(setup)
11 changes: 11 additions & 0 deletions src/cobbler_tftp/settings/data/cobbler-tftp.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[Unit]
Description=Cobbler TFTP Server
After=network.target

[Service]
ExecStart=/usr/bin/cobbler-tftp start --no-daemon
PrivateTmp=yes
Type=exec

[Install]
WantedBy=multi-user.target
35 changes: 35 additions & 0 deletions src/cobbler_tftp/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"""

Check notice on line 1 in src/cobbler_tftp/utils.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

src/cobbler_tftp/utils.py#L1

One-line docstring should fit on one line with quotes (found 3) (D200)
Various utility functions for cobbler-tftp
"""

from pathlib import Path
from typing import List, Optional, Tuple

try:
from importlib.abc import Traversable
except ImportError:
from importlib_resources.abc import Traversable


def copy_file(
src_dir: Traversable,
dst_dir: Path,
name: str,
patch: Optional[List[Tuple[str, str]]] = None,
):
"""
Copy a file to a different directory, preserving the name and
possibly replacing strings in it.

:param src_dir: Directory that contains the file to copy.
:param dst_dir: Directory to copy the file into.
:param name: Name of the file (in both directories).
:param patch: List of (old, new) strings to replace in the file.
"""
src = src_dir / name
dst = dst_dir / name
contents: bytes = src.read_bytes() # type: ignore
if patch is not None:
for old, new in patch:
contents = contents.replace(old.encode("UTF-8"), new.encode("UTF-8"))
dst.write_bytes(contents)
Loading