Skip to content

Commit

Permalink
v3
Browse files Browse the repository at this point in the history
  • Loading branch information
a1fred committed Nov 24, 2021
1 parent 71fe32f commit 7b33ec0
Show file tree
Hide file tree
Showing 28 changed files with 143 additions and 142 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ qa:
poetry run mypy .

.PHONY: test
test: docs qa dev
test: qa docs dev
poetry run python3 -m pytest -x --cov-report term --cov=carnival -vv tests/

.PHONY: test_fast
Expand Down
4 changes: 2 additions & 2 deletions carnival/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from carnival.hosts.base import Host, Connection, Result
from carnival.hosts.local import LocalHost
from carnival.hosts.ssh import SshHost
from carnival.task import TaskBase, StepsTask
from carnival.task import TaskBase, Task
from carnival import cmd
from carnival import internal_tasks
from carnival.utils import log
Expand All @@ -21,7 +21,7 @@
__all__ = [
'Step',
'SshHost', 'LocalHost', 'Host', 'Connection', 'Result',
'TaskBase', 'StepsTask',
'TaskBase', 'Task',
'cmd',
'log',
'internal_tasks',
Expand Down
2 changes: 1 addition & 1 deletion carnival/cmd/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
Модуль carnival.cmd содержит базовые комманды для взаимодействия с сервером.
Модуль carnival.cmd содержит базовые команды для взаимодействия с сервером.
Его цель - оставаться простым и помогать в написании шагов (Step).
Для написания сложных сценариев предполагается использовать шаги(Step).
Expand Down
14 changes: 12 additions & 2 deletions carnival/cmd/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,22 @@

def run(c: Connection, command: str, warn: bool = True, hide: bool = False, cwd: typing.Optional[str] = None) -> Result:
"""
Запустить комманду
Запустить команду
См <https://docs.pyinvoke.org/en/latest/api/runners.html>
:param c: Конект с хостом
:param command: Команда для запуска
:param warn: Вывести stderr
:param hide: Скрыть вывод команды
:param cwd: Перейти в папку при выполнении команды
"""
return c.run(command, warn=warn, hide=hide, cwd=cwd)


def is_cmd_exist(c: Connection, cmd_name: str) -> bool:
"""
Проверить есть ли команда в $PATH
:param c: Конект с хостом
:param command: Команда
"""
return run(c, f"which {cmd_name}", hide=True, warn=True).ok
5 changes: 5 additions & 0 deletions carnival/cmd/fs.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ def mkdirs(c: Connection, *dirs: str) -> List[Result]:
"""
Создать директории
:param c: Конект с хостом
:param dirs: пути которые нужно создать
"""
return [cmd.cli.run(c, f"mkdir -p {x}", hide=True) for x in dirs]
Expand All @@ -30,6 +31,7 @@ def is_dir_exists(c: Connection, dir_path: str) -> bool:
"""
Узнать существует ли директория
:param c: Конект с хостом
:param dir_path: путь до директории
"""
return bool(cmd.cli.run(c, f"test -d {dir_path}", warn=True, hide=True).ok)
Expand All @@ -39,6 +41,7 @@ def is_file_contains(c: Connection, filename: str, text: str, exact: bool = Fals
"""
Содержит ли файл текст
:param c: Конект с хостом
:param filename: путь до файла
:param text: текст который нужно искать
:param exact: точное совпадение
Expand All @@ -58,6 +61,7 @@ def is_file_exists(c: Connection, path: str) -> bool:
"""
Проверить существует ли файл
:param c: Конект с хостом
:param path: путь до файла
"""

Expand All @@ -75,6 +79,7 @@ def ensure_dir_exists(
"""
Проверить что директория существует и параметры соответствуют заданным
:param c: Конект с хостом
:param path: путь до директории
:param user: владелец
:param group: группа
Expand Down
7 changes: 7 additions & 0 deletions carnival/cmd/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ def set_password(c: Connection, username: str, password: str) -> Result:
"""
Установить пароль пользователю
:param c: Конект с хостом
:param username: Пользователь
:param password: Новый пароль
"""
Expand All @@ -15,6 +16,8 @@ def set_password(c: Connection, username: str, password: str) -> Result:
def get_current_user_name(c: Connection) -> str:
"""
Получить имя текущего пользователя
:param c: Конект с хостом
"""
id_res: str = cmd.cli.run(c, "id -u -n", hide=True).stdout
return id_res.strip()
Expand All @@ -23,12 +26,16 @@ def get_current_user_name(c: Connection) -> str:
def get_current_user_id(c: Connection) -> int:
"""
Получить id текущего пользователя
:param c: Конект с хостом
"""
return int(cmd.cli.run(c, "id -u", hide=True).stdout.strip())


def is_current_user_root(c: Connection) -> bool:
"""
Проверить что текущий пользователь - `root`
:param c: Конект с хостом
"""
return get_current_user_id(c) == 0
6 changes: 5 additions & 1 deletion carnival/cmd/transfer.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ def rsync(
) -> Result:
"""
Залить папку с локального диска на сервер по rsync
:param host: сервер
:param host: сервер куда заливать
:param source: локальный путь до папки
:param target: путь куда нужно залить
:param rsync_opts: параметры команды rsync
Expand Down Expand Up @@ -65,6 +66,7 @@ def get(c: Connection, remote: str, local: str, preserve_mode: bool = True) -> N
Скачать файл с сервера
<http://docs.fabfile.org/en/2.5/api/transfer.html#fabric.transfer.Transfer.get>
:param c: Конект с хостом
:param remote: путь до файла на сервере
:param local: путь куда сохранить файл
:param preserve_mode: сохранить права
Expand All @@ -79,6 +81,7 @@ def put(c: Connection, local: str, remote: str, preserve_mode: bool = True) -> N
Закачать файл на сервер
<http://docs.fabfile.org/en/2.5/api/transfer.html#fabric.transfer.Transfer.put>
:param c: Конект с хостом
:param local: путь до локального файла
:param remote: путь куда сохранить на сервере
:param preserve_mode: сохранить права
Expand All @@ -95,6 +98,7 @@ def put_template(c: Connection, template_path: str, remote: str, **context: Any)
<http://docs.fabfile.org/en/2.5/api/transfer.html#fabric.transfer.Transfer.put>
:param c: Конект с хостом
:param template_path: путь до локального файла jinja
:param remote: путь куда сохранить на сервере
:param context: контекс для рендеринга jinja2
Expand Down
38 changes: 31 additions & 7 deletions carnival/hosts/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@

@dataclass
class Result:
"""
Результат выполнения команды
"""

return_code: int
ok: bool
stdout: str
Expand All @@ -27,13 +31,25 @@ def from_invoke_result(cls, invoke_result: InvokeResult) -> "Result":
return Result(
return_code=invoke_result.exited,
ok=invoke_result.ok,
stdout=invoke_result.stdout,
stderr=invoke_result.stderr,
stdout=invoke_result.stdout.replace("\r", ""),
stderr=invoke_result.stderr.replace("\r", ""),
)


class Connection:
host: "Host"
"""
Хост с которым связан конект
"""

def __init__(self, host: "Host") -> None:
"""
Конекст с хостом, все конекты являются контекст-менеджерами
>>> with host.connection() as c:
>>> c.run("ls -1")
"""
self.host = host

def __enter__(self) -> "Connection":
Expand All @@ -49,26 +65,34 @@ def run(
hide: bool = False, warn: bool = True, cwd: typing.Optional[str] = None,
) -> Result:
"""
Запустить комманду
Запустить команду
См <https://docs.pyinvoke.org/en/latest/api/runners.html>
:param command: Команда для запуска
:param hide: Скрыть вывод команды
:param warn: Вывести stderr
:param cwd: Перейти в папку при выполнении команды
"""


class Host:
"""
Локальный хост, работает по локальному терминалу
:param context: Контекст хоста
Базовый класс для хостов
"""

def __init__(self, **context: typing.Any) -> None:
"""
:param context: Контекст хоста
"""

self.addr = ""
self.context = context
self.context['host'] = self

@abc.abstractmethod
def connect(self) -> Connection:
"""
Создать конект с хостом
"""
...

def __str__(self) -> str:
Expand Down
3 changes: 3 additions & 0 deletions carnival/hosts/local.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ class LocalHost(base.Host):
"""

def __init__(self, **context: typing.Any) -> None:
"""
:param context: Контекст хоста
"""
super().__init__(**context)
self.addr = "local"

Expand Down
2 changes: 1 addition & 1 deletion carnival/hosts/ssh.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def run(

class SshHost(base.Host):
"""
Локальный хост, работает по локальному терминалу
SSH хост
"""

def __init__(
Expand Down
24 changes: 10 additions & 14 deletions carnival/step.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,20 @@

class Step:
"""
Объект, предназначенный для выполнения группы комманд с какой-то целью.
Вызывается из класса `carnival.Task` для выполнения комманд (`carnival.cmd`) на определенных хостах.
Объект, предназначенный для выполнения группы команд с какой-то целью.
Вызывается из класса `carnival.Task` для выполнения команд (`carnival.cmd`) на определенных хостах.
Может требовать наличие определенных контекстных переменных для работы, указав их в аргументах метода `run`.
Может вернуть значение для дальнейшего использования.
Может требовать наличие определенных контекстных переменных для работы, указав их в аргументах конструктора,
а в задаче (Task) передать нужные аргументы в конструктор.
В следующем примере переменная `disk_name` будет передана в run, а `install` пропущена.
Может вернуть значение для дальнейшего использования.
>>> host = Host(
>>> # Адрес
>>> "1.2.3.4",
>>>
>>> # Контекст хоста
>>> disk_name="/dev/sda1", install=['nginx', 'htop', ]
>>> )
>>> ...
>>> class DiskUsage(Step):
>>> def run(self, disk_name: str):
>>> def __init__(self, disk_name: str):
>>> self.disk_name = disk_name
>>>
>>> def run(self, c: Connection):
>>> ...
"""
Expand All @@ -51,7 +47,7 @@ def validate(self, c: "Connection") -> None:
@abc.abstractmethod
def run(self, c: "Connection") -> typing.Any:
"""
Метод который нужно определить для выполнения комманд
Метод который нужно определить для выполнения команд
:param c: Соединение с хостом для выполнения шага
"""
Expand Down
12 changes: 6 additions & 6 deletions carnival/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ class TaskBase:
module_name:
>>> class CheckDiskSpace(TaskBase):
>>> help = "Print server root disk usage"
>>> help = "Print server root disk usage"
>>>
>>> def run(self, disk: str = "/") -> None:
>>> with connection.SetConnection(my_server):
>>> cmd.cli.run(f"df -h {disk}", hide=False)
>>> def run(self) -> None:
>>> with my_server.connect() as c:
>>> cmd.cli.run(f"df -h /", hide=False)
"""

Expand Down Expand Up @@ -82,15 +82,15 @@ def run(self) -> None:
raise NotImplementedError


class StepsTask(abc.ABC, TaskBase):
class Task(abc.ABC, TaskBase):
"""
Запустить шаги `steps` на хостах `hosts`
>>> class InstallPackages(StepsTask):
>>> help = "Install packages"
>>>
>>> hosts = [my_server]
>>> steps = [InstallStep()]
>>> steps = [InstallStep(my_server.context['packages'])]
"""

Expand Down
6 changes: 6 additions & 0 deletions carnival/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ def log(message: str, host: typing.Optional[Host], file: typing.Optional[_Writer


def envvar(varname: str) -> str:
"""
Получить переменную из окружения
Замена context_ref для carnival v3
:raises: ValueError если переменной в окружении нет
"""

if varname not in os.environ:
raise ValueError(f"{varname} is not persent in environment")

Expand Down
4 changes: 2 additions & 2 deletions carnival_tasks_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import typing

import os
from carnival import cmd, TaskBase, SshHost, Step, Host, StepsTask, Connection
from carnival import cmd, TaskBase, SshHost, Step, Host, Task, Connection
from carnival.exceptions import StepValidationError


Expand Down Expand Up @@ -39,7 +39,7 @@ def run(self, c: Connection) -> None:
cmd.cli.run(c, f"apt-get install -y {self.packages}")


class InstallPackages(StepsTask):
class InstallPackages(Task):
help = "Install packages"

hosts = [my_server]
Expand Down
2 changes: 1 addition & 1 deletion docs/source/cli.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
##################################
Интерфейс коммандной строки (cli)
Интерфейс командной строки (cli)
##################################

.. automodule:: carnival.cli
Expand Down
Loading

0 comments on commit 7b33ec0

Please sign in to comment.