Add missing changes
This commit is contained in:
parent
eea89f26cc
commit
451ffc2667
3 changed files with 270 additions and 301 deletions
196
blend
196
blend
|
@ -1,32 +1,38 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# Copyright (C) 2023 Rudra Saraswat
|
# Copyright (C) 2023 Rudra Saraswat
|
||||||
#
|
#
|
||||||
# This file is part of blend.
|
# This file is part of blend.
|
||||||
#
|
#
|
||||||
# blend is free software: you can redistribute it and/or modify
|
# blend is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# blend is distributed in the hope that it will be useful,
|
# blend is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with blend. If not, see <http://www.gnu.org/licenses/>.
|
# along with blend. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
import os, sys, getpass, time
|
import os
|
||||||
|
import sys
|
||||||
|
import glob
|
||||||
|
import time
|
||||||
import shutil
|
import shutil
|
||||||
import socket
|
import socket
|
||||||
|
import getpass
|
||||||
import pexpect
|
import pexpect
|
||||||
import argparse
|
import argparse
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
__version = '2.0.0'
|
__version = '2.0.0'
|
||||||
|
|
||||||
### Colors
|
# Colors
|
||||||
|
|
||||||
|
|
||||||
class colors:
|
class colors:
|
||||||
reset = '\033[0m'
|
reset = '\033[0m'
|
||||||
bold = '\033[01m'
|
bold = '\033[01m'
|
||||||
|
@ -63,17 +69,22 @@ class colors:
|
||||||
cyan = '\033[46m'
|
cyan = '\033[46m'
|
||||||
lightgrey = '\033[47m'
|
lightgrey = '\033[47m'
|
||||||
|
|
||||||
### END
|
# END
|
||||||
|
|
||||||
|
# Helper functions
|
||||||
|
|
||||||
### Helper functions
|
|
||||||
|
|
||||||
def info(msg):
|
def info(msg):
|
||||||
print (colors.bold + colors.fg.cyan + '>> i: ' + colors.reset + colors.bold + msg + colors.reset)
|
print(colors.bold + colors.fg.cyan + '>> i: ' +
|
||||||
|
colors.reset + colors.bold + msg + colors.reset)
|
||||||
|
|
||||||
|
|
||||||
def error(err):
|
def error(err):
|
||||||
print (colors.bold + colors.fg.red + '>> e: ' + colors.reset + colors.bold + err + colors.reset)
|
print(colors.bold + colors.fg.red + '>> e: ' +
|
||||||
|
colors.reset + colors.bold + err + colors.reset)
|
||||||
|
|
||||||
|
# END
|
||||||
|
|
||||||
### END
|
|
||||||
|
|
||||||
distro_map = {
|
distro_map = {
|
||||||
'arch': 'docker.io/library/archlinux',
|
'arch': 'docker.io/library/archlinux',
|
||||||
|
@ -84,6 +95,7 @@ distro_map = {
|
||||||
|
|
||||||
default_distro = 'arch'
|
default_distro = 'arch'
|
||||||
|
|
||||||
|
|
||||||
def get_distro():
|
def get_distro():
|
||||||
try:
|
try:
|
||||||
return distro_map[args.distro]
|
return distro_map[args.distro]
|
||||||
|
@ -91,9 +103,10 @@ def get_distro():
|
||||||
error(f"{args.distro} isn't supported by blend.")
|
error(f"{args.distro} isn't supported by blend.")
|
||||||
exit()
|
exit()
|
||||||
|
|
||||||
|
|
||||||
def list_containers():
|
def list_containers():
|
||||||
_list = subprocess.run(['podman', 'ps', '-a', '--no-trunc', '--size', '--format',
|
_list = subprocess.run(['podman', 'ps', '-a', '--no-trunc', '--size', '--format',
|
||||||
'{{.Names}}:{{.Mounts}}'], stdout=subprocess.PIPE).stdout.decode('utf-8').strip()
|
'{{.Names}}:{{.Mounts}}'], stdout=subprocess.PIPE).stdout.decode('utf-8').strip()
|
||||||
if len(_list) == 0:
|
if len(_list) == 0:
|
||||||
info('No containers. Create one by installing a package (`blend install hello`), or manually create one (`blend create-container arch`).')
|
info('No containers. Create one by installing a package (`blend install hello`), or manually create one (`blend create-container arch`).')
|
||||||
else:
|
else:
|
||||||
|
@ -103,21 +116,25 @@ def list_containers():
|
||||||
print(f"{colors.bold}{i}.{colors.reset} {container.split(':')[0]}")
|
print(f"{colors.bold}{i}.{colors.reset} {container.split(':')[0]}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def check_container(name):
|
def check_container(name):
|
||||||
_list = subprocess.run(['podman', 'ps', '-a', '--no-trunc', '--size', '--format',
|
_list = subprocess.run(['podman', 'ps', '-a', '--no-trunc', '--size', '--format',
|
||||||
'{{.Names}}:{{.Mounts}}'], stdout=subprocess.PIPE).stdout.decode('utf-8').strip()
|
'{{.Names}}:{{.Mounts}}'], stdout=subprocess.PIPE).stdout.decode('utf-8').strip()
|
||||||
for container in _list.splitlines(keepends=False):
|
for container in _list.splitlines(keepends=False):
|
||||||
if ('blend' in container.split(':')[1] or 'distrobox' in container.split(':')[1]) and name.strip() == container.split(':')[0]:
|
if ('blend' in container.split(':')[1] or 'distrobox' in container.split(':')[1]) and name.strip() == container.split(':')[0]:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def check_container_status(name):
|
|
||||||
|
def check_container_status(name):
|
||||||
return host_get_output("podman inspect --type container " + name + " --format \"{{.State.Status}}\"")
|
return host_get_output("podman inspect --type container " + name + " --format \"{{.State.Status}}\"")
|
||||||
|
|
||||||
def core_start_container(name):
|
|
||||||
subprocess.call(['podman', 'start', name], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
|
||||||
|
|
||||||
start_time = time.time() - 1000 # workaround
|
def core_start_container(name):
|
||||||
|
subprocess.call(['podman', 'start', name],
|
||||||
|
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||||
|
|
||||||
|
start_time = time.time() - 1000 # workaround
|
||||||
if check_container_status(name) != 'running':
|
if check_container_status(name) != 'running':
|
||||||
print('')
|
print('')
|
||||||
error('the entry point failed to run; try again later')
|
error('the entry point failed to run; try again later')
|
||||||
|
@ -125,12 +142,14 @@ def core_start_container(name):
|
||||||
subprocess.call(['podman', 'logs', '--since', str(start_time), name])
|
subprocess.call(['podman', 'logs', '--since', str(start_time), name])
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
logproc = pexpect.spawn('podman', args=['logs', '-f', '--since', str(start_time), name], timeout=300)
|
logproc = pexpect.spawn(
|
||||||
|
'podman', args=['logs', '-f', '--since', str(start_time), name], timeout=300)
|
||||||
logproc.logfile_read = sys.stdout.buffer
|
logproc.logfile_read = sys.stdout.buffer
|
||||||
|
|
||||||
logproc.expect('Completed container setup.')
|
logproc.expect('Completed container setup.')
|
||||||
logproc.terminate()
|
logproc.terminate()
|
||||||
|
|
||||||
|
|
||||||
def core_create_container():
|
def core_create_container():
|
||||||
name = args.container_name
|
name = args.container_name
|
||||||
distro = args.distro
|
distro = args.distro
|
||||||
|
@ -145,32 +164,39 @@ def core_create_container():
|
||||||
podman_command.extend(['--network', 'host'])
|
podman_command.extend(['--network', 'host'])
|
||||||
podman_command.extend(['--security-opt', 'label=disable'])
|
podman_command.extend(['--security-opt', 'label=disable'])
|
||||||
podman_command.extend(['--user', 'root:root', '--pid', 'host'])
|
podman_command.extend(['--user', 'root:root', '--pid', 'host'])
|
||||||
podman_command.extend(['--label', 'manager=blend']) # identify as blend container
|
# identify as blend container
|
||||||
|
podman_command.extend(['--label', 'manager=blend'])
|
||||||
|
|
||||||
# Env variables
|
# Env variables
|
||||||
podman_command.extend(['--env', 'HOME=' + os.path.expanduser('~')])
|
podman_command.extend(['--env', 'HOME=' + os.path.expanduser('~')])
|
||||||
|
podman_command.extend(['--env', 'CONTAINER_NAME=' + name])
|
||||||
|
|
||||||
# Volumes
|
# Volumes
|
||||||
podman_command.extend(['--volume', '/:/run/host:rslave'])
|
podman_command.extend(['--volume', '/:/run/host:rslave'])
|
||||||
podman_command.extend(['--volume', '/tmp:/tmp:rslave'])
|
podman_command.extend(['--volume', '/tmp:/tmp:rslave'])
|
||||||
podman_command.extend(['--volume', f"{os.path.expanduser('~')}:{os.path.expanduser('~')}:rslave"])
|
podman_command.extend(
|
||||||
podman_command.extend(['--volume', f"/run/user/{os.geteuid()}:/run/user/{os.geteuid()}:rslave"])
|
['--volume', f"{os.path.expanduser('~')}:{os.path.expanduser('~')}:rslave"])
|
||||||
|
podman_command.extend(
|
||||||
|
['--volume', f"/run/user/{os.geteuid()}:/run/user/{os.geteuid()}:rslave"])
|
||||||
|
|
||||||
# Volumes (config files)
|
# Volumes (config files)
|
||||||
podman_command.extend(['--volume', f"/etc/hosts:/etc/hosts:ro"])
|
podman_command.extend(['--volume', f"/etc/hosts:/etc/hosts:ro"])
|
||||||
podman_command.extend(['--volume', f"/etc/localtime:/etc/localtime:ro"])
|
podman_command.extend(['--volume', f"/etc/localtime:/etc/localtime:ro"])
|
||||||
podman_command.extend(['--volume', f"/etc/resolv.conf:/etc/resolv.conf:ro"])
|
podman_command.extend(
|
||||||
|
['--volume', f"/etc/resolv.conf:/etc/resolv.conf:ro"])
|
||||||
|
|
||||||
# Volumes (files and tools)
|
# Volumes (files and tools)
|
||||||
podman_command.extend(['--volume', '/usr/bin/init-blend:/usr/bin/init-blend:ro',
|
podman_command.extend(['--volume', '/usr/bin/init-blend:/usr/bin/init-blend:ro',
|
||||||
'--entrypoint', '/usr/bin/init-blend']) # our entrypoint
|
'--entrypoint', '/usr/bin/init-blend']) # our entrypoint
|
||||||
podman_command.extend(['--volume', '/usr/bin/host-blend:/usr/bin/host-blend:ro']) # and the tool to run commands on the host
|
# and the tool to run commands on the host
|
||||||
|
podman_command.extend(
|
||||||
|
['--volume', '/usr/bin/host-blend:/usr/bin/host-blend:ro'])
|
||||||
podman_command.extend(['--volume', '/var/log/journal'])
|
podman_command.extend(['--volume', '/var/log/journal'])
|
||||||
|
|
||||||
podman_command.extend(['--mount', 'type=devpts,destination=/dev/pts',
|
podman_command.extend(['--mount', 'type=devpts,destination=/dev/pts',
|
||||||
'--userns', 'keep-id',
|
'--userns', 'keep-id',
|
||||||
'--annotation', 'run.oci.keep_original_groups=1'])
|
'--annotation', 'run.oci.keep_original_groups=1'])
|
||||||
|
|
||||||
podman_command.extend([get_distro()])
|
podman_command.extend([get_distro()])
|
||||||
|
|
||||||
# User (for init-blend)
|
# User (for init-blend)
|
||||||
|
@ -189,17 +215,24 @@ def core_create_container():
|
||||||
|
|
||||||
core_start_container(name)
|
core_start_container(name)
|
||||||
|
|
||||||
core_get_output = lambda cmd: subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL).stdout.decode('UTF-8').strip()
|
|
||||||
|
|
||||||
host_get_output = lambda cmd: subprocess.run(['bash', '-c', cmd],
|
def core_get_output(cmd): return subprocess.run(
|
||||||
stdout=subprocess.PIPE, stderr=subprocess.DEVNULL).stdout.decode('UTF-8').strip()
|
cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL).stdout.decode('UTF-8').strip()
|
||||||
|
|
||||||
|
|
||||||
|
def host_get_output(cmd): return subprocess.run(['bash', '-c', cmd],
|
||||||
|
stdout=subprocess.PIPE, stderr=subprocess.DEVNULL).stdout.decode('UTF-8').strip()
|
||||||
|
|
||||||
|
|
||||||
|
def core_get_retcode(cmd): return subprocess.run(['podman', 'exec', '--user', getpass.getuser(), '-it', args.container_name, 'bash', '-c', cmd],
|
||||||
|
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL).returncode
|
||||||
|
|
||||||
core_get_retcode = lambda cmd: subprocess.run(['podman', 'exec', '--user', getpass.getuser(), '-it', args.container_name, 'bash', '-c', cmd],
|
|
||||||
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL).returncode
|
|
||||||
|
|
||||||
def core_run_container(cmd):
|
def core_run_container(cmd):
|
||||||
if os.getcwd() == os.path.expanduser('~') or os.getcwd().startswith(os.path.expanduser('~') + '/'):
|
if os.getcwd() == os.path.expanduser('~') or os.getcwd().startswith(os.path.expanduser('~') + '/'):
|
||||||
subprocess.call(['podman', 'exec', '--user', getpass.getuser(), '-w', os.getcwd(), '-it', args.container_name, 'bash', '-c', cmd])
|
subprocess.call(['podman', 'exec', '--user', getpass.getuser(),
|
||||||
|
'-w', os.getcwd(), '-it', args.container_name, 'bash', '-c', cmd])
|
||||||
|
|
||||||
|
|
||||||
def core_install_pkg(pkg):
|
def core_install_pkg(pkg):
|
||||||
if args.distro == 'fedora-rawhide':
|
if args.distro == 'fedora-rawhide':
|
||||||
|
@ -210,8 +243,10 @@ def core_install_pkg(pkg):
|
||||||
elif args.distro == 'arch':
|
elif args.distro == 'arch':
|
||||||
if core_get_retcode('[ -f /usr/bin/yay ]') != 0:
|
if core_get_retcode('[ -f /usr/bin/yay ]') != 0:
|
||||||
core_run_container('sudo pacman -Sy')
|
core_run_container('sudo pacman -Sy')
|
||||||
core_run_container('sudo pacman --noconfirm -Syu --needed git base-devel')
|
core_run_container(
|
||||||
core_run_container('TEMP_DIR="$(mktemp -d)"; cd "${TEMP_DIR}"; git clone https://aur.archlinux.org/yay.git; cd yay; makepkg --noconfirm -si; rm -rf "${TEMP_DIR}"')
|
'sudo pacman --noconfirm -Syu --needed git base-devel')
|
||||||
|
core_run_container(
|
||||||
|
'TEMP_DIR="$(mktemp -d)"; cd "${TEMP_DIR}"; git clone https://aur.archlinux.org/yay.git; cd yay; makepkg --noconfirm -si; rm -rf "${TEMP_DIR}"')
|
||||||
core_run_container(f'yay -Sy')
|
core_run_container(f'yay -Sy')
|
||||||
if args.noconfirm == True:
|
if args.noconfirm == True:
|
||||||
core_run_container(f'yay --noconfirm -Syu {pkg}')
|
core_run_container(f'yay --noconfirm -Syu {pkg}')
|
||||||
|
@ -224,6 +259,7 @@ def core_install_pkg(pkg):
|
||||||
else:
|
else:
|
||||||
core_run_container(f'sudo apt-get install {pkg}')
|
core_run_container(f'sudo apt-get install {pkg}')
|
||||||
|
|
||||||
|
|
||||||
def core_remove_pkg(pkg):
|
def core_remove_pkg(pkg):
|
||||||
if args.distro == 'fedora-rawhide':
|
if args.distro == 'fedora-rawhide':
|
||||||
if args.noconfirm == True:
|
if args.noconfirm == True:
|
||||||
|
@ -242,6 +278,7 @@ def core_remove_pkg(pkg):
|
||||||
core_run_container(f'sudo apt-get purge {pkg}')
|
core_run_container(f'sudo apt-get purge {pkg}')
|
||||||
core_run_container(f'sudo apt-get autoremove --purge -y {pkg}')
|
core_run_container(f'sudo apt-get autoremove --purge -y {pkg}')
|
||||||
|
|
||||||
|
|
||||||
def core_search_pkg(pkg):
|
def core_search_pkg(pkg):
|
||||||
if args.distro == 'fedora-rawhide':
|
if args.distro == 'fedora-rawhide':
|
||||||
core_run_container(f'dnf search {pkg}')
|
core_run_container(f'dnf search {pkg}')
|
||||||
|
@ -252,6 +289,7 @@ def core_search_pkg(pkg):
|
||||||
core_run_container(f'sudo apt-get update')
|
core_run_container(f'sudo apt-get update')
|
||||||
core_run_container(f'apt-cache search {pkg}')
|
core_run_container(f'apt-cache search {pkg}')
|
||||||
|
|
||||||
|
|
||||||
def core_show_pkg(pkg):
|
def core_show_pkg(pkg):
|
||||||
if args.distro == 'fedora-rawhide':
|
if args.distro == 'fedora-rawhide':
|
||||||
core_run_container(f'dnf info {pkg}')
|
core_run_container(f'dnf info {pkg}')
|
||||||
|
@ -262,6 +300,7 @@ def core_show_pkg(pkg):
|
||||||
core_run_container(f'sudo apt-get update')
|
core_run_container(f'sudo apt-get update')
|
||||||
core_run_container(f'apt-cache show {pkg}')
|
core_run_container(f'apt-cache show {pkg}')
|
||||||
|
|
||||||
|
|
||||||
def install_blend():
|
def install_blend():
|
||||||
if len(args.pkg) == 0:
|
if len(args.pkg) == 0:
|
||||||
error('no packages to install')
|
error('no packages to install')
|
||||||
|
@ -272,6 +311,7 @@ def install_blend():
|
||||||
core_create_container()
|
core_create_container()
|
||||||
core_install_pkg(pkg)
|
core_install_pkg(pkg)
|
||||||
|
|
||||||
|
|
||||||
def remove_blend():
|
def remove_blend():
|
||||||
if len(args.pkg) == 0:
|
if len(args.pkg) == 0:
|
||||||
error('no packages to remove')
|
error('no packages to remove')
|
||||||
|
@ -282,6 +322,7 @@ def remove_blend():
|
||||||
error(f"container {args.container_name} doesn't exist")
|
error(f"container {args.container_name} doesn't exist")
|
||||||
core_remove_pkg(pkg)
|
core_remove_pkg(pkg)
|
||||||
|
|
||||||
|
|
||||||
def search_blend():
|
def search_blend():
|
||||||
if len(args.pkg) == 0:
|
if len(args.pkg) == 0:
|
||||||
error('no packages to search for')
|
error('no packages to search for')
|
||||||
|
@ -291,6 +332,7 @@ def search_blend():
|
||||||
error(f"container {args.container_name} doesn't exist")
|
error(f"container {args.container_name} doesn't exist")
|
||||||
core_search_pkg(pkg)
|
core_search_pkg(pkg)
|
||||||
|
|
||||||
|
|
||||||
def show_blend():
|
def show_blend():
|
||||||
if len(args.pkg) == 0:
|
if len(args.pkg) == 0:
|
||||||
error('no packages to show')
|
error('no packages to show')
|
||||||
|
@ -301,6 +343,7 @@ def show_blend():
|
||||||
error(f"container {args.container_name} doesn't exist")
|
error(f"container {args.container_name} doesn't exist")
|
||||||
core_show_pkg(pkg)
|
core_show_pkg(pkg)
|
||||||
|
|
||||||
|
|
||||||
def sync_blends():
|
def sync_blends():
|
||||||
if args.distro == 'fedora-rawhide':
|
if args.distro == 'fedora-rawhide':
|
||||||
core_run_container(f'dnf makecache')
|
core_run_container(f'dnf makecache')
|
||||||
|
@ -309,6 +352,7 @@ def sync_blends():
|
||||||
elif args.distro.startswith('ubuntu-'):
|
elif args.distro.startswith('ubuntu-'):
|
||||||
core_run_container(f'sudo apt-get update')
|
core_run_container(f'sudo apt-get update')
|
||||||
|
|
||||||
|
|
||||||
def update_blends():
|
def update_blends():
|
||||||
if args.distro == 'fedora-rawhide':
|
if args.distro == 'fedora-rawhide':
|
||||||
if args.noconfirm == True:
|
if args.noconfirm == True:
|
||||||
|
@ -329,38 +373,42 @@ def update_blends():
|
||||||
else:
|
else:
|
||||||
error(f'distribution {args.distro} is not supported')
|
error(f'distribution {args.distro} is not supported')
|
||||||
|
|
||||||
|
|
||||||
def enter_container():
|
def enter_container():
|
||||||
if os.environ.get('BLEND_NO_CHECK') == None:
|
podman_args = ['--env', 'LC_ALL=C.UTF-8']
|
||||||
if not check_container(args.container_name):
|
|
||||||
core_create_container()
|
|
||||||
if check_container_status(args.container_name) != 'running':
|
|
||||||
core_start_container(args.container_name)
|
|
||||||
podman_args = []
|
|
||||||
sudo = []
|
sudo = []
|
||||||
if os.environ.get('SUDO_USER') == None:
|
if os.environ.get('SUDO_USER') == None:
|
||||||
podman_args = ['--user', getpass.getuser()]
|
podman_args = ['--user', getpass.getuser()]
|
||||||
else:
|
else:
|
||||||
sudo = ['sudo', '-u', os.environ.get('SUDO_USER'), f'PATH={os.path.expanduser("~/.local/share/bin/blend_bin")}:/usr/bin']
|
sudo = ['sudo', '-u', os.environ.get(
|
||||||
|
'SUDO_USER'), f'PATH={os.path.expanduser("~/.local/share/bin/blend_bin")}:/usr/bin']
|
||||||
for name, val in os.environ.items():
|
for name, val in os.environ.items():
|
||||||
if name not in ['LANG', 'LC_CTYPE', 'PATH', 'HOST', 'HOSTNAME', 'SHELL'] and not name.startswith('_'):
|
if name not in ['LANG', 'LC_CTYPE', 'LC_ALL', 'PATH', 'HOST', 'HOSTNAME', 'SHELL'] and not name.startswith('_'):
|
||||||
podman_args.append('--env')
|
podman_args.append('--env')
|
||||||
podman_args.append(name + '=' + val)
|
podman_args.append(name + '=' + val)
|
||||||
if os.environ.get('BLEND_COMMAND') == None or os.environ.get('BLEND_COMMAND') == '':
|
if os.environ.get('BLEND_COMMAND') == None or os.environ.get('BLEND_COMMAND') == '':
|
||||||
if args.pkg == []:
|
if args.pkg == []:
|
||||||
if os.getcwd() == os.path.expanduser('~') or os.getcwd().startswith(os.path.expanduser('~') + '/'):
|
if os.getcwd() == os.path.expanduser('~') or os.getcwd().startswith(os.path.expanduser('~') + '/'):
|
||||||
exit(subprocess.call([*sudo, 'podman', 'exec', *podman_args, '-w', os.getcwd(), '-it', args.container_name, 'bash']))
|
exit(subprocess.call([*sudo, 'podman', 'exec', *podman_args,
|
||||||
|
'-w', os.getcwd(), '-it', args.container_name, 'bash']))
|
||||||
else:
|
else:
|
||||||
exit(subprocess.call([*sudo, 'podman', 'exec', *podman_args, '-w', '/run/host' + os.getcwd(), '-it', args.container_name, 'bash']))
|
exit(subprocess.call([*sudo, 'podman', 'exec', *podman_args, '-w',
|
||||||
|
'/run/host' + os.getcwd(), '-it', args.container_name, 'bash']))
|
||||||
else:
|
else:
|
||||||
if os.getcwd() == os.path.expanduser('~') or os.getcwd().startswith(os.path.expanduser('~') + '/'):
|
if os.getcwd() == os.path.expanduser('~') or os.getcwd().startswith(os.path.expanduser('~') + '/'):
|
||||||
exit(subprocess.call([*sudo, 'podman', 'exec', *podman_args, '-w', os.getcwd(), '-it', args.container_name, *args.pkg]))
|
exit(subprocess.call([*sudo, 'podman', 'exec', *podman_args,
|
||||||
|
'-w', os.getcwd(), '-it', args.container_name, *args.pkg]))
|
||||||
else:
|
else:
|
||||||
exit(subprocess.call([*sudo, 'podman', 'exec', *podman_args, '-w', '/run/host' + os.getcwd(), '-it', args.container_name, *args.pkg]))
|
exit(subprocess.call([*sudo, 'podman', 'exec', *podman_args, '-w',
|
||||||
|
'/run/host' + os.getcwd(), '-it', args.container_name, *args.pkg]))
|
||||||
else:
|
else:
|
||||||
if os.getcwd() == os.path.expanduser('~') or os.getcwd().startswith(os.path.expanduser('~') + '/'):
|
if os.getcwd() == os.path.expanduser('~') or os.getcwd().startswith(os.path.expanduser('~') + '/'):
|
||||||
exit(subprocess.call([*sudo, 'podman', 'exec', *podman_args, '-w', os.getcwd(), '-it', args.container_name, 'bash', '-c', os.environ.get('BLEND_COMMAND')]))
|
exit(subprocess.call([*sudo, 'podman', 'exec', *podman_args, '-w', os.getcwd(
|
||||||
|
), '-it', args.container_name, 'bash', '-c', os.environ.get('BLEND_COMMAND')]))
|
||||||
else:
|
else:
|
||||||
exit(subprocess.call([*sudo, 'podman', 'exec', *podman_args, '-w', '/run/host' + os.getcwd(), '-it', args.container_name, 'bash']))
|
exit(subprocess.call([*sudo, 'podman', 'exec', *podman_args, '-w',
|
||||||
|
'/run/host' + os.getcwd(), '-it', args.container_name, 'bash']))
|
||||||
|
|
||||||
|
|
||||||
def create_container():
|
def create_container():
|
||||||
for container in args.pkg:
|
for container in args.pkg:
|
||||||
|
@ -369,15 +417,22 @@ def create_container():
|
||||||
args.distro = container
|
args.distro = container
|
||||||
core_create_container()
|
core_create_container()
|
||||||
|
|
||||||
|
|
||||||
def remove_container():
|
def remove_container():
|
||||||
for container in args.pkg:
|
for container in args.pkg:
|
||||||
info(f'removing container {container}')
|
info(f'removing container {container}')
|
||||||
subprocess.run(['podman', 'stop', container], stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL)
|
subprocess.run(['podman', 'stop', container],
|
||||||
subprocess.run(['podman', 'rm', '-f', container], stdout=subprocess.DEVNULL)
|
stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL)
|
||||||
|
subprocess.run(['podman', 'rm', '-f', container],
|
||||||
|
stdout=subprocess.DEVNULL)
|
||||||
|
for bin in os.listdir(os.path.expanduser('~/.local/bin/blend_bin')):
|
||||||
|
if bin.endswith(f'.{container}'):
|
||||||
|
os.remove(os.path.join(os.path.expanduser('~/.local/bin/blend_bin'), bin))
|
||||||
|
|
||||||
|
|
||||||
def start_containers():
|
def start_containers():
|
||||||
_list = subprocess.run(['podman', 'ps', '-a', '--no-trunc', '--size', '--format',
|
_list = subprocess.run(['podman', 'ps', '-a', '--no-trunc', '--size', '--format',
|
||||||
'{{.Names}}:{{.Mounts}}'], stdout=subprocess.PIPE).stdout.decode('utf-8').strip()
|
'{{.Names}}:{{.Mounts}}'], stdout=subprocess.PIPE).stdout.decode('utf-8').strip()
|
||||||
if len(_list) == 0:
|
if len(_list) == 0:
|
||||||
info('No containers. Create one by installing a package (`blend install hello`), or manually create one (`blend create-container -d arch`).')
|
info('No containers. Create one by installing a package (`blend install hello`), or manually create one (`blend create-container -d arch`).')
|
||||||
for container in _list.splitlines(keepends=False):
|
for container in _list.splitlines(keepends=False):
|
||||||
|
@ -385,6 +440,7 @@ def start_containers():
|
||||||
info(f'starting container {container}')
|
info(f'starting container {container}')
|
||||||
subprocess.call(['podman', 'start', container])
|
subprocess.call(['podman', 'start', container])
|
||||||
|
|
||||||
|
|
||||||
if shutil.which('podman') is None:
|
if shutil.which('podman') is None:
|
||||||
error("podman isn't installed, which is a hard dep")
|
error("podman isn't installed, which is a hard dep")
|
||||||
exit(1)
|
exit(1)
|
||||||
|
@ -407,21 +463,27 @@ epilog = f'''
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description=description, usage=argparse.SUPPRESS,
|
parser = argparse.ArgumentParser(description=description, usage=argparse.SUPPRESS,
|
||||||
epilog=epilog, formatter_class=argparse.RawTextHelpFormatter)
|
epilog=epilog, formatter_class=argparse.RawTextHelpFormatter)
|
||||||
command_map = { 'enter': enter_container,
|
command_map = {'enter': enter_container,
|
||||||
'exec': enter_container,
|
'exec': enter_container,
|
||||||
'create-container': core_create_container,
|
'create-container': core_create_container,
|
||||||
'remove-container': remove_container,
|
'remove-container': remove_container,
|
||||||
'list-containers': list_containers,
|
'list-containers': list_containers,
|
||||||
'start-containers': start_containers,
|
'start-containers': start_containers,
|
||||||
'sync': sync_blends,
|
'sync': sync_blends,
|
||||||
'help': 'help',
|
'help': 'help',
|
||||||
'version': 'version' }
|
'version': 'version'}
|
||||||
parser.add_argument('command', choices=command_map.keys(), help=argparse.SUPPRESS)
|
parser.add_argument('command', choices=command_map.keys(),
|
||||||
parser.add_argument('pkg', action='store', type=str, nargs='*', help=argparse.SUPPRESS)
|
help=argparse.SUPPRESS)
|
||||||
parser.add_argument('-cn', '--container-name', action='store', nargs=1, metavar='CONTAINER NAME', help=argparse.SUPPRESS)
|
parser.add_argument('pkg', action='store', type=str,
|
||||||
parser.add_argument('-y', '--noconfirm', action='store_true', help=argparse.SUPPRESS)
|
nargs='*', help=argparse.SUPPRESS)
|
||||||
parser.add_argument('-d', '--distro', action='store', nargs=1, metavar='DISTRO', help=argparse.SUPPRESS)
|
parser.add_argument('-cn', '--container-name', action='store',
|
||||||
parser.add_argument('-v', '--version', action='version', version=f'%(prog)s {__version}', help=argparse.SUPPRESS)
|
nargs=1, metavar='CONTAINER NAME', help=argparse.SUPPRESS)
|
||||||
|
parser.add_argument('-y', '--noconfirm',
|
||||||
|
action='store_true', help=argparse.SUPPRESS)
|
||||||
|
parser.add_argument('-d', '--distro', action='store', nargs=1,
|
||||||
|
metavar='DISTRO', help=argparse.SUPPRESS)
|
||||||
|
parser.add_argument('-v', '--version', action='version',
|
||||||
|
version=f'%(prog)s {__version}', help=argparse.SUPPRESS)
|
||||||
|
|
||||||
if len(sys.argv) == 1:
|
if len(sys.argv) == 1:
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
|
|
235
blend-files
235
blend-files
|
@ -1,242 +1,19 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
|
||||||
import yaml
|
|
||||||
import time
|
|
||||||
import glob
|
|
||||||
import getpass
|
|
||||||
import fileinput
|
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
|
|
||||||
def get_containers():
|
def get_containers():
|
||||||
container_list = subprocess.run(['sudo', '-u', user, 'podman', 'ps', '-a', '--no-trunc', '--sort=created', '--format',
|
return subprocess.run(['podman', 'ps', '-a', '--no-trunc', '--sort=created', '--format',
|
||||||
'{{.Names}}'], stdout=subprocess.PIPE).stdout.decode('utf-8').strip().split('\n')
|
'{{.Names}}'], stdout=subprocess.PIPE).stdout.decode('utf-8').strip().split('\n')
|
||||||
|
|
||||||
try:
|
if os.path.isdir(os.path.expanduser('~/.local/bin/blend_bin')) and not os.path.isfile(os.path.expanduser('~/.local/bin/blend_bin/.associations')):
|
||||||
with open(os.path.expanduser('~/.config/blend/config.yaml')) as config_file:
|
subprocess.call(['rm', '-rf', os.path.expanduser('~/.local/bin/blend_bin')], shell=False)
|
||||||
data = yaml.safe_load(config_file)
|
subprocess.call(['bash', '-c', 'rm -f "${HOME}/.local/share/applications/blend;"*'], shell=False)
|
||||||
order = data['container_order'].copy()
|
|
||||||
order.reverse()
|
|
||||||
container_list.reverse()
|
|
||||||
for i in container_list:
|
|
||||||
if i.strip() not in order:
|
|
||||||
order.insert(0, i)
|
|
||||||
for i, o in enumerate(order):
|
|
||||||
if o not in container_list:
|
|
||||||
del order[i]
|
|
||||||
return order
|
|
||||||
except:
|
|
||||||
return container_list
|
|
||||||
|
|
||||||
|
subprocess.call(['mkdir', '-p', os.path.expanduser('~/.local/bin/blend_bin/')])
|
||||||
def list_use_container_bin():
|
subprocess.call(['touch', os.path.expanduser('~/.local/bin/blend_bin/.associations')], shell=False)
|
||||||
try:
|
|
||||||
with open(os.path.expanduser('~/.config/blend/config.yaml')) as config_file:
|
|
||||||
data = yaml.safe_load(config_file)
|
|
||||||
return data['use_container_bins']
|
|
||||||
except:
|
|
||||||
return []
|
|
||||||
|
|
||||||
|
|
||||||
def check_if_present(attr, desktop_str):
|
|
||||||
for l in desktop_str:
|
|
||||||
if l.startswith(attr + '='):
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def which(bin):
|
|
||||||
results = []
|
|
||||||
for dir in os.environ.get('PATH').split(':'):
|
|
||||||
if os.path.isdir(dir):
|
|
||||||
if os.path.basename(bin) in os.listdir(dir):
|
|
||||||
results.append(os.path.join(dir, os.path.basename(bin)))
|
|
||||||
if results == []:
|
|
||||||
return None
|
|
||||||
return results
|
|
||||||
|
|
||||||
|
|
||||||
def create_container_binaries():
|
|
||||||
_binaries = []
|
|
||||||
remove_binaries = []
|
|
||||||
|
|
||||||
for c in _list:
|
|
||||||
c = c.strip()
|
|
||||||
for i in con_get_output(c, '''find /usr/bin -type f -printf "%P\n" 2>/dev/null;
|
|
||||||
find -L /usr/bin -xtype l -type f -printf "%P\n" 2>/dev/null;
|
|
||||||
find /usr/local/bin -type f -printf "%P\n" 2>/dev/null;
|
|
||||||
find -L /usr/local/bin -xtype l -type f -printf "%P\n" 2>/dev/null;''').split('\n'):
|
|
||||||
i = i.strip()
|
|
||||||
os.makedirs(os.path.expanduser(
|
|
||||||
f'~/.local/bin/blend_{c}'), exist_ok=True)
|
|
||||||
i_present = False
|
|
||||||
orig_which_out = which(os.path.basename(i))
|
|
||||||
which_out = None
|
|
||||||
if orig_which_out != None:
|
|
||||||
which_out = orig_which_out.copy()
|
|
||||||
try:
|
|
||||||
which_out.remove(os.path.expanduser(
|
|
||||||
f'~/.local/bin/blend_bin/{os.path.basename(i)}'))
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
if which_out == []:
|
|
||||||
which_out = None
|
|
||||||
if which_out != None and os.path.basename(i) not in _exceptions:
|
|
||||||
i_present = True
|
|
||||||
|
|
||||||
if os.path.basename(i) != 'host-spawn' and i != '' and not i_present:
|
|
||||||
with open(os.path.expanduser(f'~/.local/bin/blend_{c}/{os.path.basename(i)}.tmp'), 'w') as f:
|
|
||||||
f.write('#!/bin/bash\n')
|
|
||||||
f.write(f'# blend container: {c};{i}\n')
|
|
||||||
if os.path.basename(i) in _exceptions:
|
|
||||||
f.write(f'# EXCEPTION\n')
|
|
||||||
f.write('[ -f /run/.containerenv ] && { if [[ -e "/usr/bin/' + os.path.basename(i) + '" ]] || [[ -e "/usr/local/bin/' + os.path.basename(i) + '" ]]; then if [[ -e "/usr/bin/' + os.path.basename(i) + '" ]]; then /usr/bin/' + os.path.basename(
|
|
||||||
i) + ' "$@"; elif [[ -e "/usr/local/bin/' + os.path.basename(i) + '" ]]; then /usr/local/bin/' + os.path.basename(i) + ' "$@"; fi; exit $?; else echo "This command can be accessed from the host, or from the container \'' + c + '\'."; exit 127; fi } || :\n')
|
|
||||||
f.write(
|
|
||||||
f'BLEND_ALLOW_ROOT= BLEND_NO_CHECK= blend enter -cn {c} -- {os.path.basename(i)} "$@"\n')
|
|
||||||
# XXX: make this bit fully atomic
|
|
||||||
os.chmod(os.path.expanduser(
|
|
||||||
f'~/.local/bin/blend_{c}/{os.path.basename(i)}.tmp'), 0o775)
|
|
||||||
subprocess.call(['mv', os.path.expanduser(f'~/.local/bin/blend_{c}/{os.path.basename(i)}.tmp'),
|
|
||||||
os.path.expanduser(f'~/.local/bin/blend_{c}/{os.path.basename(i)}')])
|
|
||||||
_binaries.append((c, os.path.basename(os.path.basename(i))))
|
|
||||||
|
|
||||||
os.makedirs(os.path.expanduser(f'~/.local/bin/blend_bin'), exist_ok=True)
|
|
||||||
|
|
||||||
for c, i in _binaries:
|
|
||||||
try:
|
|
||||||
os.symlink(os.path.expanduser(
|
|
||||||
f'~/.local/bin/blend_{c}/{i}'), os.path.expanduser(f'~/.local/bin/blend_bin/{i}'))
|
|
||||||
except FileExistsError:
|
|
||||||
if subprocess.call(['grep', '-q', f'^# container: {c};{i}$', os.path.expanduser(f'~/.local/bin/blend_bin/{i}')], shell=False):
|
|
||||||
os.remove(os.path.expanduser(f'~/.local/bin/blend_bin/{i}'))
|
|
||||||
os.symlink(os.path.expanduser(
|
|
||||||
f'~/.local/bin/blend_{c}/{i}'), os.path.expanduser(f'~/.local/bin/blend_bin/{i}'))
|
|
||||||
|
|
||||||
for i in remove_binaries:
|
|
||||||
try:
|
|
||||||
os.remove(i)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
for b in os.listdir(os.path.expanduser(f'~/.local/bin/blend_bin')):
|
|
||||||
if [_b for _b in _binaries if _b[1] == b] == []:
|
|
||||||
os.remove(os.path.join(os.path.expanduser(
|
|
||||||
f'~/.local/bin/blend_bin'), b))
|
|
||||||
|
|
||||||
for b_dir in glob.glob(os.path.expanduser(f'~/.local/bin/blend_*')):
|
|
||||||
if os.path.basename(b_dir) != 'blend_bin' and os.path.basename(b_dir)[6:] not in _list:
|
|
||||||
subprocess.call(['rm', '-rf', b_dir], shell=False)
|
|
||||||
|
|
||||||
|
|
||||||
def create_container_applications():
|
|
||||||
_apps = []
|
|
||||||
|
|
||||||
os.makedirs(os.path.expanduser(
|
|
||||||
f'~/.local/share/applications'), exist_ok=True)
|
|
||||||
|
|
||||||
for c in _list:
|
|
||||||
c = c.strip()
|
|
||||||
for i in con_get_output(c, 'find /usr/share/applications -type f 2>/dev/null; find /usr/local/share/applications -type f 2>/dev/null').split('\n'):
|
|
||||||
orig_path = i.strip()
|
|
||||||
i = os.path.basename(orig_path)
|
|
||||||
i_present = (os.path.isfile(f'/usr/share/applications/{i}') or os.path.isfile(f'/usr/local/share/applications/{i}')
|
|
||||||
or os.path.isfile(os.path.expanduser(f'~/.local/share/applications/{i}')))
|
|
||||||
if i != '' and not i_present:
|
|
||||||
with open(os.path.expanduser(f'~/.local/share/applications/blend;{i}'), 'w') as f:
|
|
||||||
_ = con_get_output(
|
|
||||||
c, f"sudo sed -i '/^DBusActivatable=/d' {orig_path}")
|
|
||||||
_ = con_get_output(
|
|
||||||
c, f"sudo sed -i '/^TryExec=/d' {orig_path}")
|
|
||||||
contents = con_get_output(c, f'cat {orig_path}')
|
|
||||||
f.write(contents)
|
|
||||||
for line in fileinput.input(os.path.expanduser(f'~/.local/share/applications/blend;{i}'), inplace=True):
|
|
||||||
if line.strip().startswith('Exec='):
|
|
||||||
line = f'Exec=env BLEND_NO_CHECK= blend enter -cn {c} -- {line[5:]}\n'
|
|
||||||
elif line.strip().startswith('Icon='):
|
|
||||||
if '/' in line:
|
|
||||||
line = line.strip()
|
|
||||||
_ = con_get_output(
|
|
||||||
c, f"mkdir -p ~/.local/share/blend/icons/file/\"{c}_{i}\"; cp {line[5:]} ~/.local/share/blend/icons/file/\"{c}_{i}\"")
|
|
||||||
line = f'Icon={os.path.expanduser("~/.local/share/blend/icons/file/" + c + "_" + i + "/" + os.path.basename(line[5:]))}\n'
|
|
||||||
else:
|
|
||||||
line = line.strip()
|
|
||||||
icons = con_get_output(c, f'''find /usr/share/icons /usr/share/pixmaps /var/lib/flatpak/exports/share/icons \\
|
|
||||||
-type f -iname "*{line[5:]}*" 2> /dev/null | sort''').split('\r\n')
|
|
||||||
_ = con_get_output(
|
|
||||||
c, f"mkdir -p ~/.local/share/blend/icons/\"{c}_{i}\"; cp {icons[0]} ~/.local/share/blend/icons/\"{c}_{i}\"")
|
|
||||||
line = f'Icon={os.path.expanduser("~/.local/share/blend/icons/" + c + "_" + i + "/" + os.path.basename(icons[0]))}\n'
|
|
||||||
sys.stdout.write(line)
|
|
||||||
os.chmod(os.path.expanduser(
|
|
||||||
f'~/.local/share/applications/blend;{i}'), 0o775)
|
|
||||||
_apps.append((c, i))
|
|
||||||
del _
|
|
||||||
|
|
||||||
for a in os.listdir(os.path.expanduser(f'~/.local/share/applications')):
|
|
||||||
if a.startswith('blend;'):
|
|
||||||
a = a.removeprefix('blend;')
|
|
||||||
if [_a for _a in _apps if _a[1] == a] == []:
|
|
||||||
os.remove(os.path.expanduser(
|
|
||||||
f'~/.local/share/applications/blend;{a}'))
|
|
||||||
|
|
||||||
|
|
||||||
def create_container_sessions(type='xsessions'):
|
|
||||||
session_dir = f'/usr/share/{type}'
|
|
||||||
|
|
||||||
os.makedirs('/usr/share/xsessions', exist_ok=True)
|
|
||||||
|
|
||||||
for session in os.listdir(session_dir):
|
|
||||||
if session.startswith(os.path.join(session_dir, 'blend-')):
|
|
||||||
os.remove(os.path.join(session_dir, session))
|
|
||||||
|
|
||||||
for c in _list:
|
|
||||||
c = c.strip()
|
|
||||||
for i in con_get_output(c, f'find {session_dir} -type f 2>/dev/null').split('\n'):
|
|
||||||
orig_path = i.strip()
|
|
||||||
i = os.path.basename(orig_path)
|
|
||||||
if i != '':
|
|
||||||
with open(os.path.expanduser(f'{session_dir}/blend-{c};{i}'), 'w') as f:
|
|
||||||
contents = con_get_output(c, f'cat {orig_path}')
|
|
||||||
f.write(contents)
|
|
||||||
for line in fileinput.input(os.path.expanduser(f'/{session_dir}/blend-{c};{i}'), inplace=True):
|
|
||||||
if line.strip().startswith('Name'):
|
|
||||||
name = line.split('=')[1]
|
|
||||||
line = f'Name=Container {c}: {name}'
|
|
||||||
elif line.strip().startswith('Exec='):
|
|
||||||
line = f'Exec=blend enter -cn {c} -- {line[5:]}'
|
|
||||||
elif line.strip().startswith('TryExec='):
|
|
||||||
continue
|
|
||||||
|
|
||||||
sys.stdout.write(line)
|
|
||||||
os.chmod(os.path.expanduser(
|
|
||||||
f'{session_dir}/blend-{c};{i}'), 0o775)
|
|
||||||
|
|
||||||
|
|
||||||
def con_get_output(name, cmd):
|
|
||||||
try:
|
|
||||||
return subprocess.run(['sudo', '-u', user, 'podman', 'exec', '--user', getpass.getuser(), '-it', name, 'bash', '-c', cmd],
|
|
||||||
stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, timeout=5).stdout.decode('UTF-8').strip()
|
|
||||||
except subprocess.TimeoutExpired:
|
|
||||||
return ''
|
|
||||||
|
|
||||||
|
|
||||||
user = getpass.getuser()
|
|
||||||
|
|
||||||
try:
|
|
||||||
user = sys.argv[2]
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
for c in get_containers():
|
for c in get_containers():
|
||||||
c = c.strip()
|
c = c.strip()
|
||||||
subprocess.call(['podman', 'start', c])
|
subprocess.call(['podman', 'start', c])
|
||||||
|
|
||||||
while True:
|
|
||||||
_list = get_containers()
|
|
||||||
_exceptions = list_use_container_bin()
|
|
||||||
|
|
||||||
create_container_binaries()
|
|
||||||
create_container_applications()
|
|
||||||
time.sleep(1)
|
|
||||||
|
|
140
init-blend
140
init-blend
|
@ -109,18 +109,18 @@ if command -v apt-get &>/dev/null; then
|
||||||
apt-get update &>/dev/null
|
apt-get update &>/dev/null
|
||||||
DEBIAN_FRONTEND=noninteractive apt-get -y install bash bc curl less wget apt-utils apt-transport-https dialog \
|
DEBIAN_FRONTEND=noninteractive apt-get -y install bash bc curl less wget apt-utils apt-transport-https dialog \
|
||||||
diffutils findutils gnupg2 sudo time util-linux libnss-myhostname \
|
diffutils findutils gnupg2 sudo time util-linux libnss-myhostname \
|
||||||
libvte-2.9[0-9]-common libvte-common lsof ncurses-base passwd \
|
libvte-2.9[0-9]-common libvte-common lsof ncurses-base passwd inotify-tools \
|
||||||
pinentry-curses libegl1-mesa libgl1-mesa-glx libvulkan1 mesa-vulkan-drivers &>/dev/null
|
pinentry-curses libegl1-mesa libgl1-mesa-glx libvulkan1 mesa-vulkan-drivers &>/dev/null
|
||||||
|
|
||||||
elif command -v pacman &>/dev/null; then
|
elif command -v pacman &>/dev/null; then
|
||||||
pacman --noconfirm -Syyu &>/dev/null
|
pacman --noconfirm -Syyu &>/dev/null
|
||||||
pacman --noconfirm -Sy bash bc curl wget diffutils findutils gnupg sudo time util-linux vte-common lsof ncurses pinentry \
|
pacman --noconfirm -Sy bash bc curl wget diffutils findutils gnupg sudo time util-linux vte-common lsof ncurses pinentry \
|
||||||
mesa opengl-driver vulkan-intel vulkan-radeon base-devel git &>/dev/null
|
mesa opengl-driver vulkan-intel vulkan-radeon base-devel git inotify-tools &>/dev/null
|
||||||
|
|
||||||
elif command -v dnf &>/dev/null; then
|
elif command -v dnf &>/dev/null; then
|
||||||
dnf install -y --allowerasing bash bc curl wget diffutils findutils dnf-plugins-core gnupg2 less lsof passwd pinentry \
|
dnf install -y --allowerasing bash bc curl wget diffutils findutils dnf-plugins-core gnupg2 less lsof passwd pinentry \
|
||||||
procps-ng vte-profile ncurses util-linux sudo time shadow-utils vulkan mesa-vulkan-drivers \
|
procps-ng vte-profile ncurses util-linux sudo time shadow-utils vulkan mesa-vulkan-drivers \
|
||||||
mesa-dri-drivers &>/dev/null
|
mesa-dri-drivers inotify-tools &>/dev/null
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -324,6 +324,23 @@ chmod 4755 /usr/bin/sudo
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if ! command -v inotify-tools &>/dev/null; then
|
||||||
|
if command -v apt-get &>/dev/null; then
|
||||||
|
apt-get update &>/dev/null
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get -y install inotify-tools &>/dev/null
|
||||||
|
|
||||||
|
elif command -v pacman &>/dev/null; then
|
||||||
|
pacman --noconfirm -Syyu &>/dev/null
|
||||||
|
pacman --noconfirm -Sy inotify-tools &>/dev/null
|
||||||
|
|
||||||
|
elif command -v dnf &>/dev/null; then
|
||||||
|
dnf install -y --allowerasing inotify-tools &>/dev/null
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
source /run/.containerenv
|
||||||
|
CONTAINER_NAME="$name"
|
||||||
|
|
||||||
if [[ ! -f '/.init_blend.lock' ]] && command -v pacman &>/dev/null; then
|
if [[ ! -f '/.init_blend.lock' ]] && command -v pacman &>/dev/null; then
|
||||||
cd /; git clone https://aur.archlinux.org/yay.git &>/dev/null; cd yay
|
cd /; git clone https://aur.archlinux.org/yay.git &>/dev/null; cd yay
|
||||||
chown -R "$_uname" . &>/log
|
chown -R "$_uname" . &>/log
|
||||||
|
@ -333,12 +350,125 @@ if [[ ! -f '/.init_blend.lock' ]] && command -v pacman &>/dev/null; then
|
||||||
touch /.init_blend.lock
|
touch /.init_blend.lock
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo
|
for full_file in /usr/bin/*; do
|
||||||
|
if [[ -x "$full_file" ]]; then
|
||||||
|
file="$(basename "${full_file}")"
|
||||||
|
if [[ ! -f "${HOME}/.local/bin/blend_bin/${file}.${CONTAINER_NAME}" ]]; then
|
||||||
|
mkdir -p "${HOME}/.local/bin/blend_bin"
|
||||||
|
echo "#!/bin/bash" > "${HOME}/.local/bin/blend_bin/${file}.${CONTAINER_NAME}"
|
||||||
|
echo '[ -f /run/.containerenv ] && { if [[ -e "/usr/bin/'"${file}"'" ]]; then /usr/bin/'"${file}"' "$@"; exit $?; else echo "This command can be accessed from the host, or from the container '"'${CONTAINER_NAME}'"'."; exit 127; fi } || :' >> "${HOME}/.local/bin/blend_bin/${file}.${CONTAINER_NAME}"
|
||||||
|
echo 'BLEND_ALLOW_ROOT= BLEND_NO_CHECK= blend enter -cn '"${CONTAINER_NAME}"' -- '"${file}"' "$@"' >> "${HOME}/.local/bin/blend_bin/${file}.${CONTAINER_NAME}"
|
||||||
|
chmod 755 "${HOME}/.local/bin/blend_bin/${file}.${CONTAINER_NAME}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
for full_file in /usr/share/applications/*.desktop; do
|
||||||
|
file="$(basename "${full_file}")"
|
||||||
|
|
||||||
|
mkdir -p "${HOME}/.local/share/applications"
|
||||||
|
|
||||||
|
echo -n > "${HOME}/.local/share/applications/blend;${CONTAINER_NAME};${file}"
|
||||||
|
|
||||||
|
while read -r line; do
|
||||||
|
if [[ $line == Name* ]]; then
|
||||||
|
echo "${line} (container ${CONTAINER_NAME})" >> "${HOME}/.local/share/applications/blend;${CONTAINER_NAME};${file}"
|
||||||
|
elif [[ $line == Exec* ]]; then
|
||||||
|
echo "Exec=blend enter -cn ${CONTAINER_NAME} -- ${line:5}" >> "${HOME}/.local/share/applications/blend;${CONTAINER_NAME};${file}"
|
||||||
|
elif [[ $line == Icon* ]]; then
|
||||||
|
if [[ -e "${line:5}" ]]; then
|
||||||
|
mkdir -p "${HOME}/.local/share/blend/icons/${CONTAINER_NAME}_${file}"; cp "${line:5}" "${HOME}/.local/share/blend/icons/${CONTAINER_NAME}_${file}"
|
||||||
|
echo "Icon=${HOME}/.local/share/blend/icons/${CONTAINER_NAME}_${file}/$(basename "${line:5}")" >> "${HOME}/.local/share/applications/blend;${CONTAINER_NAME};${file}"
|
||||||
|
else
|
||||||
|
ICON_PATH="$(find /usr/share/icons/hicolor -type f -iname "${line:5}.*" -print -quit 2>/dev/null)"
|
||||||
|
mkdir -p "$(dirname "${ICON_PATH}" | sed 's/\/usr\/share/'"\/home\/${_uname}"'\/.local\/share/g')"
|
||||||
|
FINAL_ICON_PATH="$(dirname "${ICON_PATH}" | sed 's/\/usr\/share/'"\/home\/${_uname}"'\/.local\/share/g')/$(echo "${file%.*}").$(basename "${ICON_PATH}" | sed 's/^.*\.//')"
|
||||||
|
cp "${ICON_PATH}" "${FINAL_ICON_PATH}" &>/dev/null
|
||||||
|
echo "Icon=${FINAL_ICON_PATH}" >> "${HOME}/.local/share/applications/blend;${CONTAINER_NAME};${file}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "$line" >> "${HOME}/.local/share/applications/blend;${CONTAINER_NAME};${file}"
|
||||||
|
fi
|
||||||
|
done < "/usr/share/applications/${file}"
|
||||||
|
|
||||||
|
sed -i 's/DBusActivatable=true/DBusActivatable=false/g' "${HOME}/.local/share/applications/blend;${CONTAINER_NAME};${file}"
|
||||||
|
sed -i '/^TryExec/d' "${HOME}/.local/share/applications/blend;${CONTAINER_NAME};${file}"
|
||||||
|
|
||||||
|
chmod 755 "${HOME}/.local/share/applications/blend;${CONTAINER_NAME};${file}"
|
||||||
|
done
|
||||||
|
|
||||||
echo "Completed container setup."
|
echo "Completed container setup."
|
||||||
|
|
||||||
|
mkdir -p /usr/share/applications /usr/bin
|
||||||
|
inotifywait -m /usr/share/applications /usr/bin -e create,delete,move 2>/dev/null |
|
||||||
|
while read dir action file; do
|
||||||
|
( if [[ "$dir" == "/usr/bin/" ]]; then
|
||||||
|
if [[ "$action" == *"CREATE"* ]]; then
|
||||||
|
if [[ ! -f "${HOME}/.local/bin/blend_bin/${file}.${CONTAINER_NAME}" ]] && [[ -x "/usr/bin/${file}" ]]; then
|
||||||
|
mkdir -p "${HOME}/.local/bin/blend_bin"
|
||||||
|
echo "#!/bin/bash" > "${HOME}/.local/bin/blend_bin/${file}.${CONTAINER_NAME}"
|
||||||
|
echo '[ -f /run/.containerenv ] && { if [[ -e "/usr/bin/'"${file}"'" ]]; then /usr/bin/'"${file}"' "$@"; exit $?; else echo "This command can be accessed from the host, or from the container '"'${CONTAINER_NAME}'"'."; exit 127; fi } || :' >> "${HOME}/.local/bin/blend_bin/${file}.${CONTAINER_NAME}"
|
||||||
|
echo 'BLEND_ALLOW_ROOT= BLEND_NO_CHECK= blend enter -cn '"${CONTAINER_NAME}"' -- '"${file}"' "$@"' >> "${HOME}/.local/bin/blend_bin/${file}.${CONTAINER_NAME}"
|
||||||
|
chmod 755 "${HOME}/.local/bin/blend_bin/${file}.${CONTAINER_NAME}"
|
||||||
|
fi
|
||||||
|
elif [[ "$action" == *"DELETE"* ]]; then
|
||||||
|
rm -f "${HOME}/.local/bin/blend_bin/${file}.${CONTAINER_NAME}"
|
||||||
|
elif [[ "$action" == *"MOVED_FROM"* ]]; then
|
||||||
|
rm -f "${HOME}/.local/bin/blend_bin/${file}.${CONTAINER_NAME}"
|
||||||
|
elif [[ "$action" == *"MOVED_TO"* ]]; then
|
||||||
|
if [[ ! -f "${HOME}/.local/bin/blend_bin/${file}.${CONTAINER_NAME}" ]] && [[ -x "/usr/bin/${file}" ]]; then
|
||||||
|
mkdir -p "${HOME}/.local/bin/blend_bin"
|
||||||
|
echo "#!/bin/bash" > "${HOME}/.local/bin/blend_bin/${file}.${CONTAINER_NAME}"
|
||||||
|
echo '[ -f /run/.containerenv ] && { if [[ -e "/usr/bin/'"${file}"'" ]]; then /usr/bin/'"${file}"' "$@"; exit $?; else echo "This command can be accessed from the host, or from the container '"'${CONTAINER_NAME}'"'."; exit 127; fi } || :' >> "${HOME}/.local/bin/blend_bin/${file}.${CONTAINER_NAME}"
|
||||||
|
echo 'BLEND_ALLOW_ROOT= BLEND_NO_CHECK= blend enter -cn '"${CONTAINER_NAME}"' -- '"${file}"' "$@"' >> "${HOME}/.local/bin/blend_bin/${file}.${CONTAINER_NAME}"
|
||||||
|
chmod 755 "${HOME}/.local/bin/blend_bin/${file}.${CONTAINER_NAME}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi ) &
|
||||||
|
( if [[ "$dir" == "/usr/share/applications/" ]]; then
|
||||||
|
if [[ "$action" == *"CREATE"* ]] || [[ "$action" == *"MOVED_TO"* ]]; then
|
||||||
|
if [[ "$file" == *'.desktop' ]]; then
|
||||||
|
mkdir -p "${HOME}/.local/share/applications"
|
||||||
|
|
||||||
|
echo -n > "${HOME}/.local/share/applications/blend;${CONTAINER_NAME};${file}"
|
||||||
|
|
||||||
|
while read -r line; do
|
||||||
|
if [[ $line == Name* ]]; then
|
||||||
|
echo "${line} (${CONTAINER_NAME})" >> "${HOME}/.local/share/applications/blend;${CONTAINER_NAME};${file}"
|
||||||
|
elif [[ $line == Exec* ]]; then
|
||||||
|
echo "Exec=blend enter -cn ${CONTAINER_NAME} -- ${line:5}" >> "${HOME}/.local/share/applications/blend;${CONTAINER_NAME};${file}"
|
||||||
|
elif [[ $line == Icon* ]]; then
|
||||||
|
if [[ -e "${line:5}" ]]; then
|
||||||
|
mkdir -p "${HOME}/.local/share/blend/icons/${CONTAINER_NAME}_${file}"; cp "${line:5}" "${HOME}/.local/share/blend/icons/${CONTAINER_NAME}_${file}"
|
||||||
|
echo "Icon=${HOME}/.local/share/blend/icons/${CONTAINER_NAME}_${file}/$(basename "${line:5}")" >> "${HOME}/.local/share/applications/blend;${CONTAINER_NAME};${file}"
|
||||||
|
else
|
||||||
|
ICON_PATH="$(find /usr/share/icons/hicolor -type f -iname "${line:5}.*" -print -quit 2>/dev/null)"
|
||||||
|
mkdir -p "$(dirname "${ICON_PATH}" | sed 's/\/usr\/share/'"\/home\/${_uname}"'\/.local\/share/g')"
|
||||||
|
FINAL_ICON_PATH="$(dirname "${ICON_PATH}" | sed 's/\/usr\/share/'"\/home\/${_uname}"'\/.local\/share/g')/$(echo "${file%.*}").$(basename "${ICON_PATH}" | sed 's/^.*\.//')"
|
||||||
|
cp "${ICON_PATH}" "${FINAL_ICON_PATH}"
|
||||||
|
echo "Icon=${FINAL_ICON_PATH}" >> "${HOME}/.local/share/applications/blend;${CONTAINER_NAME};${file}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "$line" >> "${HOME}/.local/share/applications/blend;${CONTAINER_NAME};${file}"
|
||||||
|
fi
|
||||||
|
done < "/usr/share/applications/${file}"
|
||||||
|
|
||||||
|
sed -i 's/DBusActivatable=true/DBusActivatable=false/g' "${HOME}/.local/share/applications/blend;${CONTAINER_NAME};${file}"
|
||||||
|
sed -i '/^TryExec/d' "${HOME}/.local/share/applications/blend;${CONTAINER_NAME};${file}"
|
||||||
|
|
||||||
|
chmod 755 "${HOME}/.local/share/applications/blend;${CONTAINER_NAME};${file}"
|
||||||
|
fi
|
||||||
|
elif [[ "$action" == *"DELETE"* ]]; then
|
||||||
|
rm -f "${HOME}/.local/share/applications/blend;${CONTAINER_NAME};${file}"
|
||||||
|
elif [[ "$action" == *"MOVED_FROM"* ]]; then
|
||||||
|
rm -f "${HOME}/.local/share/applications/blend;${CONTAINER_NAME};${file}"
|
||||||
|
fi
|
||||||
|
fi ) &
|
||||||
|
done &
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
for i in /etc/hosts /etc/localtime /etc/resolv.conf; do
|
for i in /etc/hosts /etc/localtime /etc/resolv.conf; do
|
||||||
cp "/run/host/${i}" / &>/dev/null || :
|
cp "/run/host/${i}" / &>/dev/null || :
|
||||||
done
|
done
|
||||||
sleep 5
|
sleep 5
|
||||||
done
|
done
|
||||||
|
|
Loading…
Reference in a new issue