-
Notifications
You must be signed in to change notification settings - Fork 1
/
debian-user-install
executable file
·173 lines (147 loc) · 6.55 KB
/
debian-user-install
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#! /usr/bin/env python3
import argparse, crontab, os, pathlib, pkgutil, shutil, ssh_config, subprocess, sys
from os.path import expanduser
# Check commandline
parser = argparse.ArgumentParser(prog='debian-systemwide-install')
parser.add_argument('-i', '--install-packages', dest='packages', action='store_true', help='Automatically install needed packages via apt and python modules via pip')
parser.add_argument('-p', '--proxy', help='Specify a proxy host that is always used for connections from this machine')
parser.add_argument('clone_url', help='Git clone url to load the ssh configuration')
parsed_args = parser.parse_args()
repo_url = parsed_args.clone_url
# Run the installation
# Check for packages
if not parsed_args.packages:
missing_apt_packages = []
if shutil.which("git") is None:
missing_apt_packages.append("git")
if shutil.which("pip3") is None:
missing_apt_packages.append("python3-pip")
if pkgutil.find_loader('xdg') is None:
missing_apt_packages.append("python3-xdg")
py_cui_available = pkgutil.find_loader('py_cui') is not None
if len(missing_apt_packages) > 1:
print("The following debian packages are missing: " + " ".join(missing_apt_packages), file=sys.stderr)
elif len(missing_apt_packages) == 1:
print("The debian package `" + missing_apt_packages[0] + "' is missing.", file=sys.stderr)
if not py_cui_available:
print("The python module `py-cui' is missing.", file=sys.stderr)
if len(missing_apt_packages) > 0 or not py_cui_available:
print("You may run this installer with -i (or --install-packages) to install dependencies automatically.", file=sys.stderr)
print("Note: The uninstaller will not uninstall these dependencies", file=sys.stderr)
sys.exit(1)
# Copy source files
try:
base_dir = pathlib.Path(os.path.realpath(__file__)).parent.parent
src = base_dir / "lssh"
dst = pathlib.Path(expanduser("~")+"/.lssh/lib/lssh")
print("Copying source files to " + str(dst) + " ...")
os.makedirs(dst, exist_ok=True)
src_files = {f for f in os.listdir(src) if f.endswith(".py")}
dst_files = {f for f in os.listdir(dst) if f.endswith(".py")}
# Copy from source to destination
for filename in src_files:
shutil.copy(src / filename, dst / filename)
# Remove files that have been removed in source dir
for filename in (dst_files - src_files):
os.remove(dst / filename)
except PermissionError as e:
print("Got a PermissionError: " + str(e), file=sys.stderr)
print("Note, that this system-wide installer needs root permissions.")
sys.exit(1)
if parsed_args.packages:
# Install needed debian packages
print("Installing git, python3-pip and python3-xdg ...")
subprocess.run(["apt", "install", "-y", "git", "python3-pip", "python3-xdg"]).check_returncode()
# Install the py_cui module
print("Installing the py_cui python module ...")
subprocess.run(["pip3", "install", "py_cui"])
# Clone the repository
lssh_home = pathlib.Path(expanduser("~")+"/.lssh")
repo_path = lssh_home / "host_repo"
repo_clone_needed = not os.path.isdir(repo_path / ".git")
if repo_clone_needed:
print("Cloning repository into " + str(repo_path) + " ...")
os.makedirs(repo_path, mode=0o700, exist_ok=True)
ret = subprocess.run(["git", "clone", repo_url, str(repo_path)]).returncode
git_clone_success = ret == 0
else:
print("Repository in " + str(repo_path) + " already exists.")
# Create the directory for validated hosts
validated = lssh_home / "hosts"
print("Creating directory for validated hosts in " + str(validated) + " ...")
os.makedirs(validated, exist_ok=True)
# Create a pull wrapper-script
wrapper_file = expanduser("~")+"/.lssh/bin/pull.sh"
print("Creating pull wrapper " + str(wrapper_file) + " ...")
os.makedirs(expanduser("~")+"/.lssh/bin", exist_ok=True)
with open(wrapper_file, "w") as f:
f.write("""#! /bin/bash
cd "$(dirname "$0")"/host_repo || exit 1
pull_output="$(git pull 2>&1)"
pull_exit="$?"
if [ "$pull_exit" != "0" ]; then
echo "$pull_output"
echo "Fatal, could not update the lssh configuration because git pull failed" 1>&2
exit 1
fi
$HOME/.lssh/bin/lssh --load-from .
""")
os.chmod(wrapper_file, 0o755)
# Create the lssh executable file
lssh_file = expanduser("~")+"/.lssh/bin/lssh"
print("Creating lssh executable in " + str(lssh_file) + " ...")
if parsed_args.proxy is not None:
main_call = """options = {
"general_proxy": """ + repr(parsed_args.proxy) + """,
}
main.main(hosts_dir, update_hosts, attributes=options)
"""
else:
main_call = "main.main(hosts_dir, update_hosts)\n"
with open(lssh_file, "w") as f:
f.write("""#! /usr/bin/env python3
import sys
from os.path import expanduser
hosts_dir = expanduser("~")+"/.lssh/hosts"
def update_hosts():
import subprocess
subprocess.run([expanduser("~")+"/.lssh/bin/pull.sh"])
sys.path.append(expanduser("~")+"/.lssh/lib")
from lssh import main
""" + main_call)
os.chmod(lssh_file, 0o755)
# Create remotecommand-whitelist config file
remotecommand_whitelist_file = expanduser("~")+"/.lssh/remotecommand-whitelist.csv"
print("Creating config file " + remotecommand_whitelist_file + " ...")
if os.path.isfile(remotecommand_whitelist_file):
print(" (did already exist)")
else:
os.makedirs(expanduser("~")+"/.lssh", exist_ok=True)
open(remotecommand_whitelist_file, "a").close()
## # Add a section to the ssh config
## print("Setting relevant configs in "+expanduser("~")+"/.ssh/config ...")
## ssh_config.add_section()
## # Setup tab-completion
complete_file = expanduser("~")+"/.bashrc"
print("Writing bash completion instructions to " + complete_file + " ...")
with open(complete_file, "w") as f:
f.write("complete -o filenames -C 'lssh __complete__' lssh\n")
## # Crontab entry
## print("Creating a crontab entry to update the hostlist regularly ...")
## crontab.add_pull_entry()
if repo_clone_needed:
if git_clone_success:
# Initially load the ssh config from the repo
print("Loading initial hostlist ...")
ret = subprocess.run([expanduser("~")+"/.lssh/bin/lssh", "--load-from", str(repo_path)]).returncode
if ret != 0:
print("Your ssh configuration has not been loaded because of the previous errors.", file=sys.stderr)
exit(1)
else:
print("")
print("Warning:")
print(" Your git repository could not be cloned successfully. (See above)")
print(" Please ensure you have the needed permissions, then clone")
print(" the repository to the path " + str(repo_path) + " or run")
print(" this installer again.")
exit(1)