Skip to content

Commit

Permalink
Feat | Add launch functionality
Browse files Browse the repository at this point in the history
and more refractoring
  • Loading branch information
rywng committed Jul 8, 2022
1 parent 311ceb8 commit 95511b4
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 57 deletions.
29 changes: 8 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,11 @@

## Examples

🚧 Under construction 🚧

## Development Roadmap

- [x] v0.1 yaml processing, args processing
- [x] config file
- [x] args processing
- [x] v0.2 basic feature complete
- [x] `info` show info
- [x] `mount` mounts the chroot
- [x] `unmount` unmount the chroot
- [x] `login` enter shell for the chroot
- [ ] v0.3 advanced features
- [x] PyPI file structure
- [x] Install default config file when not found
- [x] distro specific settings
- [x] `update` update software on target chroot
- [ ] `launch` mount chroot, launch program, and unmount after program closed in one go
- [x] `list` lists available chroots
- [x] Colorful output and debug info
- [ ] `install` download and install chroots from presets
[![asciicast](https://asciinema.org/a/FdD1pQQ3XlXO5TnafexJe1C8p.svg)](https://asciinema.org/a/FdD1pQQ3XlXO5TnafexJe1C8p)

## Installing

```bash
pip install ChrootMan
chrootman -h
```
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "ChrootMan"
version = "v0.3.2"
version = "v0.3.3"
description = "Cli application to manage Chroots"
readme = "README.md"
requires-python = ">=3.7"
Expand Down
81 changes: 53 additions & 28 deletions src/ChrootMan/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
chkMountStatus,
findLocation,
getChrootCommand,
ensureMount,
suRunCommand,
cliAskChoice,
)
import logging

Expand All @@ -18,19 +18,25 @@ def list(config_data, args):
logging.debug(f"Arg is not used {args}")
print(f"{colored('Available','green')} {colored('chroots', 'yellow')}:")
for item in config_data["chroots"]:
print(colored(item, 'yellow'))
print(colored(item, "yellow"))


# Show info of specified chroot
def showinfo(config_data, args):
chroot_name = args["chroot_name"]
print(f"{colored('Name','green')}: \t\t{colored(chroot_name, 'yellow')}")
try:
print(f"{colored('Description', 'green')}: \t{colored(config_data['chroots'][chroot_name]['description'], 'yellow')}")
print(
f"{colored('Description', 'green')}: \t{colored(config_data['chroots'][chroot_name]['description'], 'yellow')}"
)
except:
logging.warn("Description not found, skipping")
print(f"{colored('Location', 'green')}: \t{colored(findLocation(config_data, chroot_name), 'yellow')}")
print(f"{colored('Distro', 'green')}: \t{colored(config_data['chroots'][chroot_name]['distro'], 'yellow')}")
print(
f"{colored('Location', 'green')}: \t{colored(findLocation(config_data, chroot_name), 'yellow')}"
)
print(
f"{colored('Distro', 'green')}: \t{colored(config_data['chroots'][chroot_name]['distro'], 'yellow')}"
)


# Execute mount-command from settings
Expand All @@ -44,7 +50,7 @@ def mount(config_data, args, chroot_name=None):
distro = config_data["chroots"][chroot_name]["distro"]

# check whether to use default or not
mount_command = getChrootCommand(config_data, distro, chroot_name, "mount-command")
mount_command = getChrootCommand(config_data, "mount-command", distro, chroot_name)
suRunCommand(config_data, chroot_name, su_provider, mount_command, "mount_command")


Expand All @@ -53,8 +59,15 @@ def unmount(config_data, args):
su_provider = config_data["general"]["su-provider"]
distro = config_data["chroots"][chroot_name]["distro"]

if not chkMountStatus(config_data, chroot_name):
logging.error(f"{chroot_name} is not mounted.")
exit(1)

unmount_command = getChrootCommand(
config_data, distro, chroot_name, "unmount-command"
config_data,
"unmount-command",
distro,
chroot_name,
)
suRunCommand(
config_data, chroot_name, su_provider, unmount_command, "unmount_command"
Expand All @@ -63,33 +76,43 @@ def unmount(config_data, args):

def login(config_data, args):
chroot_name = args["chroot_name"]
if not chkMountStatus(config_data, chroot_name):
logging.error("Filesystem is not mounted! Do you want to mount it first?")
if cliAskChoice():
mount(config_data, args)
login(config_data, args)
return

if ensureMount(config_data, chroot_name, args, mount, login):
return

su_provider = config_data["general"]["su-provider"]
distro = config_data["chroots"][chroot_name]["distro"]

login_command = getChrootCommand(config_data, distro, chroot_name, "login-command")
suRunCommand(config_data, chroot_name, su_provider, login_command, "login_command")
login_command = getChrootCommand(config_data, "login-command", distro, chroot_name)
suRunCommand(config_data, chroot_name, su_provider, login_command, "login-command")


def launch(config_data, args):
chroot_name = args["chroot_name"]

if ensureMount(config_data, chroot_name, args, mount, launch):
return

def updateChroot(config_data, args, chroot_name):
su_provider = config_data["general"]["su-provider"]
distro = config_data["chroots"][chroot_name]["distro"]
launch_command = getChrootCommand(
config_data, "launch-command", distro, chroot_name
)
suRunCommand(config_data, chroot_name, su_provider, launch_command, "login-command")

unmount(config_data, args)


def updateChroot(config_data, args):
chroot_name = args["chroot_name"]
su_provider = config_data["general"]["su-provider"]
distro = config_data["chroots"][chroot_name]["distro"]
update_command = getChrootCommand(
config_data, distro, chroot_name, "update-command"
config_data, "update-command", distro, chroot_name
)

if not chkMountStatus(config_data, chroot_name):
logging.error("Filesystem is not mounted! Do you want to mount it first?")
if cliAskChoice():
mount(config_data, args, chroot_name=chroot_name)
update(config_data, args)
return
if ensureMount(config_data, chroot_name, args, mount, updateChroot):
return

suRunCommand(
config_data, chroot_name, su_provider, update_command, "update_command"
Expand All @@ -100,13 +123,15 @@ def update(config_data, args):
if not args["chroot_name"]:
logging.debug("chroot_name arg is not found")
if not args["all"]:
print(f"{colored('chroot_name', 'yellow')} not specified, assuming {colored('--all', 'green')}")
print(
f"{colored('chroot_name', 'yellow')} not specified, assuming {colored('--all', 'green')}"
)

for chroot in config_data["chroots"]:
print(f" {colored('Updating', 'green')}: {colored(chroot, 'yellow')}")
updateChroot(config_data, args, chroot)
args["chroot_name"] = chroot
updateChroot(config_data, args)

else:
chroot_name = args["chroot_name"]
logging.debug(f"Updating {chroot_name}")
updateChroot(config_data, args, chroot_name)
logging.debug(f"Updating {args['chroot_name']}")
updateChroot(config_data, args)
3 changes: 3 additions & 0 deletions src/ChrootMan/files/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ chroots:
distro: arch
# (Optional) Description of your chroot
description: Arch linux chroot for running wine softwares
launch-command: |
chroot $rootfs_location unshare su -l steam -c "DISPLAY=:0 steam -no-cef-sandbox && exit"
debian:
location: debian
distro: default
32 changes: 25 additions & 7 deletions src/ChrootMan/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@


def cliAskChoice():
yes = {"yes", "yep", "y", "ye"}
yes = {"yes", "yep", "y", "ye", ""}
no = {"no", "nope", "n"}

choice = input(f"{colored('Input', 'blue')}: ({colored('y','green')}/{colored('n', 'red')}) > ").lower()
Expand All @@ -18,7 +18,7 @@ def cliAskChoice():
return False
else:
print(f" Please respond with '{colored('y', 'green')}' or '{colored('n', 'red')}'")
cliAskChoice()
return cliAskChoice()


def findLocation(config_data, chroot_name):
Expand All @@ -43,12 +43,21 @@ def validChrootName(config_data, chroot_name):
return True


def getChrootCommand(config_data, distro, chroot_name, command_name):
def getChrootCommand(config_data, command_name, distro = None, chroot_name = None):
# chroots-settings -> distro-settings -> default-distro-settings
debug(f"distro: {distro}, chroot_name: {chroot_name}, command_name: {command_name}")
try:
command = config_data["general"]["distro-settings"][distro][command_name]
command = config_data["chroots"][chroot_name][command_name]
except KeyError:
debug("distro is not in configured list, using default")
command = config_data["general"]["distro-settings"]["default"][command_name]
try:
command = config_data["general"]["distro-settings"][distro][command_name]
except KeyError:
try:
debug("distro is not in configured list, using default")
command = config_data["general"]["distro-settings"]["default"][command_name]
except KeyError:
error("KeyError: Make sure you have properly configured the chroots")
exit(1)

command = command.replace(
"$rootfs_location", findLocation(config_data, chroot_name)
Expand All @@ -58,10 +67,19 @@ def getChrootCommand(config_data, distro, chroot_name, command_name):
return command


def ensureMount(config_data, chroot_name, args, mount_func, command_func):
if not chkMountStatus(config_data, chroot_name):
error("Filesystem is not mounted! Do you want to mount it first?")
if cliAskChoice():
mount_func(config_data, args)
command_func(config_data, args)
return True
return False


def chkMountStatus(config_data, chroot_name):
chrootPath = findLocation(config_data, chroot_name).replace("~", environ["HOME"])
output = subprocess.run(["mount"], capture_output=True).stdout
debug(f"Path is: {chrootPath}, mountpoints are: {str(output)}")
if chrootPath in str(output):
return True
else:
Expand Down
8 changes: 8 additions & 0 deletions src/ChrootMan/parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,14 @@ def add_subcommands(subparsers):
)
login_parser.set_defaults(func=login)

launch_parser = subparsers.add_parser(
"launch", help="launch chroot using command specified in chroot"
)
launch_parser.add_argument(
"chroot_name", type=str, help="specify name of chroot to launch"
)
launch_parser.set_defaults(func=launch)

update_parser = subparsers.add_parser("update", help="update to specified chroot")
update_parser.add_argument(
"chroot_name",
Expand Down

0 comments on commit 95511b4

Please sign in to comment.