-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 4d3a653
Showing
10 changed files
with
402 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
name: Package Application with Pyinstaller | ||
|
||
on: | ||
push: | ||
tags: | ||
- "*" | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- uses: actions/checkout@v2 | ||
|
||
- name: Package Application | ||
uses: JackMcKew/[email protected] | ||
with: | ||
path: src | ||
|
||
- uses: actions/upload-artifact@v2 | ||
with: | ||
name: name-of-artifact | ||
path: src/dist/linux |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
/old | ||
/build | ||
/dist | ||
*.spec | ||
Pipfile | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
{ | ||
"recommendations": [ | ||
"dbaeumer.vscode-eslint", | ||
"esbenp.prettier-vscode", | ||
"editorconfig.editorconfig", | ||
"vue.volar", | ||
"wayou.vscode-todo-highlight" | ||
], | ||
"unwantedRecommendations": [ | ||
"octref.vetur", | ||
"hookyqr.beautify", | ||
"dbaeumer.jshint", | ||
"ms-vscode.vscode-typescript-tslint-plugin" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
{ | ||
"editor.bracketPairColorization.enabled": true, | ||
"editor.guides.bracketPairs": true, | ||
"editor.formatOnSave": true, | ||
"editor.defaultFormatter": "esbenp.prettier-vscode", | ||
"editor.codeActionsOnSave": ["source.fixAll.eslint"], | ||
"eslint.validate": ["javascript", "javascriptreact", "typescript", "vue"], | ||
"typescript.tsdk": "node_modules/typescript/lib", | ||
"[python]": { | ||
"editor.defaultFormatter": "ms-python.black-formatter", | ||
"editor.formatOnSave": true, | ||
"editor.codeActionsOnSave": { | ||
"source.organizeImports": "never" | ||
} | ||
}, | ||
"[makefile]": { | ||
"editor.insertSpaces": false, | ||
"editor.detectIndentation": false | ||
}, | ||
"cSpell.words": ["KEYCLOAK"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
default: dist/dcc/dcc | ||
|
||
clean: | ||
@rm -rf build dist | ||
|
||
dist/dcc/dcc: clean | ||
@pyinstaller dcc.py | ||
|
||
run: | ||
@dist/dcc/dcc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
import click | ||
import sh | ||
from sys import argv | ||
from helpers import TableOutput as T, Message as M, Executor as E | ||
import json | ||
from sys import exit | ||
from os.path import isfile, isdir | ||
from os import environ, getcwd | ||
from dotenv import load_dotenv | ||
|
||
docker = sh.Command("docker") | ||
bash = sh.Command("bash") | ||
|
||
|
||
def __bake_command(command_line: str): | ||
return (command_line).split() | ||
|
||
|
||
def __handle_output(output: str) -> str: | ||
# We remove the last \n | ||
return output.rstrip("\n") | ||
|
||
|
||
def __containers(filter: str = None): | ||
_filter = "" | ||
if filter: | ||
_filter = f"--filter name={filter}" | ||
cmd = docker.bake(*__bake_command("ps -a %s --format {{.Names}}" % _filter)) | ||
return __handle_output(cmd()).split("\n") | ||
|
||
|
||
def __inspect(filter: str = None): | ||
inspection = [] | ||
for cont in __containers(filter): | ||
cmd = docker.bake(*__bake_command("inspect %s" % cont)) | ||
inspection.append(json.loads(__handle_output(cmd()))[0]) | ||
return inspection | ||
|
||
|
||
def __prepare_compose_command(docker_arguments): | ||
if not isfile("docker-compose.yml"): | ||
M.error("There is no docker-compose.yml file in this directory!") | ||
exit(1) | ||
dcc_env = None | ||
env = { | ||
"GIT_VERSION": "?.?.?", | ||
"GIT_BRANCH": "N/A", | ||
"GIT_LASTCOMMITDATE": "N/A", | ||
"GIT_COMMITHASH": "N/A", | ||
"UID": 0, | ||
"GID": 0, | ||
"UNAME": "root", | ||
} | ||
if isfile(".env"): | ||
load_dotenv(".env") | ||
dcc_env = environ.get("DCC_ENV") | ||
M.debug(f"Running DCC environment {dcc_env}.") | ||
else: | ||
M.warn(f"No .env file found in current directory: {getcwd()}") | ||
if isdir(".git"): | ||
if E.success("git rev-parse --is-inside-work-tree"): | ||
env["GIT_VERSION"] = E.run("git describe --always") | ||
env["GIT_BRANCH"] = E.run("git rev-parse --abbrev-ref HEAD") | ||
env["GIT_LASTCOMMITDATE"] = E.run("git log -1 --format=%cI") | ||
env["GIT_COMMITHASH"] = E.run("git rev-parse HEAD") | ||
M.debug("Git repository detected.") | ||
else: | ||
M.warn("Not a git repository.") | ||
|
||
env["UID"] = E.run("id -u") | ||
env["GID"] = E.run("id -g") | ||
env["UNAME"] = E.run("whoami") | ||
environ.update(env) | ||
|
||
docker_files = ["docker-compose.yml"] | ||
if dcc_env: | ||
docker_files.append(f"docker-compose.{dcc_env}.yml") | ||
if isfile("docker-compose.override.yml"): | ||
docker_files.append("docker-compose.override.yml") | ||
command = ( | ||
f"docker compose -f {' -f '.join(docker_files)} {' '.join(docker_arguments)}" | ||
) | ||
M.debug(f"Command: {command}") | ||
return command | ||
|
||
|
||
def __execute_compose_command(command: str): | ||
try: | ||
bash("-c", command, _fg=True) | ||
except Exception: | ||
M.error(f"Error executing command '{command}'.") | ||
# traceback.print_exc() | ||
|
||
|
||
@click.command() | ||
@click.argument("filter", required=False) | ||
def ls(filter: str = None): | ||
_filter = "" | ||
if filter: | ||
_filter = f"--filter name={filter}" | ||
cmd = docker.bake( | ||
*__bake_command( | ||
"ps -a %s -a --format {{.Names}}#{{.Status}}#{{.Image}}" % _filter | ||
) | ||
) | ||
output = __handle_output(cmd()) | ||
T.out(output, headers=("Name", "Status", "Image")) | ||
|
||
|
||
@click.command() | ||
@click.argument("filter", required=False) | ||
def po(filter: str = None): | ||
output = "" | ||
for cont in __containers(filter): | ||
cmd = docker.bake(*__bake_command("port %s" % cont)) | ||
sep = "\n" | ||
output += f"{cont}#{', '.join(__handle_output(cmd()).split(sep))}\n" | ||
T.out(__handle_output(output), headers=("Name", "Ports")) | ||
|
||
|
||
@click.command() | ||
@click.argument("filter", required=False) | ||
def rp(filter: str = None): | ||
output = "" | ||
for i in __inspect(filter): | ||
output += ( | ||
f"{i['Name'].lstrip('/')}#{i['HostConfig']['RestartPolicy']['Name']}\n" | ||
) | ||
T.out(__handle_output(output), headers=("Name", "Restart")) | ||
|
||
|
||
@click.command() | ||
@click.argument("container") | ||
def sh(container: str): | ||
__execute_compose_command( | ||
__prepare_compose_command(["exec", container, "/usr/bin/env bash"]) | ||
) | ||
|
||
|
||
def dcc(docker_arguments): | ||
__execute_compose_command(__prepare_compose_command(docker_arguments)) | ||
|
||
|
||
if __name__ == "__main__": | ||
if len(argv) < 2: | ||
M.error("Please specify a command.") | ||
exit(1) | ||
|
||
if argv[1] in globals().keys(): | ||
globals()[argv[1]](argv[2:]) | ||
else: | ||
dcc(argv[1:]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
""" | ||
Helpers | ||
==================================== | ||
Helper classes and functions | ||
""" | ||
|
||
import os | ||
import shlex | ||
from subprocess import run | ||
from enum import Enum | ||
from yachalk import chalk | ||
from rich.console import Console | ||
from rich.table import Table | ||
|
||
|
||
class ReturnCode(Enum): | ||
OK = 0 | ||
|
||
|
||
class Executor: | ||
""" | ||
Class to execute shell commands | ||
""" | ||
|
||
@classmethod | ||
def success(cls, command: str, env: dict = None) -> bool: | ||
ret, _ = cls.__run(command, env=env) | ||
return ret == ReturnCode.OK.value | ||
|
||
@classmethod | ||
def run(cls, command: str, env: dict = None) -> str: | ||
_, output = cls.__run(command, env=env) | ||
return cls.__handle_output(output) | ||
|
||
@classmethod | ||
def __run(cls, command: str, env: dict = None) -> tuple[int, str]: | ||
""" | ||
Runs a shell command with the default environment. | ||
If env is given it is _UPDATED_ to the default environment. | ||
""" | ||
_env = os.environ.copy() | ||
if env: | ||
_env.update(env) | ||
p = run(shlex.split(command), capture_output=True, env=_env) | ||
return p.returncode, cls.__handle_output(p.stdout.decode()) | ||
|
||
@classmethod | ||
def __handle_output(cls, output: str) -> str: | ||
# We remove the last \n | ||
return output.rstrip("\n") | ||
|
||
|
||
class Message: | ||
""" | ||
Class to output colored messages to the console | ||
""" | ||
|
||
@classmethod | ||
def info(cls, message): | ||
print(chalk.green_bright.bold(message)) | ||
|
||
@classmethod | ||
def warn(cls, message): | ||
print(chalk.yellow_bright.bold(message)) | ||
|
||
@classmethod | ||
def error(cls, message): | ||
print(chalk.red_bright.bold(message)) | ||
|
||
@classmethod | ||
def debug(cls, message): | ||
print(chalk.blue_bright.bold(message)) | ||
|
||
|
||
class TableOutput: | ||
""" | ||
Class to output text in table format | ||
""" | ||
|
||
console = Console() | ||
|
||
@classmethod | ||
def out( | ||
cls, | ||
data: str | list, | ||
sep: str = "#", | ||
headers: tuple[str] = None, | ||
show_lines=False, | ||
): | ||
table = Table( | ||
show_header=(headers is not None), show_lines=show_lines, show_edge=False | ||
) | ||
if headers: | ||
for header in headers: | ||
table.add_column(header) | ||
|
||
if isinstance(data, str): | ||
data = data.split("\n") | ||
|
||
for line in data: | ||
if isinstance(line, str): | ||
table.add_row(*line.split(sep)) | ||
elif isinstance(line, list): | ||
table.add_row(*line) | ||
|
||
cls.console.print(table) | ||
|
||
|
||
#################### | ||
# OLD CODE | ||
#################### | ||
|
||
|
||
# class Interactive(): | ||
# """ | ||
# Execute a command interactively with pseudo terminal | ||
# found at https://stackoverflow.com/questions/41542960/run-interactive-bash-with-popen-and-a-dedicated-tty-python | ||
# """ | ||
|
||
# def __init__(self, command: str = '/bin/bash', env: dict = None): | ||
# self.command = command | ||
# self.env = os.environ.copy() | ||
# if env: | ||
# self.env.update(env) | ||
# self.process = None | ||
|
||
# def run(self): | ||
# old_tty = termios.tcgetattr(sys.stdin) | ||
# tty.setraw(sys.stdin.fileno()) | ||
|
||
# master, slave = pty.openpty() | ||
|
||
# try: | ||
# self.process = Popen( | ||
# shlex.split(self.command), | ||
# preexec_fn=os.setsid, | ||
# stdin=slave, | ||
# stdout=slave, | ||
# stderr=slave, | ||
# env=self.env) | ||
|
||
# while True: | ||
# r, _, _ = select.select([sys.stdin, master], [], []) | ||
# if sys.stdin in r: | ||
# d = os.read(sys.stdin.fileno(), 10240) | ||
# os.write(master, d) | ||
# elif master in r: | ||
# o = os.read(master, 10240) | ||
# if o: | ||
# os.write(sys.stdout.fileno(), o) | ||
|
||
# if self.process.poll() is not None: | ||
# sys.stdout.flush() | ||
# break | ||
# else: | ||
# sleep(0.1) | ||
|
||
# finally: | ||
# # restore tty settings back | ||
# termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_tty) |
Oops, something went wrong.