Skip to content

Commit

Permalink
folowing long command outputs
Browse files Browse the repository at this point in the history
  • Loading branch information
a1fred committed Dec 6, 2021
1 parent f7f7b30 commit 9db3e15
Show file tree
Hide file tree
Showing 14 changed files with 440 additions and 230 deletions.
5 changes: 3 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.steps import Step, InlineStep
from carnival.role import Role, SingleRole
from carnival.hosts.local import LocalHost, localhost_connection
from carnival.hosts.local import LocalHost, localhost_connection, localhost
from carnival.hosts.ssh import SshHost
from carnival.task import TaskBase, Task
from carnival import internal_tasks
Expand Down Expand Up @@ -36,7 +36,8 @@

__all__ = [
'Step', 'InlineStep',
'SshHost', 'LocalHost', 'localhost_connection', 'Host', 'Connection', 'Result',
'SshHost', 'LocalHost', 'localhost', 'localhost_connection',
'Host', 'Connection', 'Result',
'Role', 'SingleRole',
'TaskBase', 'Task',
'internal_tasks',
Expand Down
54 changes: 33 additions & 21 deletions carnival/contrib/steps/apt.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,21 @@
from carnival.steps import validators


class Update(Step):
"""
apt-get update
"""

def get_validators(self) -> typing.List[validators.StepValidatorBase]:
return [
validators.CommandRequiredValidator('apt-get'),
]

def run(self, c: Connection) -> None:
c.run("DEBIAN_FRONTEND=noninteractive sudo apt-get update", hide=True)
print(f"{S.BRIGHT}apt packages list{S.RESET_ALL}: {F.YELLOW}updated{F.RESET}")


class GetPackageVersions(Step):
"""
Получить список доступных версий пакета
Expand Down Expand Up @@ -102,11 +117,10 @@ class ForceInstall(Step):
Установить пакет без проверки установлен ли он
"""

def __init__(self, pkgname: str, version: typing.Optional[str] = None, update: bool = False, hide: bool = False):
def __init__(self, pkgname: str, version: typing.Optional[str] = None, update: bool = False):
self.pkgname = pkgname
self.version = version
self.update = update
self.hide = hide

def get_validators(self) -> typing.List[validators.StepValidatorBase]:
return [
Expand All @@ -119,9 +133,9 @@ def run(self, c: Connection) -> None:
pkgname = f"{self.pkgname}={self.version}"

if self.update:
c.run("DEBIAN_FRONTEND=noninteractive sudo apt-get update", hide=self.hide)
Update().run(c)

c.run(f"DEBIAN_FRONTEND=noninteractive sudo apt-get install -y {pkgname}", hide=self.hide)
c.run(f"DEBIAN_FRONTEND=noninteractive sudo apt-get install -y {pkgname}")


class Install(Step):
Expand All @@ -133,23 +147,20 @@ def __init__(
pkgname: str,
version: typing.Optional[str] = None,
update: bool = True,
hide: bool = False,
) -> None:
"""
:param pkgname: название пакета
:param version: версия
:param update: запустить apt-get update перед установкой
:param hide: скрыть вывод этапов
"""
self.pkgname = pkgname
self.version = version
self.update = update
self.hide = hide

self.is_package_installed = IsPackageInstalled(pkgname=self.pkgname, version=self.version)
self.force_install = ForceInstall(
pkgname=self.pkgname, version=self.version,
update=self.update, hide=self.hide
update=self.update,
)

def get_validators(self) -> typing.List[validators.StepValidatorBase]:
Expand All @@ -168,7 +179,7 @@ def run(self, c: Connection) -> bool:
return False
return False

ForceInstall(pkgname=self.pkgname, version=self.version, update=self.update, hide=self.hide).run(c=c)
ForceInstall(pkgname=self.pkgname, version=self.version, update=self.update).run(c=c)
print(f"{S.BRIGHT}{self.pkgname}{S.RESET_ALL}: {F.YELLOW}installed{F.RESET}")
return True

Expand All @@ -178,16 +189,17 @@ class InstallMultiple(Step):
Установить несколько пакетов, если они не установлены
"""

def __init__(self, pkg_names: typing.List[str], update: bool = True, hide: bool = False) -> None:
def __init__(self, pkg_names: typing.List[str], update: bool = True) -> None:
"""
:param pkg_names: список пакетов которые нужно установить
:param update: запустить apt-get update перед установкой
:param hide: скрыть вывод этапов
"""

self.pkg_names = pkg_names
self.update = update
self.hide = hide

def get_name(self) -> str:
return f"{super().get_name()}(pkg_names={self.pkg_names})"

def get_validators(self) -> typing.List[validators.StepValidatorBase]:
return [
Expand All @@ -202,10 +214,10 @@ def run(self, c: Connection) -> bool:
return False

if self.update:
c.run("DEBIAN_FRONTEND=noninteractive sudo apt-get update", hide=self.hide)
c.run("DEBIAN_FRONTEND=noninteractive sudo apt-get update", hide=True)

for pkg in self.pkg_names:
Install(pkgname=pkg, update=False, hide=self.hide).run(c=c)
Install(pkgname=pkg, update=False).run(c=c)
return True


Expand All @@ -214,13 +226,11 @@ class Remove(Step):
Удалить пакет
"""

def __init__(self, pkg_names: typing.List[str], hide: bool = False) -> None:
def __init__(self, pkg_names: typing.List[str]) -> None:
"""
:param pkg_names: список пакетов которые нужно удалить
:param hide: скрыть вывод этапов
"""
self.pkg_names = pkg_names
self.hide = hide

def get_validators(self) -> typing.List[validators.StepValidatorBase]:
return [
Expand All @@ -232,7 +242,9 @@ def get_validators(self) -> typing.List[validators.StepValidatorBase]:
]

def run(self, c: Connection) -> None:
c.run(
f"DEBIAN_FRONTEND=noninteractive sudo apt-get remove --auto-remove -y {' '.join(self.pkg_names)}",
hide=self.hide
)
for pkg in self.pkg_names:
if IsPackageInstalled(pkg).run(c):
c.run(
f"DEBIAN_FRONTEND=noninteractive sudo apt-get remove --auto-remove -y {' '.join(self.pkg_names)}",
)
print(f"{S.BRIGHT}{pkg}{S.RESET_ALL}: {F.YELLOW}removed{F.RESET}")
20 changes: 0 additions & 20 deletions carnival/contrib/steps/cli.py

This file was deleted.

49 changes: 30 additions & 19 deletions carnival/contrib/steps/docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,45 @@
from carnival import Connection
from carnival.steps import validators, shortcuts

from carnival.contrib.steps import apt, systemd
from carnival.contrib.steps import apt, systemd, transfer


class CeInstallUbuntu(Step):
"""
Установить docker на ubuntu
https://docs.docker.com/engine/install/ubuntu/
"""
def __init__(self, docker_version: typing.Optional[str] = None) -> None:
def __init__(self, version: typing.Optional[str] = None) -> None:
"""
:param docker_version: версия docker-ce
:param version: версия docker-ce
"""
self.docker_version = docker_version
self.version = version

def get_name(self) -> str:
return f"{super().get_name()}(version={self.version or 'any'})"

def get_validators(self) -> typing.List[validators.StepValidatorBase]:
return [
validators.CommandRequiredValidator("apt-get"),
validators.CommandRequiredValidator("curl"),
]

def run(self, c: Connection) -> None:
pkgname = "docker-ce"
if apt.IsPackageInstalled(pkgname=pkgname, version=self.docker_version).run(c=c):
print(f"{S.BRIGHT}docker-ce{S.RESET_ALL}: {F.GREEN}already installed{F.RESET}")
if apt.IsPackageInstalled(pkgname=pkgname, version=self.version).run(c=c):
return

print(f"Installing {pkgname}...")
c.run("sudo apt-get update")
c.run("sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common")
c.run("curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -")
c.run('sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"') # noqa:E501
apt.InstallMultiple(
["apt-transport-https", "ca-certificates", "curl", "software-properties-common"],
update=True
).run(c)

apt.ForceInstall(pkgname=pkgname, version=self.docker_version, update=True, hide=True).run(c=c)
print(f"{S.BRIGHT}docker-ce{S.RESET_ALL}: {F.YELLOW}installed{F.RESET}")
c.run("curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -", hide=True)
c.run(
'add-apt-repository -y "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"', # noqa:E501
hide=True
)
apt.Update().run(c)
apt.Install(pkgname, version=self.version, update=False).run(c)


class ComposeInstall(Step):
Expand All @@ -65,7 +71,6 @@ def get_validators(self) -> typing.List[validators.StepValidatorBase]:

def run(self, c: Connection) -> None:
if shortcuts.is_cmd_exist(c, "docker-compose"):
print(f"{S.BRIGHT}docker-compose{S.RESET_ALL}: {F.GREEN}already installed{F.RESET}")
return

link = f"https://github.com/docker/compose/releases/download/{self.version}/docker-compose-`uname -s`-`uname -m`" # noqa:501
Expand All @@ -84,7 +89,7 @@ def __init__(
docker_image_path: str,
dest_dir: str = '/tmp/',
rm_after_load: bool = False,
rsync_opts: typing.Optional[typing.Dict[str, typing.Any]] = None,
rsync_opts: typing.Optional[str] = None,
):
"""
:param docker_image_path: tar-образ docker
Expand All @@ -97,7 +102,13 @@ def __init__(
self.docker_image_path = docker_image_path
self.dest_dir = dest_dir
self.rm_after_load = rm_after_load
self.rsync_opts = rsync_opts or {}
self.rsync_opts = rsync_opts

self.rsync_step = transfer.Rsync(
src_dir_or_file=self.docker_image_path,
dst_dir=self.dest_dir,
rsync_opts=self.rsync_opts
)

def get_name(self) -> str:
return f"{super().get_name()}(src={self.docker_image_path}, dst={self.dest_dir})"
Expand All @@ -106,13 +117,13 @@ def get_validators(self) -> typing.List[validators.StepValidatorBase]:
return [
validators.CommandRequiredValidator("systemctl"),
validators.CommandRequiredValidator("docker"),
*self.rsync_step.get_validators(),
]

def run(self, c: Connection) -> None:
image_file_name = os.path.basename(self.docker_image_path)
systemd.Start("docker").run(c=c)

shortcuts.rsync(c.host, self.docker_image_path, self.dest_dir, **self.rsync_opts)
self.rsync_step.run(c)
c.run(f"cd {self.dest_dir}; docker load -i {image_file_name}")

if self.rm_after_load:
Expand Down
31 changes: 25 additions & 6 deletions carnival/contrib/steps/docker_compose.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,33 @@ class UploadService(Step):
"""

def __init__(
self,
app_dir: str,
self,
app_dir: str,

template_files: typing.List[typing.Union[str, typing.Tuple[str, str]]],
template_context: typing.Dict[str, typing.Any],
static_files: typing.List[typing.Union[str, typing.Tuple[str, str]]],
template_files: typing.List[typing.Union[str, typing.Tuple[str, str]]],
template_context: typing.Dict[str, typing.Any],
):
"""
:param app_dir: Путь до папки назначения
:param static_files: Список файлов. Может быть списком файлов или кортежей (src, dst)
:param template_files: Список jinja2-шаблонов. Может быть списком файлов или кортежей (src, dst)
:param template_context: Контекст шаблонов, один на все шаблоны
"""
self.app_dir = app_dir

self.static_files: typing.List[typing.Tuple[str, str]] = []
for dest in static_files:
if isinstance(dest, str):
file_path = dest
dest_fname = os.path.basename(file_path)
elif isinstance(dest, tuple):
file_path, dest_fname = dest
else:
raise ValueError(f"Cant parse static file definition: {dest}")

self.static_files.append((file_path, dest_fname))

self.template_files: typing.List[typing.Tuple[str, str]] = []
for dest in template_files:
if isinstance(dest, str):
Expand All @@ -36,13 +50,18 @@ def __init__(
elif isinstance(dest, tuple):
template_path, dest_fname = dest
else:
raise ValueError(f"Cant parse template_file definition: {dest}")
raise ValueError(f"Cant parse template file definition: {dest}")

self.template_files.append((template_path, dest_fname))

self.template_context = template_context

self.transfer_chain = []
self.transfer_chain: typing.List[Step] = []
for file_path, dest_fname in self.static_files:
self.transfer_chain.append(transfer.PutFile(
local_path=file_path,
remote_path=os.path.join(self.app_dir, dest_fname),
))
for template_path, dest_fname in self.template_files:
self.transfer_chain.append(transfer.PutTemplate(
template_path=template_path,
Expand Down
Loading

0 comments on commit 9db3e15

Please sign in to comment.