# Copyright (c) 2025 Kim Jarvis TPF Software Services S.A. kim.jarvis@tpfsystems.com
# This software is licensed under the MIT License. See the LICENSE file for details.
#
from ipaddress import ip_address
from dotenv import set_key
import time
[docs]
class Standup_lcx_vm_localhost:
def __init__(self,
vm: str,
image: str,
name: str,
user: str,
user_password: str,
root_password: str,
sudo: bool = False,
su: bool = False):
self.vm = vm
self.image = image
self.name = name
self.user = user
self.user_password = user_password
self.root_password = root_password
self.sudo: bool = sudo
self.su: bool = su
def __repr__(self) -> str:
return (f"Debian("
f"sudo={self.sudo!r}, "
f"su={self.su!r}"
f")")
def execute(self):
from reemote.operations.server.shell import Shell
from reemote.operations.lxc.copy import Copy
from reemote.operations.lxc.init import Init
from reemote.operations.lxc.start import Start
from reemote.facts.lxc.get_status import Get_status
from reemote.operations.lxc.exec import Exec
from reemote.operations.users.mkpasswd import Mkpasswd
from reemote.facts.lxc.get_ip import Get_ip
from reemote.utilities.add_localhost_to_known_hosts import add_localhost_to_known_hosts
from reemote.utilities.make_inventory import make_inventory
# Call the function
add_localhost_to_known_hosts()
yield Copy(image=self.image,sudo=self.sudo,su=self.su)
if "ubuntu" in self.image:
yield Init(image=self.image,
vm=self.vm,
user=self.user,
user_password=self.user_password,
options="--vm",
sudo=self.sudo,
su=self.su,
)
else:
yield Init(image=self.image,
vm=self.vm,
user=self.user,
user_password=self.user_password,
sudo=self.sudo,
su=self.su,
)
r = yield Start(vm=self.vm)
while r.cp.stdout!="RUNNING":
r=yield Get_status(vm=self.vm)
print(r)
time.sleep(1)
if "ubuntu" in self.image:
r=yield Exec(vm=self.vm,cmd='apt-get update',sudo=self.sudo,su=self.su)
print(">>>>>>>>>>>>>>>>>>>>>>",r)
yield Exec(vm=self.vm,cmd='apt install -y openssh-server',sudo=self.sudo,su=self.su)
yield Exec(vm=self.vm, cmd='systemctl start ssh', sudo=self.sudo, su=self.su)
yield Exec(vm=self.vm, cmd='systemctl enable ssh', sudo=self.sudo, su=self.su)
yield Exec(vm=self.vm, cmd='systemctl status ssh', sudo=self.sudo, su=self.su)
yield Exec(vm=self.vm,cmd=f"useradd -m -s /bin/bash -c '{self.name}' {self.user}", sudo=self.sudo,su=self.su)
r=yield Mkpasswd(password=self.user_password)
print(r)
yield Exec(vm=self.vm,cmd=f"usermod --password '{r.cp.stdout}' {self.user}", sudo=self.sudo,su=self.su)
# Should check whether there are pipes in these commands as cannot run in terminal ? We can grep the output but not run a script like thing in lxc
# yield Exec(vm=self.vm,cmd=f"echo '{self.user} ALL=(ALL:ALL) ALL' | sudo tee /etc/sudoers.d/{self.user} > /dev/null", sudo=self.sudo,su=self.su)
yield Exec(vm=self.vm, cmd=f"""bash -c 'cat <<EOF > /etc/sudoers.d/{self.user}
{self.user} ALL=(ALL:ALL) ALL
EOF'
""")
yield Exec(vm=self.vm,cmd=f"sudo chmod 440 /etc/sudoers.d/{self.user}", sudo=self.sudo,su=self.su)
if "debian" in self.image:
yield Exec(vm=self.vm, cmd='apt-get update', sudo=self.sudo, su=self.su)
yield Exec(vm=self.vm, cmd='apt install -y openssh-server', sudo=self.sudo, su=self.su)
yield Exec(vm=self.vm, cmd='systemctl start ssh', sudo=self.sudo, su=self.su)
yield Exec(vm=self.vm, cmd='systemctl enable ssh', sudo=self.sudo, su=self.su)
yield Exec(vm=self.vm, cmd='systemctl status ssh', sudo=self.sudo, su=self.su)
yield Exec(vm=self.vm, cmd=f"useradd -m -s /bin/bash -c '{self.name}' {self.user}", sudo=self.sudo,
su=self.su)
r = yield Mkpasswd(password=self.user_password)
print(r)
yield Exec(vm=self.vm, cmd=f"usermod --password '{r.cp.stdout}' {self.user}", sudo=self.sudo,
su=self.su)
# Should check whether there are pipes in these commands as cannot run in terminal ? We can grep the output but not run a script like thing in lxc
# yield Exec(vm=self.vm,cmd=f"echo '{self.user} ALL=(ALL:ALL) ALL' | sudo tee /etc/sudoers.d/{self.user} > /dev/null", sudo=self.sudo,su=self.su)
yield Exec(vm=self.vm, cmd=f"""bash -c 'cat <<EOF > /etc/sudoers.d/{self.user}
{self.user} ALL=(ALL:ALL) ALL
EOF'
""")
yield Exec(vm=self.vm, cmd=f"sudo chmod 440 /etc/sudoers.d/{self.user}", sudo=self.sudo, su=self.su)
if "alpine" in self.image:
yield Exec(vm=self.vm,cmd='apk update',sudo=self.sudo,su=self.su)
# yield Exec(vm=self.vm,cmd='apk add shadow',sudo=self.sudo,su=self.su)
yield Exec(vm=self.vm,cmd='apk add openssh-server',sudo=self.sudo,su=self.su)
yield Exec(vm=self.vm, cmd='rc-update add sshd', sudo=self.sudo, su=self.su)
yield Exec(vm=self.vm, cmd='rc-service sshd start', sudo=self.sudo, su=self.su)
yield Exec(vm=self.vm, cmd='rc-service sshd status', sudo=self.sudo, su=self.su)
yield Exec(vm=self.vm, cmd=f"useradd -m -s /bin/sh -c '{self.name}' {self.user}", sudo=self.sudo,su=self.su)
r = yield Mkpasswd(password=self.user_password)
print(r)
yield Exec(vm=self.vm, cmd=f"usermod --password '{r.cp.stdout}' {self.user}", sudo=self.sudo, su=self.su)
yield Exec(vm=self.vm,cmd='apk add sudo',sudo=self.sudo,su=self.su)
yield Exec(vm=self.vm, cmd=f"""sh -c 'echo "{self.user} ALL=(ALL:ALL) ALL" > /etc/sudoers.d/{self.user}' """, sudo=self.sudo, su=self.su)
if "centos" in self.image:
yield Exec(vm=self.vm, cmd='dnf update', sudo=self.sudo, su=self.su)
yield Exec(vm=self.vm, cmd='dnf install -y openssh-server', sudo=self.sudo, su=self.su)
yield Exec(vm=self.vm, cmd='systemctl start sshd', sudo=self.sudo, su=self.su)
yield Exec(vm=self.vm, cmd='systemctl enable sshd', sudo=self.sudo, su=self.su)
yield Exec(vm=self.vm, cmd='systemctl status sshd', sudo=self.sudo, su=self.su)
yield Exec(vm=self.vm, cmd=f"useradd -m -s /bin/bash -c '{self.name}' {self.user}", sudo=self.sudo,
su=self.su)
r = yield Mkpasswd(password=self.user_password)
print(r)
yield Exec(vm=self.vm, cmd=f"usermod --password '{r.cp.stdout}' {self.user}", sudo=self.sudo, su=self.su)
# Should check whether there are pipes in these commands as cannot run in terminal ? We can grep the output but not run a script like thing in lxc
# yield Exec(vm=self.vm,cmd=f"echo '{self.user} ALL=(ALL:ALL) ALL' | sudo tee /etc/sudoers.d/{self.user} > /dev/null", sudo=self.sudo,su=self.su)
yield Exec(vm=self.vm, cmd=f"sudo chmod 777 /etc/sudoers.d", sudo=self.sudo, su=self.su)
yield Exec(vm=self.vm, cmd=f"echo '{self.user} ALL=(ALL:ALL) ALL' > /etc/sudoers.d/{self.user}", sudo=self.sudo, su=self.su)
yield Exec(vm=self.vm, cmd=f"sudo chmod 440 /etc/sudoers.d", sudo=self.sudo, su=self.su)
yield Exec(vm=self.vm, cmd=f"sudo chmod 440 /etc/sudoers.d/{self.user}", sudo=self.sudo, su=self.su)
if "arch" in self.image:
yield Exec(vm=self.vm, cmd='pacman --noconfirm -Syu', sudo=self.sudo, su=self.su)
yield Exec(vm=self.vm, cmd='pacman --noconfirm -S openssh', sudo=self.sudo, su=self.su)
yield Exec(vm=self.vm, cmd='systemctl start sshd', sudo=self.sudo, su=self.su)
yield Exec(vm=self.vm, cmd='systemctl enable sshd', sudo=self.sudo, su=self.su)
yield Exec(vm=self.vm, cmd='systemctl status sshd', sudo=self.sudo, su=self.su)
yield Exec(vm=self.vm, cmd=f"useradd -m -s /bin/bash -c '{self.name}' {self.user}", sudo=self.sudo,
su=self.su)
r = yield Mkpasswd(password=self.user_password)
print(r)
yield Exec(vm=self.vm, cmd=f"usermod --password '{r.cp.stdout}' {self.user}", sudo=self.sudo,
su=self.su)
# Should check whether there are pipes in these commands as cannot run in terminal ? We can grep the output but not run a script like thing in lxc
# yield Exec(vm=self.vm,cmd=f"echo '{self.user} ALL=(ALL:ALL) ALL' | sudo tee /etc/sudoers.d/{self.user} > /dev/null", sudo=self.sudo,su=self.su)
yield Exec(vm=self.vm, cmd=f"""bash -c 'cat <<EOF > /etc/sudoers.d/{self.user}
{self.user} ALL=(ALL:ALL) ALL
EOF'
""")
yield Exec(vm=self.vm, cmd=f"sudo chmod 440 /etc/sudoers.d/{self.user}", sudo=self.sudo, su=self.su)
if "suse" in self.image:
yield Exec(vm=self.vm, cmd='zypper -n refresh', sudo=self.sudo, su=self.su)
yield Exec(vm=self.vm, cmd='zypper -n install openssh-server', sudo=self.sudo, su=self.su)
yield Exec(vm=self.vm, cmd='zypper -n install vim', sudo=self.sudo, su=self.su)
yield Exec(vm=self.vm, cmd='systemctl start sshd', sudo=self.sudo, su=self.su)
yield Exec(vm=self.vm, cmd='systemctl enable sshd', sudo=self.sudo, su=self.su)
yield Exec(vm=self.vm, cmd='systemctl status sshd', sudo=self.sudo, su=self.su)
yield Exec(vm=self.vm, cmd=f"useradd -m -s /bin/bash -c '{self.name}' {self.user}", sudo=self.sudo,
su=self.su)
r = yield Mkpasswd(password=self.user_password)
yield Exec(vm=self.vm, cmd=f"usermod --password '{r.cp.stdout}' {self.user}", sudo=self.sudo,
su=self.su)
r=yield Mkpasswd(password=self.root_password)
yield Shell(f"lxc exec {self.vm} -- usermod --password '{r.cp.stdout}' root", sudo=self.sudo,su=self.su)
# yield Exec(vm=self.vm, cmd=f"touch /etc/sudoers.d/kim", sudo=self.sudo, su=self.su)
yield Exec(vm=self.vm, cmd=f"touch /tmp/sudoers.tmp", sudo=self.sudo, su=self.su)
yield Exec(vm=self.vm, cmd=f"chmod 750 /etc/sudoers.d/", sudo=self.sudo, su=self.su)
# yield Exec(vm=self.vm, cmd=f"chmod 750 /etc/sudoers.d/kim", sudo=self.sudo, su=self.su)
# yield Exec(vm=self.vm, cmd=f"chown root:root /etc/sudoers.d/kim", sudo=self.sudo, su=self.su)
# yield Exec(vm=self.vm, cmd=f"chown kim:kim /etc/sudoers.d/kim", sudo=self.sudo, su=self.su)
# yield Exec(vm=self.vm, cmd=f"chmod 777 /etc/sudoers.d", sudo=self.sudo, su=self.su)
# yield Exec(vm=self.vm, cmd=f"chown kim:kim /etc/sudoers.d", sudo=self.sudo, su=self.su)
# r=yield Exec(vm=self.vm, cmd=f"sudo echo '{self.user} ALL=(ALL:ALL) ALL' > /etc/sudoers.d/{self.user}", sudo=self.sudo, su=self.su)
# I think the root sudoers password is required here, its been set already to "secret".
r = yield Exec(vm=self.vm, cmd=f"""sh -c "echo '{self.user} ALL=(ALL:ALL) ALL' > /etc/sudoers.d/{self.user}" """, sudo=self.sudo, su=self.su)
print('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>',r)
yield Exec(vm=self.vm, cmd=f"touch /etc/sudoers", sudo=self.sudo, su=self.su)
yield Exec(vm=self.vm, cmd=f"chmod 750 /etc/sudoers", sudo=self.sudo, su=self.su)
# yield Exec(vm=self.vm, cmd=f"sudo sed -i '/^Defaults[ \t]*targetpw/d' /etc/sudoers", sudo=self.sudo, su=self.su)
yield Exec(vm=self.vm, cmd=f"""echo "{self.user} ALL=(ALL:ALL) ALL" >> /tmp/sudoers.tmp""", sudo=self.sudo, su=self.su)
yield Exec(vm=self.vm, cmd=f"visudo -c -f /tmp/sudoers.tmp && cp /tmp/sudoers.tmp /etc/sudoers", sudo=self.sudo, su=self.su)
# yield Exec(vm=self.vm, cmd=f"chown root:root /etc/sudoers.d", sudo=self.sudo, su=self.su)
# yield Exec(vm=self.vm, cmd=f"chmod 440 /etc/sudoers.d", sudo=self.sudo, su=self.su)
# yield Exec(vm=self.vm, cmd=f"chmod 440 /etc/sudoers.d/{self.user}", sudo=self.sudo, su=self.su)
# # No rc-service or shadow on debian
# yield Exec(vm=self.vm, cmd=f"""sh -c "echo -e 'PasswordAuthentication yes\nPermitRootLogin no\nAllowUsers {self.user}' >> /etc/ssh/sshd_config && rc-service sshd restart" """, sudo=self.sudo,su=self.su)
# r=yield Mkpasswd(password=self.user_password)
# print(r.cp.stdout)
# yield Exec(vm=self.vm, cmd=f"""sh -c 'echo "{self.user}:{r.cp.stdout}" >> /etc/shadow'""", sudo=self.sudo,su=self.su)
#
# # yield Shell(f"lxc exec {self.vm} -- usermod --password '{r.cp.stdout}' {self.user}", sudo=self.sudo,su=self.su)
# # r=yield Mkpasswd(password=self.root_password)
# # yield Shell(f"lxc exec {self.vm} -- usermod --password '{r.cp.stdout}' root", sudo=self.sudo,su=self.su)
r=yield Get_ip(vm=self.vm, sudo=self.sudo,su=self.su)
ip_address=r.cp.stdout
yield Shell(f"ssh-keyscan {ip_address} >> ~/.ssh/known_hosts", sudo=self.sudo,su=self.su)
make_inventory(
inventory_filename=f"inventory-{self.vm}.py",
image=self.image,
vm=self.vm,
name=self.name,
user=self.user,
user_password=self.user_password,
root_password=self.root_password,
ip_address=ip_address
)
# Write the output to the console
output = f"""{self.image} virtual machine {self.vm} started
view credentials at http://{ip_address}
ssh access:
ssh {self.user}@{ip_address}
using password: {self.user_password}
the user {self.name} {self.user} has been added to the sudoers file
wrote inventory file inventory-{self.vm}.py"""
print(output)