mirror of
https://github.com/arcan1s/ahriman.git
synced 2025-04-24 07:17:17 +00:00
allow to use multiple upload and report targets with the same name
In this feature target option must allways point to section name instead of type. Type will be read from type option. In case if type option is not presented it will try to check if section with architecture exists (e.g. target = email, section = email:x86_64); if it does, the correct section name and type will be used. Otherwise it will check if the specified section exists; if it does, seection name and type will be returned.
This commit is contained in:
parent
fd38dfd176
commit
20962f0385
@ -69,12 +69,19 @@ Settings for signing packages or repository. Group name must refer to architectu
|
|||||||
|
|
||||||
Report generation settings.
|
Report generation settings.
|
||||||
|
|
||||||
* `target` - list of reports to be generated, space separated list of strings, required. Allowed values are `html`, `email`.
|
* `target` - list of reports to be generated, space separated list of strings, required. It must point to valid section (or to section with architecture), e.g. `somerandomname` must point to existing section, `email` must point to one of `email` of `email:x86_64` (with architecture it has higher priority).
|
||||||
|
|
||||||
### `email:*` groups
|
Type will be read from several ways:
|
||||||
|
|
||||||
Group name must refer to architecture, e.g. it should be `email:x86_64` for x86_64 architecture.
|
* In case if `type` option set inside the section, it will be used.
|
||||||
|
* Otherwise, it will look for type from section name removing architecture name.
|
||||||
|
* And finally, it will use section name as type.
|
||||||
|
|
||||||
|
### `email` type
|
||||||
|
|
||||||
|
Section name must be either `email` (plus optional architecture name, e.g. `email:x86_64`) or random name with `type` set.
|
||||||
|
|
||||||
|
* `type` - type of the report, string, optional, must be set to `email` if exists.
|
||||||
* `full_template_path` - path to Jinja2 template for full package description index, string, optional.
|
* `full_template_path` - path to Jinja2 template for full package description index, string, optional.
|
||||||
* `homepage` - link to homepage, string, optional.
|
* `homepage` - link to homepage, string, optional.
|
||||||
* `host` - SMTP host for sending emails, string, required.
|
* `host` - SMTP host for sending emails, string, required.
|
||||||
@ -88,10 +95,11 @@ Group name must refer to architecture, e.g. it should be `email:x86_64` for x86_
|
|||||||
* `template_path` - path to Jinja2 template, string, required.
|
* `template_path` - path to Jinja2 template, string, required.
|
||||||
* `user` - SMTP user to authenticate, string, optional.
|
* `user` - SMTP user to authenticate, string, optional.
|
||||||
|
|
||||||
### `html:*` groups
|
### `html` type
|
||||||
|
|
||||||
Group name must refer to architecture, e.g. it should be `html:x86_64` for x86_64 architecture.
|
Section name must be either `html` (plus optional architecture name, e.g. `html:x86_64`) or random name with `type` set.
|
||||||
|
|
||||||
|
* `type` - type of the report, string, optional, must be set to `html` if exists.
|
||||||
* `path` - path to html report file, string, required.
|
* `path` - path to html report file, string, required.
|
||||||
* `homepage` - link to homepage, string, optional.
|
* `homepage` - link to homepage, string, optional.
|
||||||
* `link_path` - prefix for HTML links, string, required.
|
* `link_path` - prefix for HTML links, string, required.
|
||||||
@ -101,12 +109,19 @@ Group name must refer to architecture, e.g. it should be `html:x86_64` for x86_6
|
|||||||
|
|
||||||
Remote synchronization settings.
|
Remote synchronization settings.
|
||||||
|
|
||||||
* `target` - list of synchronizations to be used, space separated list of strings, required. Allowed values are `rsync`, `s3`, `github`.
|
* `target` - list of synchronizations to be used, space separated list of strings, required. It must point to valid section (or to section with architecture), e.g. `somerandomname` must point to existing section, `github` must point to one of `github` of `github:x86_64` (with architecture it has higher priority).
|
||||||
|
|
||||||
### `github:*` groups
|
Type will be read from several ways:
|
||||||
|
|
||||||
Group name must refer to architecture, e.g. it should be `github:x86_64` for x86_64 architecture. This feature requires Github key creation (see below).
|
* In case if `type` option set inside the section, it will be used.
|
||||||
|
* Otherwise, it will look for type from section name removing architecture name.
|
||||||
|
* And finally, it will use section name as type.
|
||||||
|
|
||||||
|
### `github` type
|
||||||
|
|
||||||
|
This feature requires Github key creation (see below). Section name must be either `github` (plus optional architecture name, e.g. `github:x86_64`) or random name with `type` set.
|
||||||
|
|
||||||
|
* `type` - type of the upload, string, optional, must be set to `github` if exists.
|
||||||
* `owner` - Github repository owner, string, required.
|
* `owner` - Github repository owner, string, required.
|
||||||
* `password` - created Github API key. In order to create it do the following:
|
* `password` - created Github API key. In order to create it do the following:
|
||||||
1. Go to [settings page](https://github.com/settings/profile).
|
1. Go to [settings page](https://github.com/settings/profile).
|
||||||
@ -116,17 +131,19 @@ Group name must refer to architecture, e.g. it should be `github:x86_64` for x86
|
|||||||
* `repository` - Github repository name, string, required. Repository must be created before any action and must have active branch (e.g. with readme).
|
* `repository` - Github repository name, string, required. Repository must be created before any action and must have active branch (e.g. with readme).
|
||||||
* `username` - Github authorization user, string, required. Basically the same as `owner`.
|
* `username` - Github authorization user, string, required. Basically the same as `owner`.
|
||||||
|
|
||||||
### `rsync:*` groups
|
### `rsync` type
|
||||||
|
|
||||||
Group name must refer to architecture, e.g. it should be `rsync:x86_64` for x86_64 architecture. Requires `rsync` package to be installed. Do not forget to configure ssh for user `ahriman`.
|
Requires `rsync` package to be installed. Do not forget to configure ssh for user `ahriman`. Section name must be either `rsync` (plus optional architecture name, e.g. `rsync:x86_64`) or random name with `type` set.
|
||||||
|
|
||||||
|
* `type` - type of the upload, string, optional, must be set to `rsync` if exists.
|
||||||
* `command` - rsync command to run, space separated list of string, required.
|
* `command` - rsync command to run, space separated list of string, required.
|
||||||
* `remote` - remote server to rsync (e.g. `1.2.3.4:path/to/sync`), string, required.
|
* `remote` - remote server to rsync (e.g. `1.2.3.4:path/to/sync`), string, required.
|
||||||
|
|
||||||
### `s3:*` groups
|
### `s3` type
|
||||||
|
|
||||||
Group name must refer to architecture, e.g. it should be `s3:x86_64` for x86_64 architecture.
|
Requires `boto3` library to be installed. Section name must be either `s3` (plus optional architecture name, e.g. `s3:x86_64`) or random name with `type` set.
|
||||||
|
|
||||||
|
* `type` - type of the upload, string, optional, must be set to `github` if exists.
|
||||||
* `access_key` - AWS access key ID, string, required.
|
* `access_key` - AWS access key ID, string, required.
|
||||||
* `bucket` - bucket name (e.g. `bucket`), string, required.
|
* `bucket` - bucket name (e.g. `bucket`), string, required.
|
||||||
* `chunk_size` - chunk size for calculating entity tags, int, optional, default 8 * 1024 * 1024.
|
* `chunk_size` - chunk size for calculating entity tags, int, optional, default 8 * 1024 * 1024.
|
||||||
@ -135,7 +152,7 @@ Group name must refer to architecture, e.g. it should be `s3:x86_64` for x86_64
|
|||||||
|
|
||||||
## `web:*` groups
|
## `web:*` groups
|
||||||
|
|
||||||
Web server settings. If any of `host`/`port` is not set, web integration will be disabled. Group name must refer to architecture, e.g. it should be `web:x86_64` for x86_64 architecture.
|
Web server settings. If any of `host`/`port` is not set, web integration will be disabled. Group name must refer to architecture, e.g. it should be `web:x86_64` for x86_64 architecture. This feature requires `aiohttp` libraries to be installed.
|
||||||
|
|
||||||
* `address` - optional address in form `proto://host:port` (`port` can be omitted in case of default `proto` ports), will be used instead of `http://{host}:{port}` in case if set, string, optional. This option is required in case if `OAuth` provider is used.
|
* `address` - optional address in form `proto://host:port` (`port` can be omitted in case of default `proto` ports), will be used instead of `http://{host}:{port}` in case if set, string, optional. This option is required in case if `OAuth` provider is used.
|
||||||
* `debug` - enable debug toolbar, boolean, optional, default `no`.
|
* `debug` - enable debug toolbar, boolean, optional, default `no`.
|
||||||
|
60
docs/faq.md
60
docs/faq.md
@ -21,6 +21,66 @@ systemctl enable --now ahriman@x86_64.timer
|
|||||||
|
|
||||||
The idea is to install the package as usual, create working directory tree, create configuration for `sudo` and `devtools`. Detailed description of the setup instruction can be found [here](setup.md).
|
The idea is to install the package as usual, create working directory tree, create configuration for `sudo` and `devtools`. Detailed description of the setup instruction can be found [here](setup.md).
|
||||||
|
|
||||||
|
### What does "architecture specific" mean? / How to configure for different architectures?
|
||||||
|
|
||||||
|
Some sections can be configured per architecture. The service will merge architecture specific values into common settings. In order to specify settings for specific architecture you must point it in section name.
|
||||||
|
|
||||||
|
For example, the section
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[build]
|
||||||
|
build_command = extra-x86_64-build
|
||||||
|
```
|
||||||
|
|
||||||
|
states that default build command is `extra-x86_64-build`. But if there is section
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[build:i686]
|
||||||
|
build_command = extra-i686-build
|
||||||
|
```
|
||||||
|
|
||||||
|
the `extra-i686-build` command will be used for `i686` architecture.
|
||||||
|
|
||||||
|
### How to use reporter/upload settings?
|
||||||
|
|
||||||
|
Normally you probably like to generate only one report for the specific type, e.g. only one email report. In order to do it you will need to have the following configuration:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[report]
|
||||||
|
target = email
|
||||||
|
|
||||||
|
[email]
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
or in case of multiple architectures and _different_ reporting settings:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[report]
|
||||||
|
target = email
|
||||||
|
|
||||||
|
[email:i686]
|
||||||
|
...
|
||||||
|
|
||||||
|
[email:x86_64]
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
But for some cases you would like to have multiple different reports with the same type (e.g. sending different templates to different addresses). For these cases you will need to specify section name in target and type in section, e.g. the following configuration can be used:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[report]
|
||||||
|
target = email_1 email_2
|
||||||
|
|
||||||
|
[email_1]
|
||||||
|
type = email
|
||||||
|
...
|
||||||
|
|
||||||
|
[email_2]
|
||||||
|
type = email
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
### Okay, I've installed ahriman, how do I add new package?
|
### Okay, I've installed ahriman, how do I add new package?
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
|
@ -24,7 +24,7 @@ import logging
|
|||||||
|
|
||||||
from logging.config import fileConfig
|
from logging.config import fileConfig
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, Dict, List, Optional, Type
|
from typing import Any, Dict, List, Optional, Tuple, Type
|
||||||
|
|
||||||
from ahriman.core.exceptions import InitializeException
|
from ahriman.core.exceptions import InitializeException
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ class Configuration(configparser.RawConfigParser):
|
|||||||
DEFAULT_LOG_FORMAT = "[%(levelname)s %(asctime)s] [%(filename)s:%(lineno)d] [%(funcName)s]: %(message)s"
|
DEFAULT_LOG_FORMAT = "[%(levelname)s %(asctime)s] [%(filename)s:%(lineno)d] [%(funcName)s]: %(message)s"
|
||||||
DEFAULT_LOG_LEVEL = logging.DEBUG
|
DEFAULT_LOG_LEVEL = logging.DEBUG
|
||||||
|
|
||||||
ARCHITECTURE_SPECIFIC_SECTIONS = ["build", "html", "rsync", "s3", "sign", "web"]
|
ARCHITECTURE_SPECIFIC_SECTIONS = ["build", "sign", "web"]
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
"""
|
"""
|
||||||
@ -121,6 +121,26 @@ class Configuration(configparser.RawConfigParser):
|
|||||||
|
|
||||||
def getpath(self, *args: Any, **kwargs: Any) -> Path: ...
|
def getpath(self, *args: Any, **kwargs: Any) -> Path: ...
|
||||||
|
|
||||||
|
def gettype(self, section: str, architecture: str) -> Tuple[str, str]:
|
||||||
|
"""
|
||||||
|
get type variable with fallback to old logic
|
||||||
|
Despite the fact that it has same semantics as other get* methods, but it has different argument list
|
||||||
|
:param section: section name
|
||||||
|
:param architecture: repository architecture
|
||||||
|
:return: section name and found type name
|
||||||
|
"""
|
||||||
|
group_type = self.get(section, "type", fallback=None) # new-style logic
|
||||||
|
if group_type is not None:
|
||||||
|
return section, group_type
|
||||||
|
# okay lets check for the section with architecture name
|
||||||
|
full_section = self.section_name(section, architecture)
|
||||||
|
if self.has_section(full_section):
|
||||||
|
return full_section, section
|
||||||
|
# okay lets just use section as type
|
||||||
|
if not self.has_section(section):
|
||||||
|
raise configparser.NoSectionError(section)
|
||||||
|
return section, section
|
||||||
|
|
||||||
def load(self, path: Path) -> None:
|
def load(self, path: Path) -> None:
|
||||||
"""
|
"""
|
||||||
fully load configuration
|
fully load configuration
|
||||||
|
@ -45,27 +45,28 @@ class Email(Report, JinjaTemplate):
|
|||||||
:ivar user: username to authenticate via SMTP
|
:ivar user: username to authenticate via SMTP
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, architecture: str, configuration: Configuration) -> None:
|
def __init__(self, architecture: str, configuration: Configuration, section: str) -> None:
|
||||||
"""
|
"""
|
||||||
default constructor
|
default constructor
|
||||||
:param architecture: repository architecture
|
:param architecture: repository architecture
|
||||||
:param configuration: configuration instance
|
:param configuration: configuration instance
|
||||||
|
:param section: settings section name
|
||||||
"""
|
"""
|
||||||
Report.__init__(self, architecture, configuration)
|
Report.__init__(self, architecture, configuration)
|
||||||
JinjaTemplate.__init__(self, "email", configuration)
|
JinjaTemplate.__init__(self, section, configuration)
|
||||||
|
|
||||||
self.full_template_path = configuration.getpath("email", "full_template_path", fallback=None)
|
self.full_template_path = configuration.getpath(section, "full_template_path", fallback=None)
|
||||||
self.template_path = configuration.getpath("email", "template_path")
|
self.template_path = configuration.getpath(section, "template_path")
|
||||||
|
|
||||||
# base smtp settings
|
# base smtp settings
|
||||||
self.host = configuration.get("email", "host")
|
self.host = configuration.get(section, "host")
|
||||||
self.no_empty_report = configuration.getboolean("email", "no_empty_report", fallback=True)
|
self.no_empty_report = configuration.getboolean(section, "no_empty_report", fallback=True)
|
||||||
self.password = configuration.get("email", "password", fallback=None)
|
self.password = configuration.get(section, "password", fallback=None)
|
||||||
self.port = configuration.getint("email", "port")
|
self.port = configuration.getint(section, "port")
|
||||||
self.receivers = configuration.getlist("email", "receivers")
|
self.receivers = configuration.getlist(section, "receivers")
|
||||||
self.sender = configuration.get("email", "sender")
|
self.sender = configuration.get(section, "sender")
|
||||||
self.ssl = SmtpSSLSettings.from_option(configuration.get("email", "ssl", fallback="disabled"))
|
self.ssl = SmtpSSLSettings.from_option(configuration.get(section, "ssl", fallback="disabled"))
|
||||||
self.user = configuration.get("email", "user", fallback=None)
|
self.user = configuration.get(section, "user", fallback=None)
|
||||||
|
|
||||||
def _send(self, text: str, attachment: Dict[str, str]) -> None:
|
def _send(self, text: str, attachment: Dict[str, str]) -> None:
|
||||||
"""
|
"""
|
||||||
|
@ -31,17 +31,18 @@ class HTML(Report, JinjaTemplate):
|
|||||||
:ivar report_path: output path to html report
|
:ivar report_path: output path to html report
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, architecture: str, configuration: Configuration) -> None:
|
def __init__(self, architecture: str, configuration: Configuration, section: str) -> None:
|
||||||
"""
|
"""
|
||||||
default constructor
|
default constructor
|
||||||
:param architecture: repository architecture
|
:param architecture: repository architecture
|
||||||
:param configuration: configuration instance
|
:param configuration: configuration instance
|
||||||
|
:param section: settings section name
|
||||||
"""
|
"""
|
||||||
Report.__init__(self, architecture, configuration)
|
Report.__init__(self, architecture, configuration)
|
||||||
JinjaTemplate.__init__(self, "html", configuration)
|
JinjaTemplate.__init__(self, section, configuration)
|
||||||
|
|
||||||
self.report_path = configuration.getpath("html", "path")
|
self.report_path = configuration.getpath(section, "path")
|
||||||
self.template_path = configuration.getpath("html", "template_path")
|
self.template_path = configuration.getpath(section, "template_path")
|
||||||
|
|
||||||
def generate(self, packages: Iterable[Package], built_packages: Iterable[Package]) -> None:
|
def generate(self, packages: Iterable[Package], built_packages: Iterable[Package]) -> None:
|
||||||
"""
|
"""
|
||||||
|
@ -53,16 +53,17 @@ class Report:
|
|||||||
load client from settings
|
load client from settings
|
||||||
:param architecture: repository architecture
|
:param architecture: repository architecture
|
||||||
:param configuration: configuration instance
|
:param configuration: configuration instance
|
||||||
:param target: target to generate report (e.g. html)
|
:param target: target to generate report aka section name (e.g. html)
|
||||||
:return: client according to current settings
|
:return: client according to current settings
|
||||||
"""
|
"""
|
||||||
provider = ReportSettings.from_option(target)
|
section, provider_name = configuration.gettype(target, architecture)
|
||||||
|
provider = ReportSettings.from_option(provider_name)
|
||||||
if provider == ReportSettings.HTML:
|
if provider == ReportSettings.HTML:
|
||||||
from ahriman.core.report.html import HTML
|
from ahriman.core.report.html import HTML
|
||||||
return HTML(architecture, configuration)
|
return HTML(architecture, configuration, section)
|
||||||
if provider == ReportSettings.Email:
|
if provider == ReportSettings.Email:
|
||||||
from ahriman.core.report.email import Email
|
from ahriman.core.report.email import Email
|
||||||
return Email(architecture, configuration)
|
return Email(architecture, configuration, section)
|
||||||
return cls(architecture, configuration) # should never happen
|
return cls(architecture, configuration) # should never happen
|
||||||
|
|
||||||
def generate(self, packages: Iterable[Package], built_packages: Iterable[Package]) -> None:
|
def generate(self, packages: Iterable[Package], built_packages: Iterable[Package]) -> None:
|
||||||
|
@ -36,15 +36,16 @@ class Github(HttpUpload):
|
|||||||
:ivar gh_repository: github repository name
|
:ivar gh_repository: github repository name
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, architecture: str, configuration: Configuration) -> None:
|
def __init__(self, architecture: str, configuration: Configuration, section: str) -> None:
|
||||||
"""
|
"""
|
||||||
default constructor
|
default constructor
|
||||||
:param architecture: repository architecture
|
:param architecture: repository architecture
|
||||||
:param configuration: configuration instance
|
:param configuration: configuration instance
|
||||||
|
:param section: settings section name
|
||||||
"""
|
"""
|
||||||
HttpUpload.__init__(self, architecture, configuration, "github")
|
HttpUpload.__init__(self, architecture, configuration, section)
|
||||||
self.gh_owner = configuration.get("github", "owner")
|
self.gh_owner = configuration.get(section, "owner")
|
||||||
self.gh_repository = configuration.get("github", "repository")
|
self.gh_repository = configuration.get(section, "repository")
|
||||||
|
|
||||||
def asset_remove(self, release: Dict[str, Any], name: str) -> None:
|
def asset_remove(self, release: Dict[str, Any], name: str) -> None:
|
||||||
"""
|
"""
|
||||||
|
@ -35,15 +35,16 @@ class Rsync(Upload):
|
|||||||
|
|
||||||
_check_output = check_output
|
_check_output = check_output
|
||||||
|
|
||||||
def __init__(self, architecture: str, configuration: Configuration) -> None:
|
def __init__(self, architecture: str, configuration: Configuration, section: str) -> None:
|
||||||
"""
|
"""
|
||||||
default constructor
|
default constructor
|
||||||
:param architecture: repository architecture
|
:param architecture: repository architecture
|
||||||
:param configuration: configuration instance
|
:param configuration: configuration instance
|
||||||
|
:param section: settings section name
|
||||||
"""
|
"""
|
||||||
Upload.__init__(self, architecture, configuration)
|
Upload.__init__(self, architecture, configuration)
|
||||||
self.command = configuration.getlist("rsync", "command")
|
self.command = configuration.getlist(section, "command")
|
||||||
self.remote = configuration.get("rsync", "remote")
|
self.remote = configuration.get(section, "remote")
|
||||||
|
|
||||||
def sync(self, path: Path, built_packages: Iterable[Package]) -> None:
|
def sync(self, path: Path, built_packages: Iterable[Package]) -> None:
|
||||||
"""
|
"""
|
||||||
|
@ -37,15 +37,15 @@ class S3(Upload):
|
|||||||
:ivar chunk_size: chunk size for calculating checksums
|
:ivar chunk_size: chunk size for calculating checksums
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, architecture: str, configuration: Configuration) -> None:
|
def __init__(self, architecture: str, configuration: Configuration, section: str) -> None:
|
||||||
"""
|
"""
|
||||||
default constructor
|
default constructor
|
||||||
:param architecture: repository architecture
|
:param architecture: repository architecture
|
||||||
:param configuration: configuration instance
|
:param configuration: configuration instance
|
||||||
"""
|
"""
|
||||||
Upload.__init__(self, architecture, configuration)
|
Upload.__init__(self, architecture, configuration)
|
||||||
self.bucket = self.get_bucket(configuration)
|
self.bucket = self.get_bucket(configuration, section)
|
||||||
self.chunk_size = configuration.getint("s3", "chunk_size", fallback=8 * 1024 * 1024)
|
self.chunk_size = configuration.getint(section, "chunk_size", fallback=8 * 1024 * 1024)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def calculate_etag(path: Path, chunk_size: int) -> str:
|
def calculate_etag(path: Path, chunk_size: int) -> str:
|
||||||
@ -70,17 +70,18 @@ class S3(Upload):
|
|||||||
return f"{checksum.hexdigest()}{suffix}"
|
return f"{checksum.hexdigest()}{suffix}"
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_bucket(configuration: Configuration) -> Any:
|
def get_bucket(configuration: Configuration, section: str) -> Any:
|
||||||
"""
|
"""
|
||||||
create resource client from configuration
|
create resource client from configuration
|
||||||
:param configuration: configuration instance
|
:param configuration: configuration instance
|
||||||
|
:param section: settings section name
|
||||||
:return: amazon client
|
:return: amazon client
|
||||||
"""
|
"""
|
||||||
client = boto3.resource(service_name="s3",
|
client = boto3.resource(service_name="s3",
|
||||||
region_name=configuration.get("s3", "region"),
|
region_name=configuration.get(section, "region"),
|
||||||
aws_access_key_id=configuration.get("s3", "access_key"),
|
aws_access_key_id=configuration.get(section, "access_key"),
|
||||||
aws_secret_access_key=configuration.get("s3", "secret_key"))
|
aws_secret_access_key=configuration.get(section, "secret_key"))
|
||||||
return client.Bucket(configuration.get("s3", "bucket"))
|
return client.Bucket(configuration.get(section, "bucket"))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def files_remove(local_files: Dict[Path, str], remote_objects: Dict[Path, Any]) -> None:
|
def files_remove(local_files: Dict[Path, str], remote_objects: Dict[Path, Any]) -> None:
|
||||||
|
@ -57,16 +57,17 @@ class Upload:
|
|||||||
:param target: target to run sync (e.g. s3)
|
:param target: target to run sync (e.g. s3)
|
||||||
:return: client according to current settings
|
:return: client according to current settings
|
||||||
"""
|
"""
|
||||||
provider = UploadSettings.from_option(target)
|
section, provider_name = configuration.gettype(target, architecture)
|
||||||
|
provider = UploadSettings.from_option(provider_name)
|
||||||
if provider == UploadSettings.Rsync:
|
if provider == UploadSettings.Rsync:
|
||||||
from ahriman.core.upload.rsync import Rsync
|
from ahriman.core.upload.rsync import Rsync
|
||||||
return Rsync(architecture, configuration)
|
return Rsync(architecture, configuration, section)
|
||||||
if provider == UploadSettings.S3:
|
if provider == UploadSettings.S3:
|
||||||
from ahriman.core.upload.s3 import S3
|
from ahriman.core.upload.s3 import S3
|
||||||
return S3(architecture, configuration)
|
return S3(architecture, configuration, section)
|
||||||
if provider == UploadSettings.Github:
|
if provider == UploadSettings.Github:
|
||||||
from ahriman.core.upload.github import Github
|
from ahriman.core.upload.github import Github
|
||||||
return Github(architecture, configuration)
|
return Github(architecture, configuration, section)
|
||||||
return cls(architecture, configuration) # should never happen
|
return cls(architecture, configuration) # should never happen
|
||||||
|
|
||||||
def run(self, path: Path, built_packages: Iterable[Package]) -> None:
|
def run(self, path: Path, built_packages: Iterable[Package]) -> None:
|
||||||
|
@ -11,7 +11,7 @@ def test_send(configuration: Configuration, mocker: MockerFixture) -> None:
|
|||||||
"""
|
"""
|
||||||
smtp_mock = mocker.patch("smtplib.SMTP")
|
smtp_mock = mocker.patch("smtplib.SMTP")
|
||||||
|
|
||||||
report = Email("x86_64", configuration)
|
report = Email("x86_64", configuration, "email")
|
||||||
report._send("a text", {"attachment.html": "an attachment"})
|
report._send("a text", {"attachment.html": "an attachment"})
|
||||||
smtp_mock.return_value.starttls.assert_not_called()
|
smtp_mock.return_value.starttls.assert_not_called()
|
||||||
smtp_mock.return_value.login.assert_not_called()
|
smtp_mock.return_value.login.assert_not_called()
|
||||||
@ -27,7 +27,7 @@ def test_send_auth(configuration: Configuration, mocker: MockerFixture) -> None:
|
|||||||
configuration.set_option("email", "password", "password")
|
configuration.set_option("email", "password", "password")
|
||||||
smtp_mock = mocker.patch("smtplib.SMTP")
|
smtp_mock = mocker.patch("smtplib.SMTP")
|
||||||
|
|
||||||
report = Email("x86_64", configuration)
|
report = Email("x86_64", configuration, "email")
|
||||||
report._send("a text", {"attachment.html": "an attachment"})
|
report._send("a text", {"attachment.html": "an attachment"})
|
||||||
smtp_mock.return_value.login.assert_called_once()
|
smtp_mock.return_value.login.assert_called_once()
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ def test_send_auth_no_password(configuration: Configuration, mocker: MockerFixtu
|
|||||||
configuration.set_option("email", "user", "username")
|
configuration.set_option("email", "user", "username")
|
||||||
smtp_mock = mocker.patch("smtplib.SMTP")
|
smtp_mock = mocker.patch("smtplib.SMTP")
|
||||||
|
|
||||||
report = Email("x86_64", configuration)
|
report = Email("x86_64", configuration, "email")
|
||||||
report._send("a text", {"attachment.html": "an attachment"})
|
report._send("a text", {"attachment.html": "an attachment"})
|
||||||
smtp_mock.return_value.login.assert_not_called()
|
smtp_mock.return_value.login.assert_not_called()
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ def test_send_auth_no_user(configuration: Configuration, mocker: MockerFixture)
|
|||||||
configuration.set_option("email", "password", "password")
|
configuration.set_option("email", "password", "password")
|
||||||
smtp_mock = mocker.patch("smtplib.SMTP")
|
smtp_mock = mocker.patch("smtplib.SMTP")
|
||||||
|
|
||||||
report = Email("x86_64", configuration)
|
report = Email("x86_64", configuration, "email")
|
||||||
report._send("a text", {"attachment.html": "an attachment"})
|
report._send("a text", {"attachment.html": "an attachment"})
|
||||||
smtp_mock.return_value.login.assert_not_called()
|
smtp_mock.return_value.login.assert_not_called()
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ def test_send_ssl_tls(configuration: Configuration, mocker: MockerFixture) -> No
|
|||||||
configuration.set_option("email", "ssl", "ssl")
|
configuration.set_option("email", "ssl", "ssl")
|
||||||
smtp_mock = mocker.patch("smtplib.SMTP_SSL")
|
smtp_mock = mocker.patch("smtplib.SMTP_SSL")
|
||||||
|
|
||||||
report = Email("x86_64", configuration)
|
report = Email("x86_64", configuration, "email")
|
||||||
report._send("a text", {"attachment.html": "an attachment"})
|
report._send("a text", {"attachment.html": "an attachment"})
|
||||||
smtp_mock.return_value.starttls.assert_not_called()
|
smtp_mock.return_value.starttls.assert_not_called()
|
||||||
smtp_mock.return_value.login.assert_not_called()
|
smtp_mock.return_value.login.assert_not_called()
|
||||||
@ -78,7 +78,7 @@ def test_send_starttls(configuration: Configuration, mocker: MockerFixture) -> N
|
|||||||
configuration.set_option("email", "ssl", "starttls")
|
configuration.set_option("email", "ssl", "starttls")
|
||||||
smtp_mock = mocker.patch("smtplib.SMTP")
|
smtp_mock = mocker.patch("smtplib.SMTP")
|
||||||
|
|
||||||
report = Email("x86_64", configuration)
|
report = Email("x86_64", configuration, "email")
|
||||||
report._send("a text", {"attachment.html": "an attachment"})
|
report._send("a text", {"attachment.html": "an attachment"})
|
||||||
smtp_mock.return_value.starttls.assert_called_once()
|
smtp_mock.return_value.starttls.assert_called_once()
|
||||||
|
|
||||||
@ -89,7 +89,7 @@ def test_generate(configuration: Configuration, package_ahriman: Package, mocker
|
|||||||
"""
|
"""
|
||||||
send_mock = mocker.patch("ahriman.core.report.email.Email._send")
|
send_mock = mocker.patch("ahriman.core.report.email.Email._send")
|
||||||
|
|
||||||
report = Email("x86_64", configuration)
|
report = Email("x86_64", configuration, "email")
|
||||||
report.generate([package_ahriman], [])
|
report.generate([package_ahriman], [])
|
||||||
send_mock.assert_called_once()
|
send_mock.assert_called_once()
|
||||||
|
|
||||||
@ -100,7 +100,7 @@ def test_generate_with_built(configuration: Configuration, package_ahriman: Pack
|
|||||||
"""
|
"""
|
||||||
send_mock = mocker.patch("ahriman.core.report.email.Email._send")
|
send_mock = mocker.patch("ahriman.core.report.email.Email._send")
|
||||||
|
|
||||||
report = Email("x86_64", configuration)
|
report = Email("x86_64", configuration, "email")
|
||||||
report.generate([package_ahriman], [package_ahriman])
|
report.generate([package_ahriman], [package_ahriman])
|
||||||
send_mock.assert_called_once()
|
send_mock.assert_called_once()
|
||||||
|
|
||||||
@ -114,7 +114,7 @@ def test_generate_with_built_and_full_path(
|
|||||||
"""
|
"""
|
||||||
send_mock = mocker.patch("ahriman.core.report.email.Email._send")
|
send_mock = mocker.patch("ahriman.core.report.email.Email._send")
|
||||||
|
|
||||||
report = Email("x86_64", configuration)
|
report = Email("x86_64", configuration, "email")
|
||||||
report.full_template_path = report.template_path
|
report.full_template_path = report.template_path
|
||||||
report.generate([package_ahriman], [package_ahriman])
|
report.generate([package_ahriman], [package_ahriman])
|
||||||
send_mock.assert_called_once()
|
send_mock.assert_called_once()
|
||||||
@ -127,7 +127,7 @@ def test_generate_no_empty(configuration: Configuration, package_ahriman: Packag
|
|||||||
configuration.set_option("email", "no_empty_report", "yes")
|
configuration.set_option("email", "no_empty_report", "yes")
|
||||||
send_mock = mocker.patch("ahriman.core.report.email.Email._send")
|
send_mock = mocker.patch("ahriman.core.report.email.Email._send")
|
||||||
|
|
||||||
report = Email("x86_64", configuration)
|
report = Email("x86_64", configuration, "email")
|
||||||
report.generate([package_ahriman], [])
|
report.generate([package_ahriman], [])
|
||||||
send_mock.assert_not_called()
|
send_mock.assert_not_called()
|
||||||
|
|
||||||
@ -140,6 +140,6 @@ def test_generate_no_empty_with_built(configuration: Configuration, package_ahri
|
|||||||
configuration.set_option("email", "no_empty_report", "yes")
|
configuration.set_option("email", "no_empty_report", "yes")
|
||||||
send_mock = mocker.patch("ahriman.core.report.email.Email._send")
|
send_mock = mocker.patch("ahriman.core.report.email.Email._send")
|
||||||
|
|
||||||
report = Email("x86_64", configuration)
|
report = Email("x86_64", configuration, "email")
|
||||||
report.generate([package_ahriman], [package_ahriman])
|
report.generate([package_ahriman], [package_ahriman])
|
||||||
send_mock.assert_called_once()
|
send_mock.assert_called_once()
|
||||||
|
@ -11,6 +11,6 @@ def test_generate(configuration: Configuration, package_ahriman: Package, mocker
|
|||||||
"""
|
"""
|
||||||
write_mock = mocker.patch("pathlib.Path.write_text")
|
write_mock = mocker.patch("pathlib.Path.write_text")
|
||||||
|
|
||||||
report = HTML("x86_64", configuration)
|
report = HTML("x86_64", configuration, "html")
|
||||||
report.generate([package_ahriman], [])
|
report.generate([package_ahriman], [])
|
||||||
write_mock.assert_called_once()
|
write_mock.assert_called_once()
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from pathlib import Path
|
|
||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
|
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
@ -15,7 +14,7 @@ def test_report_failure(configuration: Configuration, mocker: MockerFixture) ->
|
|||||||
"""
|
"""
|
||||||
mocker.patch("ahriman.core.report.html.HTML.generate", side_effect=Exception())
|
mocker.patch("ahriman.core.report.html.HTML.generate", side_effect=Exception())
|
||||||
with pytest.raises(ReportFailed):
|
with pytest.raises(ReportFailed):
|
||||||
Report.load("x86_64", configuration, ReportSettings.HTML.name).run(Path("path"), [])
|
Report.load("x86_64", configuration, "html").run([], [])
|
||||||
|
|
||||||
|
|
||||||
def test_report_dummy(configuration: Configuration, mocker: MockerFixture) -> None:
|
def test_report_dummy(configuration: Configuration, mocker: MockerFixture) -> None:
|
||||||
@ -24,7 +23,7 @@ def test_report_dummy(configuration: Configuration, mocker: MockerFixture) -> No
|
|||||||
"""
|
"""
|
||||||
mocker.patch("ahriman.models.report_settings.ReportSettings.from_option", return_value=ReportSettings.Disabled)
|
mocker.patch("ahriman.models.report_settings.ReportSettings.from_option", return_value=ReportSettings.Disabled)
|
||||||
report_mock = mocker.patch("ahriman.core.report.report.Report.generate")
|
report_mock = mocker.patch("ahriman.core.report.report.Report.generate")
|
||||||
Report.load("x86_64", configuration, ReportSettings.Disabled.name).run(Path("path"), [])
|
Report.load("x86_64", configuration, "disabled").run([], [])
|
||||||
report_mock.assert_called_once()
|
report_mock.assert_called_once()
|
||||||
|
|
||||||
|
|
||||||
@ -33,7 +32,7 @@ def test_report_email(configuration: Configuration, mocker: MockerFixture) -> No
|
|||||||
must generate email report
|
must generate email report
|
||||||
"""
|
"""
|
||||||
report_mock = mocker.patch("ahriman.core.report.email.Email.generate")
|
report_mock = mocker.patch("ahriman.core.report.email.Email.generate")
|
||||||
Report.load("x86_64", configuration, ReportSettings.Email.name).run(Path("path"), [])
|
Report.load("x86_64", configuration, "email").run([], [])
|
||||||
report_mock.assert_called_once()
|
report_mock.assert_called_once()
|
||||||
|
|
||||||
|
|
||||||
@ -42,5 +41,5 @@ def test_report_html(configuration: Configuration, mocker: MockerFixture) -> Non
|
|||||||
must generate html report
|
must generate html report
|
||||||
"""
|
"""
|
||||||
report_mock = mocker.patch("ahriman.core.report.html.HTML.generate")
|
report_mock = mocker.patch("ahriman.core.report.html.HTML.generate")
|
||||||
Report.load("x86_64", configuration, ReportSettings.HTML.name).run(Path("path"), [])
|
Report.load("x86_64", configuration, "html").run([], [])
|
||||||
report_mock.assert_called_once()
|
report_mock.assert_called_once()
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import configparser
|
import configparser
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
|
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
@ -24,53 +24,6 @@ def test_from_path(mocker: MockerFixture) -> None:
|
|||||||
load_logging_mock.assert_called_once()
|
load_logging_mock.assert_called_once()
|
||||||
|
|
||||||
|
|
||||||
def test_section_name(configuration: Configuration) -> None:
|
|
||||||
"""
|
|
||||||
must return architecture specific group
|
|
||||||
"""
|
|
||||||
assert configuration.section_name("build", "x86_64") == "build:x86_64"
|
|
||||||
|
|
||||||
|
|
||||||
def test_absolute_path_for_absolute(configuration: Configuration) -> None:
|
|
||||||
"""
|
|
||||||
must not change path for absolute path in settings
|
|
||||||
"""
|
|
||||||
path = Path("/a/b/c")
|
|
||||||
configuration.set_option("build", "path", str(path))
|
|
||||||
assert configuration.getpath("build", "path") == path
|
|
||||||
|
|
||||||
|
|
||||||
def test_absolute_path_for_relative(configuration: Configuration) -> None:
|
|
||||||
"""
|
|
||||||
must prepend root path to relative path
|
|
||||||
"""
|
|
||||||
path = Path("a")
|
|
||||||
configuration.set_option("build", "path", str(path))
|
|
||||||
result = configuration.getpath("build", "path")
|
|
||||||
assert result.is_absolute()
|
|
||||||
assert result.parent == configuration.path.parent
|
|
||||||
assert result.name == path.name
|
|
||||||
|
|
||||||
|
|
||||||
def test_path_with_fallback(configuration: Configuration) -> None:
|
|
||||||
"""
|
|
||||||
must return fallback path
|
|
||||||
"""
|
|
||||||
path = Path("a")
|
|
||||||
assert configuration.getpath("some", "option", fallback=path).name == str(path)
|
|
||||||
assert configuration.getpath("some", "option", fallback=None) is None
|
|
||||||
|
|
||||||
|
|
||||||
def test_path_without_fallback(configuration: Configuration) -> None:
|
|
||||||
"""
|
|
||||||
must raise exception without fallback
|
|
||||||
"""
|
|
||||||
with pytest.raises(configparser.NoSectionError):
|
|
||||||
assert configuration.getpath("some", "option")
|
|
||||||
with pytest.raises(configparser.NoOptionError):
|
|
||||||
assert configuration.getpath("build", "option")
|
|
||||||
|
|
||||||
|
|
||||||
def test_dump(configuration: Configuration) -> None:
|
def test_dump(configuration: Configuration) -> None:
|
||||||
"""
|
"""
|
||||||
dump must not be empty
|
dump must not be empty
|
||||||
@ -93,6 +46,53 @@ def test_dump_architecture_specific(configuration: Configuration) -> None:
|
|||||||
assert dump["build"]["archbuild_flags"] == "hello flag"
|
assert dump["build"]["archbuild_flags"] == "hello flag"
|
||||||
|
|
||||||
|
|
||||||
|
def test_section_name(configuration: Configuration) -> None:
|
||||||
|
"""
|
||||||
|
must return architecture specific group
|
||||||
|
"""
|
||||||
|
assert configuration.section_name("build", "x86_64") == "build:x86_64"
|
||||||
|
|
||||||
|
|
||||||
|
def test_getpath_absolute_to_absolute(configuration: Configuration) -> None:
|
||||||
|
"""
|
||||||
|
must not change path for absolute path in settings
|
||||||
|
"""
|
||||||
|
path = Path("/a/b/c")
|
||||||
|
configuration.set_option("build", "path", str(path))
|
||||||
|
assert configuration.getpath("build", "path") == path
|
||||||
|
|
||||||
|
|
||||||
|
def test_getpath_absolute_to_relative(configuration: Configuration) -> None:
|
||||||
|
"""
|
||||||
|
must prepend root path to relative path
|
||||||
|
"""
|
||||||
|
path = Path("a")
|
||||||
|
configuration.set_option("build", "path", str(path))
|
||||||
|
result = configuration.getpath("build", "path")
|
||||||
|
assert result.is_absolute()
|
||||||
|
assert result.parent == configuration.path.parent
|
||||||
|
assert result.name == path.name
|
||||||
|
|
||||||
|
|
||||||
|
def test_getpath_with_fallback(configuration: Configuration) -> None:
|
||||||
|
"""
|
||||||
|
must return fallback path
|
||||||
|
"""
|
||||||
|
path = Path("a")
|
||||||
|
assert configuration.getpath("some", "option", fallback=path).name == str(path)
|
||||||
|
assert configuration.getpath("some", "option", fallback=None) is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_getpath_without_fallback(configuration: Configuration) -> None:
|
||||||
|
"""
|
||||||
|
must raise exception without fallback
|
||||||
|
"""
|
||||||
|
with pytest.raises(configparser.NoSectionError):
|
||||||
|
assert configuration.getpath("some", "option")
|
||||||
|
with pytest.raises(configparser.NoOptionError):
|
||||||
|
assert configuration.getpath("build", "option")
|
||||||
|
|
||||||
|
|
||||||
def test_getlist(configuration: Configuration) -> None:
|
def test_getlist(configuration: Configuration) -> None:
|
||||||
"""
|
"""
|
||||||
must return list of string correctly
|
must return list of string correctly
|
||||||
@ -119,6 +119,43 @@ def test_getlist_single(configuration: Configuration) -> None:
|
|||||||
assert configuration.getlist("build", "test_list") == ["a"]
|
assert configuration.getlist("build", "test_list") == ["a"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_gettype(configuration: Configuration) -> None:
|
||||||
|
"""
|
||||||
|
must extract type from variable
|
||||||
|
"""
|
||||||
|
section, provider = configuration.gettype("customs3", "x86_64")
|
||||||
|
assert section == "customs3"
|
||||||
|
assert provider == "s3"
|
||||||
|
|
||||||
|
|
||||||
|
def test_gettype_from_section(configuration: Configuration) -> None:
|
||||||
|
"""
|
||||||
|
must extract type from section name
|
||||||
|
"""
|
||||||
|
section, provider = configuration.gettype("rsync", "x86_64")
|
||||||
|
assert section == "rsync"
|
||||||
|
assert provider == "rsync"
|
||||||
|
|
||||||
|
|
||||||
|
def test_gettype_from_section_with_architecture(configuration: Configuration) -> None:
|
||||||
|
"""
|
||||||
|
must extract type from section name with architecture
|
||||||
|
"""
|
||||||
|
section, provider = configuration.gettype("github", "x86_64")
|
||||||
|
assert section == "github:x86_64"
|
||||||
|
assert provider == "github"
|
||||||
|
|
||||||
|
|
||||||
|
def test_gettype_from_section_no_section(configuration: Configuration) -> None:
|
||||||
|
"""
|
||||||
|
must extract type from section name with architecture
|
||||||
|
"""
|
||||||
|
# technically rsync:x86_64 is valid section
|
||||||
|
# but in current configuration it must be considered as missing section
|
||||||
|
with pytest.raises(configparser.NoSectionError):
|
||||||
|
configuration.gettype("rsync:x86_64", "x86_64")
|
||||||
|
|
||||||
|
|
||||||
def test_load_includes_missing(configuration: Configuration) -> None:
|
def test_load_includes_missing(configuration: Configuration) -> None:
|
||||||
"""
|
"""
|
||||||
must not fail if not include directory found
|
must not fail if not include directory found
|
||||||
@ -137,7 +174,7 @@ def test_load_includes_no_option(configuration: Configuration) -> None:
|
|||||||
|
|
||||||
def test_load_includes_no_section(configuration: Configuration) -> None:
|
def test_load_includes_no_section(configuration: Configuration) -> None:
|
||||||
"""
|
"""
|
||||||
must not fail if no option set
|
must not fail if no section set
|
||||||
"""
|
"""
|
||||||
configuration.remove_section("settings")
|
configuration.remove_section("settings")
|
||||||
configuration.load_includes()
|
configuration.load_includes()
|
||||||
|
@ -20,7 +20,7 @@ def github(configuration: Configuration) -> Github:
|
|||||||
:param configuration: configuration fixture
|
:param configuration: configuration fixture
|
||||||
:return: github test instance
|
:return: github test instance
|
||||||
"""
|
"""
|
||||||
return Github("x86_64", configuration)
|
return Github("x86_64", configuration, "github:x86_64")
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
@ -50,7 +50,7 @@ def rsync(configuration: Configuration) -> Rsync:
|
|||||||
:param configuration: configuration fixture
|
:param configuration: configuration fixture
|
||||||
:return: rsync test instance
|
:return: rsync test instance
|
||||||
"""
|
"""
|
||||||
return Rsync("x86_64", configuration)
|
return Rsync("x86_64", configuration, "rsync")
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
@ -60,7 +60,7 @@ def s3(configuration: Configuration) -> S3:
|
|||||||
:param configuration: configuration fixture
|
:param configuration: configuration fixture
|
||||||
:return: S3 test instance
|
:return: S3 test instance
|
||||||
"""
|
"""
|
||||||
return S3("x86_64", configuration)
|
return S3("x86_64", configuration, "customs3")
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
|
@ -15,7 +15,7 @@ def test_upload_failure(configuration: Configuration, mocker: MockerFixture) ->
|
|||||||
"""
|
"""
|
||||||
mocker.patch("ahriman.core.upload.rsync.Rsync.sync", side_effect=Exception())
|
mocker.patch("ahriman.core.upload.rsync.Rsync.sync", side_effect=Exception())
|
||||||
with pytest.raises(SyncFailed):
|
with pytest.raises(SyncFailed):
|
||||||
Upload.load("x86_64", configuration, UploadSettings.Rsync.name).run(Path("path"), [])
|
Upload.load("x86_64", configuration, "rsync").run(Path("path"), [])
|
||||||
|
|
||||||
|
|
||||||
def test_report_dummy(configuration: Configuration, mocker: MockerFixture) -> None:
|
def test_report_dummy(configuration: Configuration, mocker: MockerFixture) -> None:
|
||||||
@ -24,7 +24,7 @@ def test_report_dummy(configuration: Configuration, mocker: MockerFixture) -> No
|
|||||||
"""
|
"""
|
||||||
mocker.patch("ahriman.models.upload_settings.UploadSettings.from_option", return_value=UploadSettings.Disabled)
|
mocker.patch("ahriman.models.upload_settings.UploadSettings.from_option", return_value=UploadSettings.Disabled)
|
||||||
upload_mock = mocker.patch("ahriman.core.upload.upload.Upload.sync")
|
upload_mock = mocker.patch("ahriman.core.upload.upload.Upload.sync")
|
||||||
Upload.load("x86_64", configuration, UploadSettings.Disabled.name).run(Path("path"), [])
|
Upload.load("x86_64", configuration, "disabled").run(Path("path"), [])
|
||||||
upload_mock.assert_called_once()
|
upload_mock.assert_called_once()
|
||||||
|
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ def test_upload_rsync(configuration: Configuration, mocker: MockerFixture) -> No
|
|||||||
must upload via rsync
|
must upload via rsync
|
||||||
"""
|
"""
|
||||||
upload_mock = mocker.patch("ahriman.core.upload.rsync.Rsync.sync")
|
upload_mock = mocker.patch("ahriman.core.upload.rsync.Rsync.sync")
|
||||||
Upload.load("x86_64", configuration, UploadSettings.Rsync.name).run(Path("path"), [])
|
Upload.load("x86_64", configuration, "rsync").run(Path("path"), [])
|
||||||
upload_mock.assert_called_once()
|
upload_mock.assert_called_once()
|
||||||
|
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ def test_upload_s3(configuration: Configuration, mocker: MockerFixture) -> None:
|
|||||||
must upload via s3
|
must upload via s3
|
||||||
"""
|
"""
|
||||||
upload_mock = mocker.patch("ahriman.core.upload.s3.S3.sync")
|
upload_mock = mocker.patch("ahriman.core.upload.s3.S3.sync")
|
||||||
Upload.load("x86_64", configuration, UploadSettings.S3.name).run(Path("path"), [])
|
Upload.load("x86_64", configuration, "customs3").run(Path("path"), [])
|
||||||
upload_mock.assert_called_once()
|
upload_mock.assert_called_once()
|
||||||
|
|
||||||
|
|
||||||
@ -51,5 +51,5 @@ def test_upload_github(configuration: Configuration, mocker: MockerFixture) -> N
|
|||||||
must upload via github
|
must upload via github
|
||||||
"""
|
"""
|
||||||
upload_mock = mocker.patch("ahriman.core.upload.github.Github.sync")
|
upload_mock = mocker.patch("ahriman.core.upload.github.Github.sync")
|
||||||
Upload.load("x86_64", configuration, UploadSettings.Github.name).run(Path("path"), [])
|
Upload.load("x86_64", configuration, "github").run(Path("path"), [])
|
||||||
upload_mock.assert_called_once()
|
upload_mock.assert_called_once()
|
||||||
|
@ -55,13 +55,16 @@ target =
|
|||||||
command = rsync --archive --verbose --compress --partial --delete
|
command = rsync --archive --verbose --compress --partial --delete
|
||||||
remote =
|
remote =
|
||||||
|
|
||||||
[s3]
|
[disabled]
|
||||||
|
|
||||||
|
[customs3]
|
||||||
|
type = s3
|
||||||
access_key =
|
access_key =
|
||||||
bucket = bucket
|
bucket = bucket
|
||||||
region = eu-central-1
|
region = eu-central-1
|
||||||
secret_key =
|
secret_key =
|
||||||
|
|
||||||
[github]
|
[github:x86_64]
|
||||||
owner = arcan1s
|
owner = arcan1s
|
||||||
password =
|
password =
|
||||||
repository = ahriman
|
repository = ahriman
|
||||||
|
Loading…
Reference in New Issue
Block a user