Merge branch '23-make-project-release-ready' into 'master'
Resolve "Make project release ready" Closes #23 See merge request icaotix/linux-tools!22
This commit is contained in:
commit
4b384d27a9
9
README.md
Normal file
9
README.md
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# About
|
||||||
|
|
||||||
|
# How to start a dev env
|
||||||
|
|
||||||
|
```shell script
|
||||||
|
docker run --rm -it -v $(pwd):/data/linux-tools ubuntu bash
|
||||||
|
```
|
||||||
|
|
||||||
|
# Contributing
|
@ -1,5 +1,10 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
if [[ $EUID -ne 0 ]]; then
|
||||||
|
echo "This script must be run as root"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||||
cd "$DIR" || exit
|
cd "$DIR" || exit
|
||||||
FILE=./your_system_information.txt
|
FILE=./your_system_information.txt
|
||||||
@ -8,7 +13,6 @@ if [ ! -f "$FILE" ]; then
|
|||||||
echo "Preparing your system for the first run"
|
echo "Preparing your system for the first run"
|
||||||
apt-get update -y && apt-get upgrade -y
|
apt-get update -y && apt-get upgrade -y
|
||||||
apt-get install curl screenfetch python3.7 python3-pip -y
|
apt-get install curl screenfetch python3.7 python3-pip -y
|
||||||
pip3 install setuptools wheel regex
|
|
||||||
pip3 install -r requirements.txt
|
pip3 install -r requirements.txt
|
||||||
python3 main.py helloworld
|
python3 main.py helloworld
|
||||||
else
|
else
|
||||||
|
36
main.py
36
main.py
@ -1,25 +1,25 @@
|
|||||||
import fire
|
import fire
|
||||||
|
|
||||||
from modules.helloworld.HelloWorld import HelloWorld
|
import modules.bashrc as bashrc
|
||||||
from modules.install.ToolsInstaller import ToolsInstaller
|
import modules.fail2ban as fail2ban
|
||||||
from modules.swap.SwapModule import SwapModule
|
import modules.hacker as hacker
|
||||||
from modules.systemupdate.Systemupdate import Systemupdate
|
import modules.helloworld as helloworld
|
||||||
from modules.vim.VimModule import VimModule
|
import modules.install as install
|
||||||
from modules.teamspeak.Teamspeak import Teamspeak
|
import modules.swap as swap
|
||||||
from modules.hacker.Hacker import Hacker
|
import modules.systemupdate as update
|
||||||
import modules.fail2ban.Fail2BanModule as fail2ban
|
import modules.teamspeak as teamspeak
|
||||||
from modules.bashrc.BashrcModule import BashrcModule
|
import modules.vim as vim
|
||||||
|
|
||||||
modules = {
|
modules = {
|
||||||
"helloworld": HelloWorld().run,
|
"bashrc": bashrc.functions,
|
||||||
"install": ToolsInstaller,
|
"fail2ban": fail2ban.functions,
|
||||||
"swap": SwapModule().run,
|
"hacker": hacker.functions,
|
||||||
"update": Systemupdate().run,
|
"helloworld": helloworld.functions,
|
||||||
"vim": VimModule().run,
|
"install": install.functions,
|
||||||
"teamspeak": Teamspeak,
|
"swap": swap.functions,
|
||||||
"hacker": Hacker,
|
"update": update.functions,
|
||||||
"fail2ban": fail2ban.run,
|
"teamspeak": teamspeak.functions,
|
||||||
"bashrc": BashrcModule().run
|
"vim": vim.functions,
|
||||||
}
|
}
|
||||||
|
|
||||||
fire.Fire(modules)
|
fire.Fire(modules)
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
from PyInquirer import prompt
|
|
||||||
import os
|
|
||||||
from shutil import copyfile
|
|
||||||
from print_helpers import print_gr, print_fail
|
|
||||||
|
|
||||||
|
|
||||||
class BashrcModule:
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
bashrc_path = os.path.join(os.path.expanduser('~'), ".bashrc")
|
|
||||||
bashrc_exists = os.path.exists(bashrc_path)
|
|
||||||
|
|
||||||
if bashrc_exists:
|
|
||||||
print_gr(f"Found .bashrc in {bashrc_path}")
|
|
||||||
ask_to_keep = {
|
|
||||||
'type': 'confirm',
|
|
||||||
'message': 'Do you want to overwrite the existing .bashrc?',
|
|
||||||
'name': 'overwrite',
|
|
||||||
'default': False,
|
|
||||||
}
|
|
||||||
if not prompt(ask_to_keep)['overwrite']:
|
|
||||||
print_fail("Stopping")
|
|
||||||
return
|
|
||||||
|
|
||||||
copyfile("./modules/bashrc/bashrc_default", bashrc_path)
|
|
||||||
print_gr("Successfully overwritten .bashrc!") if bashrc_exists else print_gr(f"Successfully created .bashrc!")
|
|
31
modules/bashrc/__init__.py
Normal file
31
modules/bashrc/__init__.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import os
|
||||||
|
from shutil import copyfile
|
||||||
|
|
||||||
|
from PyInquirer import prompt
|
||||||
|
|
||||||
|
from print_helpers import print_gr, print_fail
|
||||||
|
|
||||||
|
|
||||||
|
def run():
|
||||||
|
bashrc_path = os.path.join(os.path.expanduser('~'), ".bashrc")
|
||||||
|
bashrc_exists = os.path.exists(bashrc_path)
|
||||||
|
|
||||||
|
if bashrc_exists:
|
||||||
|
print_gr(f"Found .bashrc in {bashrc_path}")
|
||||||
|
ask_to_keep = {
|
||||||
|
'type': 'confirm',
|
||||||
|
'message': 'Do you want to overwrite the existing .bashrc?',
|
||||||
|
'name': 'overwrite',
|
||||||
|
'default': False,
|
||||||
|
}
|
||||||
|
if not prompt(ask_to_keep)['overwrite']:
|
||||||
|
print_fail("Stopping")
|
||||||
|
return
|
||||||
|
|
||||||
|
copyfile("./modules/bashrc/bashrc_default", bashrc_path)
|
||||||
|
print_gr("Successfully overwritten .bashrc!") if bashrc_exists else print_gr(f"Successfully created .bashrc!")
|
||||||
|
|
||||||
|
|
||||||
|
functions = {
|
||||||
|
"run": run,
|
||||||
|
}
|
@ -1,15 +1,22 @@
|
|||||||
import subprocess
|
import subprocess
|
||||||
from shutil import copyfile
|
from shutil import copyfile
|
||||||
|
|
||||||
|
from print_helpers import print_bold
|
||||||
|
|
||||||
|
|
||||||
def run():
|
def run():
|
||||||
subprocess.call("apt install fail2ban -y", shell=True)
|
subprocess.call("apt install fail2ban -y", shell=True)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
ufw_is_installed = subprocess.check_output("which ufw", shell=True).decode().strip()
|
ufw_is_installed = subprocess.check_output("which ufw", shell=True).decode().strip()
|
||||||
print(f"ufw is already installed in {ufw_is_installed}")
|
print_bold(f"ufw is already installed in {ufw_is_installed}")
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
subprocess.call("sudo apt install ufw -y", shell=True)
|
subprocess.call("sudo apt install ufw -y", shell=True)
|
||||||
subprocess.call("ufw allow ssh && ufw enable", shell=True)
|
subprocess.call("ufw allow ssh && ufw enable", shell=True)
|
||||||
|
|
||||||
copyfile("./modules/fail2ban/jail.local", "/etc/fail2ban/jail.local")
|
copyfile("./modules/fail2ban/jail.local", "/etc/fail2ban/jail.local")
|
||||||
|
|
||||||
|
|
||||||
|
functions = {
|
||||||
|
"run": run
|
||||||
|
}
|
@ -1,29 +0,0 @@
|
|||||||
import subprocess
|
|
||||||
from os import path
|
|
||||||
import os
|
|
||||||
import random
|
|
||||||
|
|
||||||
|
|
||||||
class Hacker:
|
|
||||||
|
|
||||||
def run_bash(self):
|
|
||||||
try:
|
|
||||||
subprocess.run("bash hacker.sh", shell=True, cwd=path.dirname(__file__))
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def run_py(self):
|
|
||||||
columns = int(os.popen('stty size', 'r').read().split()[1]) # length of current line
|
|
||||||
try:
|
|
||||||
while True:
|
|
||||||
num_to_show = random.randint(0, 1)
|
|
||||||
count = random.randint(3, columns // 20)
|
|
||||||
hacker = " " * columns
|
|
||||||
for i in range(count):
|
|
||||||
pos = random.randint(0, columns)
|
|
||||||
hacker = hacker[:pos] + str(num_to_show) + hacker[pos+1:]
|
|
||||||
print("\033[92m" + hacker)
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
print(columns)
|
|
||||||
print("Finished")
|
|
||||||
print("\033[0m")
|
|
35
modules/hacker/__init__.py
Normal file
35
modules/hacker/__init__.py
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import os
|
||||||
|
import random
|
||||||
|
import subprocess
|
||||||
|
from os import path
|
||||||
|
|
||||||
|
from print_helpers import print_gr
|
||||||
|
|
||||||
|
|
||||||
|
def run_bash():
|
||||||
|
try:
|
||||||
|
subprocess.run("bash hacker.sh", shell=True, cwd=path.dirname(__file__))
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def run_py():
|
||||||
|
columns = int(os.popen('stty size', 'r').read().split()[1]) # length of current line
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
num_to_show = random.randint(0, 1)
|
||||||
|
count = random.randint(3, columns // 20)
|
||||||
|
hacker = " " * columns
|
||||||
|
for i in range(count):
|
||||||
|
pos = random.randint(0, columns)
|
||||||
|
hacker = hacker[:pos] + str(num_to_show) + hacker[pos + 1:]
|
||||||
|
print_gr(hacker)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print(columns)
|
||||||
|
print_gr("Finished")
|
||||||
|
|
||||||
|
|
||||||
|
functions = {
|
||||||
|
"runBash": run_bash,
|
||||||
|
"runPy": run_py
|
||||||
|
}
|
@ -1,13 +0,0 @@
|
|||||||
import subprocess
|
|
||||||
|
|
||||||
|
|
||||||
class HelloWorld:
|
|
||||||
"""docstring for SampleModule."""
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
print("This shows that your installation is working correctly.")
|
|
||||||
subprocess.call("screenfetch", shell=True)
|
|
||||||
print("You can now start using the tool.")
|
|
||||||
output = subprocess.check_output("cat /etc/*-release", shell=True).decode("UTF-8")
|
|
||||||
with open("your_system_information.txt", "w") as file:
|
|
||||||
file.write(output)
|
|
@ -0,0 +1,17 @@
|
|||||||
|
"""Docstring"""
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
from print_helpers import print_gr
|
||||||
|
|
||||||
|
|
||||||
|
def helloworld():
|
||||||
|
print_gr("This shows that your installation is working correctly")
|
||||||
|
subprocess.call("screenfetch", shell=True)
|
||||||
|
print_gr("You can now proceed with setting up individual modules")
|
||||||
|
print_gr("Run ./lnxtools.sh to see all available commands")
|
||||||
|
output = subprocess.check_output("cat /etc/*-release", shell=True).decode("UTF-8")
|
||||||
|
with open("your_system_information.txt", "w") as file:
|
||||||
|
file.write(output)
|
||||||
|
|
||||||
|
|
||||||
|
functions = helloworld
|
@ -1,22 +0,0 @@
|
|||||||
import subprocess
|
|
||||||
|
|
||||||
|
|
||||||
class ToolsInstaller:
|
|
||||||
|
|
||||||
def basic_tools(self):
|
|
||||||
"""Install the most basic tools!"""
|
|
||||||
print("Try to install basic Command-line tools")
|
|
||||||
subprocess.run("apt-get install -y bleachbit nano xrdp htop bash-completion dialog powertop tree wget",
|
|
||||||
shell=True)
|
|
||||||
print("Script ran to completion.")
|
|
||||||
|
|
||||||
def hard_drive_tools(self):
|
|
||||||
"""Install tools to look up smart information from your hard-drives"""
|
|
||||||
subprocess.run("apt-get install -y smartmontools gsmartcontrol", shell=True)
|
|
||||||
|
|
||||||
def docker(self):
|
|
||||||
"""Install the Docker service on the machine"""
|
|
||||||
subprocess.run("curl -fsSL https://get.docker.com | bash", shell=True)
|
|
||||||
subprocess.run("curl -L \"https://github.com/docker/compose/releases/download/"
|
|
||||||
"1.25.4/docker-compose-$(uname -s)-$(uname -m)\" -o /usr/local/bin/docker-compose"
|
|
||||||
"&& chmod +x /usr/local/bin/docker-compose", shell=True)
|
|
@ -0,0 +1,33 @@
|
|||||||
|
import subprocess
|
||||||
|
|
||||||
|
from print_helpers import print_warn, print_gr
|
||||||
|
|
||||||
|
|
||||||
|
def basic_tools():
|
||||||
|
"""Install the most basic tools!"""
|
||||||
|
print_warn("Try to install basic Command-line tools")
|
||||||
|
subprocess.run(
|
||||||
|
"apt update && apt-get install -y bleachbit nano htop bash-completion dialog powertop tree wget vim git",
|
||||||
|
shell=True
|
||||||
|
)
|
||||||
|
print_gr("Module basictools has successfully finished!")
|
||||||
|
|
||||||
|
|
||||||
|
def hard_drive_tools():
|
||||||
|
"""Install tools to look up smart information from your hard-drives"""
|
||||||
|
subprocess.run("apt-get install -y smartmontools gsmartcontrol", shell=True)
|
||||||
|
|
||||||
|
|
||||||
|
def docker():
|
||||||
|
"""Install the Docker service on the machine"""
|
||||||
|
subprocess.run("curl -fsSL https://get.docker.com | bash", shell=True)
|
||||||
|
subprocess.run("curl -L \"https://github.com/docker/compose/releases/download/"
|
||||||
|
"1.25.4/docker-compose-$(uname -s)-$(uname -m)\" -o /usr/local/bin/docker-compose"
|
||||||
|
"&& chmod +x /usr/local/bin/docker-compose", shell=True)
|
||||||
|
|
||||||
|
|
||||||
|
functions = {
|
||||||
|
"basictools": basic_tools,
|
||||||
|
"harddrive": hard_drive_tools,
|
||||||
|
"docker": docker
|
||||||
|
}
|
@ -1,154 +0,0 @@
|
|||||||
import subprocess
|
|
||||||
from typing import List
|
|
||||||
|
|
||||||
from PyInquirer import prompt
|
|
||||||
|
|
||||||
|
|
||||||
def _run_shell_command(cmd: List[str]) -> str:
|
|
||||||
return subprocess.check_output(cmd).decode("UTF-8").strip()
|
|
||||||
|
|
||||||
|
|
||||||
class SwapModule:
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
actions = {
|
|
||||||
"Create/Resize temp. swap": self._create_resize_swap,
|
|
||||||
"Create/Resize persistent swap": self._create_resize_persistent_swap,
|
|
||||||
"Delete swap": self._delete_swap,
|
|
||||||
"Make temp. swap persistent": self._make_swap_persistent,
|
|
||||||
"Get swap location": self._get_swap_location,
|
|
||||||
"Get swap size": self._get_swap_size,
|
|
||||||
"Show swapiness": self._show_swapiness,
|
|
||||||
"Adjust temp. swapiness": self._adjust_swapiness_temp,
|
|
||||||
"Check fstab for entry": self._fstab_entry_exists
|
|
||||||
}
|
|
||||||
menu = [
|
|
||||||
{
|
|
||||||
'type': 'list',
|
|
||||||
'message': 'Select action',
|
|
||||||
'name': 'action',
|
|
||||||
'choices': list(map(lambda x: {"name": x}, actions.keys()))
|
|
||||||
}
|
|
||||||
]
|
|
||||||
selected_action = prompt(menu)['action']
|
|
||||||
actions[selected_action]()
|
|
||||||
|
|
||||||
def _create_resize_persistent_swap(self):
|
|
||||||
self._create_resize_swap()
|
|
||||||
self._make_swap_persistent()
|
|
||||||
|
|
||||||
def _get_swap_location(self):
|
|
||||||
output_swaps = _run_shell_command(["cat", "/proc/swaps"])
|
|
||||||
try:
|
|
||||||
swap_location = output_swaps.split()[5]
|
|
||||||
print("Swap is located here:", swap_location)
|
|
||||||
return swap_location
|
|
||||||
except IndexError:
|
|
||||||
print("Swap file doesn´t exist!")
|
|
||||||
return None
|
|
||||||
|
|
||||||
def _get_swap_size(self):
|
|
||||||
swap_size = _run_shell_command(['swapon', '--show'])
|
|
||||||
try:
|
|
||||||
swap_size = swap_size.split()[7]
|
|
||||||
print("Swap is {}b big!".format(swap_size))
|
|
||||||
except IndexError:
|
|
||||||
print("Swap file doesn´t exist!")
|
|
||||||
|
|
||||||
def _create_resize_swap(self):
|
|
||||||
output_swapon = _run_shell_command(['swapon', '--show'])
|
|
||||||
if output_swapon is not "":
|
|
||||||
swap_size = output_swapon.split()[7]
|
|
||||||
print("")
|
|
||||||
print("Swap already installed! You can resize it!")
|
|
||||||
print("Curr. swap size: {}b".format(swap_size))
|
|
||||||
resize = input("How big should your swap become (numbers in Gigabyte)? ")
|
|
||||||
resize_swapfile = "sudo swapoff /swapfile && " + \
|
|
||||||
"sudo fallocate -l {}G /swapfile && ".format(resize) + \
|
|
||||||
"sudo mkswap /swapfile && " + \
|
|
||||||
"sudo swapon /swapfile"
|
|
||||||
subprocess.call(resize_swapfile, shell=True)
|
|
||||||
output_free = _run_shell_command(["free", "-h"])
|
|
||||||
print(output_free.strip())
|
|
||||||
|
|
||||||
else:
|
|
||||||
size = input("How big should the swap be (numbers in Gigabyte)? ")
|
|
||||||
create_swapfile = "sudo fallocate -l {}G /swapfile && ".format(size) + \
|
|
||||||
"sudo chmod 600 /swapfile && " + \
|
|
||||||
"sudo mkswap /swapfile && " + \
|
|
||||||
"sudo swapon /swapfile"
|
|
||||||
subprocess.call(create_swapfile, shell=True)
|
|
||||||
|
|
||||||
output_free = _run_shell_command(["free", "-h"])
|
|
||||||
print(output_free.strip())
|
|
||||||
|
|
||||||
def _make_swap_persistent(self):
|
|
||||||
swap_location = self._get_swap_location()
|
|
||||||
if swap_location is None:
|
|
||||||
print("Swap file doesn't exist!")
|
|
||||||
return
|
|
||||||
backup_fstab = "sudo cp /etc/fstab /etc/fstab.bak"
|
|
||||||
enable_persistence = "echo '{} none swap sw 0 0' | sudo tee -a /etc/fstab".format(swap_location)
|
|
||||||
if self._fstab_entry_exists():
|
|
||||||
print("Swap is already persistent!")
|
|
||||||
else:
|
|
||||||
subprocess.call(backup_fstab, shell=True)
|
|
||||||
subprocess.call(enable_persistence, shell=True)
|
|
||||||
print("Swap is now persistent!")
|
|
||||||
|
|
||||||
def _show_swapiness(self):
|
|
||||||
print(_run_shell_command(["cat", "/proc/sys/vm/swappiness"]))
|
|
||||||
|
|
||||||
def _adjust_swapiness_temp(self):
|
|
||||||
options = {
|
|
||||||
"Light": 25,
|
|
||||||
"Default": 60,
|
|
||||||
"Aggressive": 100
|
|
||||||
}
|
|
||||||
menu = [
|
|
||||||
{
|
|
||||||
'type': 'list',
|
|
||||||
'message': 'Select action',
|
|
||||||
'name': 'action',
|
|
||||||
'choices': list(map(lambda x: {"name": x}, options.keys()))
|
|
||||||
}
|
|
||||||
]
|
|
||||||
selected_swapiness = prompt(menu)['action']
|
|
||||||
|
|
||||||
adjust = "sudo sysctl vm.swappiness=" + str(options[selected_swapiness])
|
|
||||||
subprocess.call(adjust, shell=True)
|
|
||||||
print("Temporary swapiness is " + str(options[selected_swapiness]))
|
|
||||||
|
|
||||||
def _delete_swap(self):
|
|
||||||
swap_location = self._get_swap_location()
|
|
||||||
if swap_location is None:
|
|
||||||
return
|
|
||||||
disable_swapfile = "sudo swapoff {} && ".format(swap_location) + \
|
|
||||||
"sudo rm {}".format(swap_location)
|
|
||||||
if self._fstab_entry_exists():
|
|
||||||
with open("/etc/fstab", "r") as fstab_out:
|
|
||||||
content = fstab_out.readlines()
|
|
||||||
with open("/etc/fstab", "w") as fstab_in:
|
|
||||||
content = content[:-1]
|
|
||||||
for line in content:
|
|
||||||
fstab_in.write(line)
|
|
||||||
else:
|
|
||||||
print("No entry in /etc/fstab!")
|
|
||||||
subprocess.call(disable_swapfile, shell=True)
|
|
||||||
output_swapon = _run_shell_command(['swapon', '--show'])
|
|
||||||
output_free = _run_shell_command(["free", "-h"])
|
|
||||||
if not output_swapon:
|
|
||||||
print("Swap deleted!")
|
|
||||||
print(output_free.strip())
|
|
||||||
|
|
||||||
def _fstab_entry_exists(self):
|
|
||||||
swap_location = self._get_swap_location()
|
|
||||||
fstab_entry = "{} none swap sw 0 0\n".format(swap_location)
|
|
||||||
with open("/etc/fstab", "r") as fstab_file:
|
|
||||||
line = fstab_file.readlines()[-1]
|
|
||||||
if line != fstab_entry:
|
|
||||||
print("No entry in /etc/fstab")
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
print("fstab entry:", line.strip())
|
|
||||||
return True
|
|
@ -0,0 +1,166 @@
|
|||||||
|
import subprocess
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
from PyInquirer import prompt
|
||||||
|
|
||||||
|
from print_helpers import print_bold, print_warn, print_gr
|
||||||
|
|
||||||
|
|
||||||
|
def run_shell_command(cmd: List[str]) -> str:
|
||||||
|
return subprocess.check_output(cmd).decode("UTF-8").strip()
|
||||||
|
|
||||||
|
|
||||||
|
def create_resize_persistent_swap():
|
||||||
|
create_resize_swap()
|
||||||
|
make_swap_persistent()
|
||||||
|
|
||||||
|
|
||||||
|
def get_swap_location():
|
||||||
|
output_swaps = run_shell_command(["cat", "/proc/swaps"])
|
||||||
|
try:
|
||||||
|
swap_location = output_swaps.split()[5]
|
||||||
|
print_bold(f"Swap is located here: {swap_location}")
|
||||||
|
return swap_location
|
||||||
|
except IndexError:
|
||||||
|
print_warn("Swap file doesn´t exist!")
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def get_swap_size():
|
||||||
|
swap_size = run_shell_command(['swapon', '--show'])
|
||||||
|
try:
|
||||||
|
swap_size = swap_size.split()[7]
|
||||||
|
print_gr(f"Swap is {swap_size}b big!")
|
||||||
|
except IndexError:
|
||||||
|
print_warn("Swap file doesn´t exist!")
|
||||||
|
|
||||||
|
|
||||||
|
def create_resize_swap():
|
||||||
|
output_swapon = run_shell_command(['swapon', '--show'])
|
||||||
|
if output_swapon is not "":
|
||||||
|
swap_size = output_swapon.split()[7]
|
||||||
|
print("")
|
||||||
|
print_bold("Swap already installed! You can resize it!")
|
||||||
|
print_bold(f"Curr. swap size: {swap_size}b")
|
||||||
|
resize = input("How big should your swap become (numbers in Gigabyte)? ")
|
||||||
|
resize_swapfile = "swapoff /swapfile && " + \
|
||||||
|
f"fallocate -l {resize}G /swapfile && " + \
|
||||||
|
"mkswap /swapfile && " + \
|
||||||
|
"swapon /swapfile"
|
||||||
|
subprocess.call(resize_swapfile, shell=True)
|
||||||
|
output_free = run_shell_command(["free", "-h"])
|
||||||
|
print_gr(output_free)
|
||||||
|
|
||||||
|
else:
|
||||||
|
size = input("How big should the swap be (numbers in Gigabyte)? ")
|
||||||
|
create_swapfile = f"fallocate -l {size}G /swapfile && " + \
|
||||||
|
"chmod 600 /swapfile && " + \
|
||||||
|
"mkswap /swapfile && " + \
|
||||||
|
"swapon /swapfile"
|
||||||
|
subprocess.call(create_swapfile, shell=True)
|
||||||
|
|
||||||
|
output_free = run_shell_command(["free", "-h"])
|
||||||
|
print_gr(output_free)
|
||||||
|
|
||||||
|
|
||||||
|
def make_swap_persistent():
|
||||||
|
swap_location = get_swap_location()
|
||||||
|
if swap_location is None:
|
||||||
|
print_warn("Swap file doesn't exist!")
|
||||||
|
return
|
||||||
|
backup_fstab = "cp /etc/fstab /etc/fstab.bak"
|
||||||
|
enable_persistence = f"echo '{swap_location} none swap sw 0 0' | tee -a /etc/fstab"
|
||||||
|
if fstab_entry_exists():
|
||||||
|
print_warn("Swap is already persistent!")
|
||||||
|
else:
|
||||||
|
subprocess.call(backup_fstab, shell=True)
|
||||||
|
subprocess.call(enable_persistence, shell=True)
|
||||||
|
print_gr("Swap is now persistent!")
|
||||||
|
|
||||||
|
|
||||||
|
def show_swapiness():
|
||||||
|
print_gr(run_shell_command(["cat", "/proc/sys/vm/swappiness"]))
|
||||||
|
|
||||||
|
|
||||||
|
def adjust_swapiness_temp():
|
||||||
|
options = {
|
||||||
|
"Light": 25,
|
||||||
|
"Default": 60,
|
||||||
|
"Aggressive": 100
|
||||||
|
}
|
||||||
|
menu = [
|
||||||
|
{
|
||||||
|
'type': 'list',
|
||||||
|
'message': 'Select action',
|
||||||
|
'name': 'action',
|
||||||
|
'choices': list(map(lambda x: {"name": x}, options.keys()))
|
||||||
|
}
|
||||||
|
]
|
||||||
|
selected_swapiness = prompt(menu)['action']
|
||||||
|
|
||||||
|
adjust = "sysctl vm.swappiness=" + str(options[selected_swapiness])
|
||||||
|
subprocess.call(adjust, shell=True)
|
||||||
|
print_gr("Temporary swapiness is " + str(options[selected_swapiness]))
|
||||||
|
|
||||||
|
|
||||||
|
def delete_swap():
|
||||||
|
swap_location = get_swap_location()
|
||||||
|
if swap_location is None:
|
||||||
|
return
|
||||||
|
disable_swapfile = f"swapoff {swap_location} && " + \
|
||||||
|
f"rm {swap_location}"
|
||||||
|
if fstab_entry_exists():
|
||||||
|
with open("/etc/fstab", "r") as fstab_out:
|
||||||
|
content = fstab_out.readlines()
|
||||||
|
with open("/etc/fstab", "w") as fstab_in:
|
||||||
|
content = content[:-1]
|
||||||
|
for line in content:
|
||||||
|
fstab_in.write(line)
|
||||||
|
else:
|
||||||
|
print_warn("No entry in /etc/fstab!")
|
||||||
|
subprocess.call(disable_swapfile, shell=True)
|
||||||
|
output_swapon = run_shell_command(['swapon', '--show'])
|
||||||
|
output_free = run_shell_command(["free", "-h"])
|
||||||
|
if not output_swapon:
|
||||||
|
print_gr("Swap deleted!")
|
||||||
|
print_gr(output_free)
|
||||||
|
|
||||||
|
|
||||||
|
def fstab_entry_exists():
|
||||||
|
swap_location = get_swap_location()
|
||||||
|
fstab_entry = f"{swap_location} none swap sw 0 0\n"
|
||||||
|
with open("/etc/fstab", "r") as fstab_file:
|
||||||
|
line = fstab_file.readlines()[-1]
|
||||||
|
if line != fstab_entry:
|
||||||
|
print_warn("No entry in /etc/fstab")
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
print_gr(f"fstab entry: {line.strip()}")
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def run():
|
||||||
|
actions = {
|
||||||
|
"Create/Resize temp. swap": create_resize_swap,
|
||||||
|
"Create/Resize persistent swap": create_resize_persistent_swap,
|
||||||
|
"Delete swap": delete_swap,
|
||||||
|
"Make temp. swap persistent": make_swap_persistent,
|
||||||
|
"Get swap location": get_swap_location,
|
||||||
|
"Get swap size": get_swap_size,
|
||||||
|
"Show swapiness": show_swapiness,
|
||||||
|
"Adjust temp. swapiness": adjust_swapiness_temp,
|
||||||
|
"Check fstab for entry": fstab_entry_exists,
|
||||||
|
}
|
||||||
|
menu = [
|
||||||
|
{
|
||||||
|
'type': 'list',
|
||||||
|
'message': 'Select action',
|
||||||
|
'name': 'action',
|
||||||
|
'choices': list(map(lambda x: {"name": x}, actions.keys()))
|
||||||
|
}
|
||||||
|
]
|
||||||
|
selected_action = prompt(menu)['action']
|
||||||
|
actions[selected_action]()
|
||||||
|
|
||||||
|
|
||||||
|
functions = run
|
@ -1,13 +0,0 @@
|
|||||||
import subprocess
|
|
||||||
|
|
||||||
|
|
||||||
class Systemupdate:
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
print("Running update")
|
|
||||||
subprocess.call(["apt", "update", "-y"])
|
|
||||||
subprocess.call(["apt", "upgrade", "-y"])
|
|
||||||
subprocess.call(["apt", "dist-upgrade", "-y"])
|
|
||||||
subprocess.call(["apt", "autoremove", "-y"])
|
|
||||||
subprocess.call(["apt", "autoclean", "-y"])
|
|
||||||
print("All update processes finished, please check output for further details.")
|
|
@ -0,0 +1,18 @@
|
|||||||
|
import subprocess
|
||||||
|
|
||||||
|
from print_helpers import print_gr
|
||||||
|
|
||||||
|
|
||||||
|
def run():
|
||||||
|
print("Running update")
|
||||||
|
subprocess.call(["apt", "update", "-y"])
|
||||||
|
subprocess.call(["apt", "upgrade", "-y"])
|
||||||
|
subprocess.call(["apt", "dist-upgrade", "-y"])
|
||||||
|
subprocess.call(["apt", "autoremove", "-y"])
|
||||||
|
subprocess.call(["apt", "autoclean", "-y"])
|
||||||
|
print_gr("All update processes finished, please check output for further details.")
|
||||||
|
|
||||||
|
|
||||||
|
functions = {
|
||||||
|
"run": run
|
||||||
|
}
|
@ -1,32 +0,0 @@
|
|||||||
import subprocess
|
|
||||||
from os import path
|
|
||||||
import time
|
|
||||||
import re
|
|
||||||
|
|
||||||
|
|
||||||
class Teamspeak:
|
|
||||||
"""Manage a Docker backed Teamspeak server"""
|
|
||||||
|
|
||||||
def start(self):
|
|
||||||
"""Starts a Teamspeak Server with docker-compose"""
|
|
||||||
show_creds = False if path.exists(path.join(path.dirname(__file__), "ts3_data")) else True
|
|
||||||
subprocess.run("docker-compose up -d", shell=True, cwd=path.dirname(__file__))
|
|
||||||
if show_creds:
|
|
||||||
logs = subprocess.check_output("docker-compose logs", shell=True, cwd=path.dirname(__file__)).decode("UTF-8")
|
|
||||||
while re.search(r"token", logs) is None:
|
|
||||||
time.sleep(2)
|
|
||||||
logs = subprocess.check_output("docker-compose logs", shell=True, cwd=path.dirname(__file__)).decode("UTF-8")
|
|
||||||
print("Server Query Admin Account: " + re.search(r"loginname=.*", logs).group(0))
|
|
||||||
print("Server Admin Token: " + re.search(r"token=(.*)", logs).group(1))
|
|
||||||
|
|
||||||
def stop(self):
|
|
||||||
"""Stops the Teamspeak Server with docker-compose"""
|
|
||||||
subprocess.run("docker-compose down -v", shell=True, cwd=path.dirname(__file__))
|
|
||||||
|
|
||||||
def pack_data(self, name="ts3_data.tar.gz"):
|
|
||||||
"""Pack all user data of the server started with this script as tar file"""
|
|
||||||
subprocess.run(f"tar -zcvf {name} ts3_data", shell=True, cwd=path.dirname(__file__))
|
|
||||||
|
|
||||||
def show_logs(self):
|
|
||||||
"""show the logs of the running Teamspeak server"""
|
|
||||||
subprocess.run("docker-compose logs", shell=True, cwd=path.dirname(__file__))
|
|
43
modules/teamspeak/__init__.py
Normal file
43
modules/teamspeak/__init__.py
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import re
|
||||||
|
import subprocess
|
||||||
|
import time
|
||||||
|
from os import path
|
||||||
|
|
||||||
|
from print_helpers import print_bold
|
||||||
|
|
||||||
|
|
||||||
|
def start():
|
||||||
|
"""Starts a Teamspeak Server with docker-compose"""
|
||||||
|
show_creds = False if path.exists(path.join(path.dirname(__file__), "ts3_data")) else True
|
||||||
|
subprocess.run("docker-compose up -d", shell=True, cwd=path.dirname(__file__))
|
||||||
|
if show_creds:
|
||||||
|
logs = subprocess.check_output("docker-compose logs", shell=True, cwd=path.dirname(__file__)).decode("UTF-8")
|
||||||
|
while re.search(r"token", logs) is None:
|
||||||
|
time.sleep(2)
|
||||||
|
logs = subprocess.check_output("docker-compose logs", shell=True, cwd=path.dirname(__file__)).decode(
|
||||||
|
"UTF-8")
|
||||||
|
print_bold("Server Query Admin Account: " + re.search(r"loginname=.*", logs).group(0))
|
||||||
|
print_bold("Server Admin Token: " + re.search(r"token=(.*)", logs).group(1))
|
||||||
|
|
||||||
|
|
||||||
|
def stop():
|
||||||
|
"""Stops the Teamspeak Server with docker-compose"""
|
||||||
|
subprocess.run("docker-compose down -v", shell=True, cwd=path.dirname(__file__))
|
||||||
|
|
||||||
|
|
||||||
|
def pack_data(name="ts3_data.tar.gz"):
|
||||||
|
"""Pack all user data of the server started with this script as tar file"""
|
||||||
|
subprocess.run(f"tar -zcvf {name} ts3_data", shell=True, cwd=path.dirname(__file__))
|
||||||
|
|
||||||
|
|
||||||
|
def show_logs():
|
||||||
|
"""show the logs of the running Teamspeak server"""
|
||||||
|
subprocess.run("docker-compose logs", shell=True, cwd=path.dirname(__file__))
|
||||||
|
|
||||||
|
|
||||||
|
functions = {
|
||||||
|
"start": start,
|
||||||
|
"stop": stop,
|
||||||
|
"pack": pack_data,
|
||||||
|
"logs": show_logs
|
||||||
|
}
|
@ -1,104 +0,0 @@
|
|||||||
import json
|
|
||||||
import os
|
|
||||||
import subprocess
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
from PyInquirer import prompt
|
|
||||||
|
|
||||||
|
|
||||||
class VimModule:
|
|
||||||
def __init__(self):
|
|
||||||
super().__init__()
|
|
||||||
self._debugFlag = False
|
|
||||||
self._json_config = {}
|
|
||||||
with open("modules/vim/vimrc_conf.json") as plugins:
|
|
||||||
self._json_config = json.load(plugins)
|
|
||||||
|
|
||||||
def _get_vim_root(self):
|
|
||||||
if self._debugFlag:
|
|
||||||
return Path(os.getcwd()).joinpath("devenv", ".vim")
|
|
||||||
else:
|
|
||||||
return Path().home().joinpath(".vim")
|
|
||||||
|
|
||||||
def _create_folder_structure(self):
|
|
||||||
os.makedirs(str(self._get_vim_root().joinpath("autoload")), exist_ok=True)
|
|
||||||
os.makedirs(str(self._get_vim_root().joinpath("plugged")), exist_ok=True)
|
|
||||||
|
|
||||||
def _get_vimplug_file(self):
|
|
||||||
vimplug_filepath = Path(str(self._get_vim_root().joinpath("autoload")))
|
|
||||||
print(vimplug_filepath)
|
|
||||||
if os.path.isfile(str(self._get_vim_root().joinpath("autoload", "plug.vim"))):
|
|
||||||
print("Vimplug already installed!")
|
|
||||||
else:
|
|
||||||
curl_request = "curl {} -o {}".format(
|
|
||||||
self._json_config['pluginmanager_url'],
|
|
||||||
str(self._get_vim_root().joinpath("autoload", "plug.vim"))
|
|
||||||
)
|
|
||||||
subprocess.call(curl_request, shell=True)
|
|
||||||
|
|
||||||
def _create_plugin_section(self):
|
|
||||||
vimrc_content = []
|
|
||||||
plugins = self._json_config['plugins']
|
|
||||||
print("Available Plugins:")
|
|
||||||
plugin_selection = [
|
|
||||||
{
|
|
||||||
'type': 'checkbox',
|
|
||||||
'message': 'Select plugins',
|
|
||||||
'name': 'modules',
|
|
||||||
'choices': list(map(lambda x: {"name": x}, plugins.keys()))
|
|
||||||
}
|
|
||||||
]
|
|
||||||
selected_plugins = prompt(plugin_selection)['modules']
|
|
||||||
if len(selected_plugins) > 0:
|
|
||||||
self._get_vimplug_file()
|
|
||||||
print("\033[4mYour selection:\033[0m")
|
|
||||||
[print(x) for x in selected_plugins]
|
|
||||||
|
|
||||||
vimrc_content.append("call plug#begin('~/.vim/plugged')\n")
|
|
||||||
for element in selected_plugins:
|
|
||||||
vimrc_content.append(plugins[element] + "\n")
|
|
||||||
vimrc_content.append("call plug#end()\n")
|
|
||||||
|
|
||||||
return vimrc_content
|
|
||||||
|
|
||||||
def _create_setting_section(self):
|
|
||||||
default_settings = list(self._json_config['settings'].values())
|
|
||||||
|
|
||||||
print("\n\033[4mDefault settings:\033[0m")
|
|
||||||
[print(i) for i in default_settings]
|
|
||||||
|
|
||||||
vimrc_content = list(map(lambda x: x + "\n", default_settings))
|
|
||||||
return vimrc_content
|
|
||||||
|
|
||||||
def _get_vimfile_working_copy(self):
|
|
||||||
vimrc_path = str(self._get_vim_root().joinpath(".vimrc"))
|
|
||||||
try:
|
|
||||||
with open(vimrc_path, "r") as vimrc_file:
|
|
||||||
vimrc_content = vimrc_file.readlines()
|
|
||||||
except FileNotFoundError:
|
|
||||||
vimrc_content = []
|
|
||||||
|
|
||||||
return vimrc_content
|
|
||||||
|
|
||||||
def _write_vimfile(self, vimrc_content):
|
|
||||||
seen = set()
|
|
||||||
seen_add = seen.add
|
|
||||||
vimrc_content = [x1 for x1 in vimrc_content if not (x1 in seen or seen_add(x1))]
|
|
||||||
|
|
||||||
vimrc_path = str(self._get_vim_root().joinpath(".vimrc"))
|
|
||||||
with open(vimrc_path, "w") as vimrc_file:
|
|
||||||
for line in vimrc_content:
|
|
||||||
vimrc_file.write(line)
|
|
||||||
|
|
||||||
def _exec_plugin_manager(self):
|
|
||||||
install_plugins = "vim +PlugInstall +qall +silent"
|
|
||||||
subprocess.call(install_plugins, shell=True)
|
|
||||||
|
|
||||||
def run(self, debug=False):
|
|
||||||
if debug:
|
|
||||||
self._debugFlag = True
|
|
||||||
self._create_folder_structure()
|
|
||||||
plugin_section = self._create_plugin_section()
|
|
||||||
settings_section = self._create_setting_section()
|
|
||||||
self._write_vimfile(settings_section + plugin_section)
|
|
||||||
self._exec_plugin_manager()
|
|
@ -0,0 +1,94 @@
|
|||||||
|
import json
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from PyInquirer import prompt
|
||||||
|
|
||||||
|
from print_helpers import print_gr, print_bold
|
||||||
|
|
||||||
|
vim_root = Path().home().joinpath(".vim")
|
||||||
|
vimrc_path = str(Path().home().joinpath(".vimrc"))
|
||||||
|
json_config = {}
|
||||||
|
|
||||||
|
|
||||||
|
def create_plugin_section():
|
||||||
|
plugins = json_config['plugins']
|
||||||
|
print("Available Plugins:")
|
||||||
|
plugin_selection = [
|
||||||
|
{
|
||||||
|
'type': 'checkbox',
|
||||||
|
'message': 'Select plugins',
|
||||||
|
'name': 'modules',
|
||||||
|
'choices': list(map(lambda x: {"name": x}, plugins.keys()))
|
||||||
|
}
|
||||||
|
]
|
||||||
|
selected_plugins = prompt(plugin_selection)['modules']
|
||||||
|
print_bold("Your selection:")
|
||||||
|
[print(x) for x in selected_plugins]
|
||||||
|
|
||||||
|
# Install vimplug if plugins selected
|
||||||
|
vimplug_path = str(vim_root.joinpath("autoload", "plug.vim"))
|
||||||
|
if selected_plugins and not os.path.isfile(vimplug_path):
|
||||||
|
curl_request = f"curl {json_config['pluginmanager_url']} -o {vimplug_path}"
|
||||||
|
subprocess.call(curl_request, shell=True)
|
||||||
|
print_gr("Pluginmanager was set up")
|
||||||
|
|
||||||
|
vimrc_content = ["call plug#begin('~/.vim/plugged')\n"]
|
||||||
|
for element in selected_plugins:
|
||||||
|
vimrc_content.append(plugins[element] + "\n")
|
||||||
|
vimrc_content.append("call plug#end()\n")
|
||||||
|
return vimrc_content
|
||||||
|
|
||||||
|
|
||||||
|
def create_setting_section():
|
||||||
|
default_settings = list(json_config['settings'].values())
|
||||||
|
|
||||||
|
print_bold("Default settings:")
|
||||||
|
[print(i) for i in default_settings]
|
||||||
|
|
||||||
|
vimrc_content = list(map(lambda x: x + "\n", default_settings))
|
||||||
|
return vimrc_content
|
||||||
|
|
||||||
|
|
||||||
|
def write_vimfile(vimrc_content):
|
||||||
|
seen = set()
|
||||||
|
seen_add = seen.add
|
||||||
|
vimrc_content = [x1 for x1 in vimrc_content if not (x1 in seen or seen_add(x1))]
|
||||||
|
|
||||||
|
with open(vimrc_path, "w") as vimrc_file:
|
||||||
|
for line in vimrc_content:
|
||||||
|
vimrc_file.write(line)
|
||||||
|
|
||||||
|
|
||||||
|
# Unused
|
||||||
|
def _get_vimfile_working_copy():
|
||||||
|
try:
|
||||||
|
with open(vimrc_path, "r") as vimrc_file:
|
||||||
|
vimrc_content = vimrc_file.readlines()
|
||||||
|
except FileNotFoundError:
|
||||||
|
vimrc_content = []
|
||||||
|
return vimrc_content
|
||||||
|
|
||||||
|
|
||||||
|
def run():
|
||||||
|
global json_config
|
||||||
|
with open("modules/vim/vimrc_conf.json", "r") as config:
|
||||||
|
json_config = json.load(config)
|
||||||
|
|
||||||
|
# Create folders
|
||||||
|
os.makedirs(str(vim_root.joinpath("autoload")), exist_ok=True)
|
||||||
|
os.makedirs(str(vim_root.joinpath("plugged")), exist_ok=True)
|
||||||
|
|
||||||
|
plugin_section = create_plugin_section()
|
||||||
|
settings_section = create_setting_section()
|
||||||
|
|
||||||
|
write_vimfile(settings_section + plugin_section)
|
||||||
|
|
||||||
|
# Exec plugin manager
|
||||||
|
install_plugins = "vim +PlugInstall +qall"
|
||||||
|
subprocess.call(install_plugins, shell=True)
|
||||||
|
print_gr("Module finished successfully!")
|
||||||
|
|
||||||
|
|
||||||
|
functions = run
|
@ -1,12 +1,16 @@
|
|||||||
{
|
{
|
||||||
"pluginmanager_url": "https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim",
|
"pluginmanager_url": "https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim",
|
||||||
"plugins": {
|
"plugins": {
|
||||||
"Colorschemes": "Plug 'https://github.com/rafi/awesome-vim-colorschemes.git'",
|
"AutoPair": "Plug 'https://github.com/jiangmiao/auto-pairs.git'",
|
||||||
"Unix Operations": "Plug 'https://github.com/tpope/vim-eunuch.git'",
|
|
||||||
"Emmet": "Plug 'https://github.com/mattn/emmet-vim.git'",
|
"Emmet": "Plug 'https://github.com/mattn/emmet-vim.git'",
|
||||||
|
"Jellybeans Theme": "Plug 'https://github.com/nanotech/jellybeans.vim.git'",
|
||||||
"Meta5 Theme": "Plug 'https://github.com/christophermca/meta5.git'",
|
"Meta5 Theme": "Plug 'https://github.com/christophermca/meta5.git'",
|
||||||
"Nerdtree": "Plug 'https://github.com/scrooloose/nerdtree'",
|
"Nerdtree": "Plug 'https://github.com/scrooloose/nerdtree'",
|
||||||
"Lightline": "Plug 'https://github.com/itchyny/lightline.vim'"
|
"Vim Airline": "Plug 'https://github.com/vim-airline/vim-airline.git'",
|
||||||
|
"Onedark Theme": "Plug 'https://github.com/joshdick/onedark.vim.git'",
|
||||||
|
"Malokai Theme": "Plug 'kiddos/malokai.vim'",
|
||||||
|
"Monokai Theme": "Plug 'crusoexia/vim-monokai'",
|
||||||
|
"JavaScript Extension": "Plug 'pangloss/vim-javascript'"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"tabstop": "set tabstop=2",
|
"tabstop": "set tabstop=2",
|
||||||
|
@ -12,3 +12,7 @@ def print_warn(text):
|
|||||||
|
|
||||||
def print_blue(text):
|
def print_blue(text):
|
||||||
print("\033[94m" + "[+] " + text + "\033[0m")
|
print("\033[94m" + "[+] " + text + "\033[0m")
|
||||||
|
|
||||||
|
|
||||||
|
def print_bold(text):
|
||||||
|
print("\033[1m" + text + "\033[0m")
|
||||||
|
@ -1,2 +1,5 @@
|
|||||||
fire
|
fire==0.3.1
|
||||||
PyInquirer==1.0.3
|
PyInquirer==1.0.3
|
||||||
|
regex==2020.7.14
|
||||||
|
wheel==0.34.2
|
||||||
|
setuptools==49.2.0
|
||||||
|
Loading…
Reference in New Issue
Block a user