Prelim: Setup text mode install phase, partial functionality on Debian

This commit is contained in:
Rory Fewell
2025-06-29 03:17:16 +01:00
parent f068eaacec
commit 2cae83e60f
8 changed files with 293 additions and 7 deletions

1
base/setup/initial/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
complist.ini

View File

@@ -19,12 +19,26 @@ include(../../../packaging/cmake-inc/common/CMakeLists.txt)
set(CMAKE_INSTALL_PREFIX "")
# Generate list of library names
#
execute_process(
COMMAND /usr/bin/bash -c "find . -mindepth 1 -maxdepth 1 -type d | cut -d'/' -f2 | tr '\n' ','"
WORKING_DIRECTORY ${REPO_ROOT}/shared
OUTPUT_VARIABLE WSETUP_LIBLIST
)
configure_file(complist.ini.in ${PROJECT_ROOT}/complist.ini @ONLY)
# Installation
#
install(
PROGRAMS setup.sh
DESTINATION .
)
install(
FILES complist.ini
DESTINATION ./setup
)
install(
DIRECTORY autorun
DESTINATION ./setup

View File

@@ -0,0 +1,5 @@
[BaseSystem]
Libs=@WSETUP_LIBLIST@
OurPackages=wintc-setup-gui,wintc-theme-native,wintc-cursor-theme-standard-with-shadow
DistPackagesDeb=lightdm,xfwm4,xfconf
# FIXME: Other distro packags here

View File

@@ -11,9 +11,6 @@ export SETUPROOT
# running distro and its init system before chaining onto the rest of setup
#
clear
printf "%s\n" "Setup is inspecting your computer's hardware configuration...";
# Probe for Python as we cannot run binaries at this point
#
python_path=`which python 2>/dev/null`
@@ -44,6 +41,15 @@ export WSETUP_DIST_PKGFMT_EXT
#
if [ -z "$DISPLAY" ] && [ -z "$WAYLAND_DISPLAY" ]
then
if [ $(id -u) -ne 0 ]
then
printf "%s\n" "You must be root to run setup."
exit 1
fi
clear
printf "%s\n" "Setup is inspecting your computer's hardware configuration...";
$python_path setup/textmode/main.py
else
$python_path setup/autorun/main.py

View File

@@ -10,7 +10,8 @@ def main(stdscr):
wsetup_step_beta_notice,
wsetup_step_welcome,
wsetup_step_eula,
wsetup_step_confirm_system
wsetup_step_confirm_system,
wsetup_step_install_base
]
current_step = 1

View File

@@ -0,0 +1,68 @@
import configparser
import os
import subprocess
def wsetup_pkg_get_pkgfmt_extension():
pkgfmt = os.environ.get("WSETUP_DIST_PKGFMT")
if pkgfmt == "apk":
return ".apk"
elif pkgfmt == "archpkg":
return ".pkg.tar.zst"
elif pkgfmt == "bsdpkg":
return ".pkg"
elif pkgfmt == "deb":
return ".deb"
elif pkgfmt == "rpm":
return ".rpm"
elif pkgfmt == "xbps":
return ".xbps"
raise Exception(f"Unknown package format {pkgfmt}")
def wsetup_pkg_get_pkgnames_basesystem():
setup_root = os.environ.get("SETUPROOT")
# Set up package format vars
#
pkgfmt_arch = subprocess.Popen(
"uname -m",
shell=True,
stdout=subprocess.PIPE
).stdout.read().decode('utf-8').strip()
pkgfmt = os.environ.get("WSETUP_DIST_PKGFMT")
pkgfmt_ext = os.environ.get("WSETUP_DIST_PKGFMT_EXT", "std")
pkgfmt_fileext = wsetup_pkg_get_pkgfmt_extension()
pkg_src_dir = f"{setup_root}/{pkgfmt}/{pkgfmt_ext}/{pkgfmt_arch}"
# Read complist.ini to set up the stuff we need to install for phase 2
#
complist = configparser.ConfigParser()
complist.read(f"{setup_root}/setup/complist.ini")
libs_arr = complist["BaseSystem"]["Libs"].split(",")
ourpkgs_arr = complist["BaseSystem"]["OurPackages"].split(",")
for i in range(len(libs_arr)):
if libs_arr[i] == "":
continue
libs_arr[i] = f"{pkg_src_dir}/libwintc-{libs_arr[i]}{pkgfmt_fileext}"
libs = " ".join(libs_arr)
for i in range(len(ourpkgs_arr)):
if ourpkgs_arr[i] == "":
continue
ourpkgs_arr[i] = f"{pkg_src_dir}/{ourpkgs_arr[i]}{pkgfmt_fileext}"
ourpkgs = " ".join(ourpkgs_arr)
distpkgs = " ".join(
complist["BaseSystem"]["DistPackages" + pkgfmt.title()].split(",")
)
return f"{libs} {ourpkgs} {distpkgs}"

View File

@@ -1,4 +1,5 @@
import curses
import math
from wsetup_brand import *
@@ -16,6 +17,11 @@ COLOR_PAIR_INSTRUCTIONS = 4
WSETUP_MAIN_Y = 4
WSETUP_MAIN_X = 3
# Dimensions for scaling based on Windows setup (NT setup uses 80x50 text mode)
#
WSETUP_NATIVE_W = 80
WSETUP_NATIVE_H = 50
def wsetup_screen_init(stdscr):
# Set up our colours
#
@@ -117,10 +123,86 @@ def wsetup_screen_write_instructions(stdscr, arr):
cur_x += len(instruction) + 2
def wsetup_screen_write_simple(stdscr, y, x, text, attr):
def wsetup_screen_write_direct(stdscr, y, x, text, attr):
cur_y = y
lines = text.split("\n")
for line in lines:
stdscr.addstr(WSETUP_MAIN_Y + cur_y, WSETUP_MAIN_X + x, line, attr)
stdscr.addstr(cur_y, x, line, attr)
cur_y += 1
def wsetup_screen_write_simple(stdscr, y, x, text, attr):
wsetup_screen_write_direct(stdscr, WSETUP_MAIN_Y + y, WSETUP_MAIN_X + x, text, attr)
def wsetup_screen_draw_box(stdscr, y, x, height, width):
# Top left corner
#
stdscr.addch(
y, x,
curses.ACS_ULCORNER,
curses.color_pair(COLOR_PAIR_NORMAL_TEXT)
)
# Top middle
#
for i in range(x + 1, x + width - 1):
stdscr.addch(
y, i,
curses.ACS_HLINE,
curses.color_pair(COLOR_PAIR_NORMAL_TEXT)
)
# Top right corner
#
stdscr.addch(
y, x + width - 1,
curses.ACS_URCORNER,
curses.color_pair(COLOR_PAIR_NORMAL_TEXT)
)
# Middle
#
for i in range(y + 1, y + height - 1):
stdscr.addch(
i, x,
curses.ACS_VLINE,
curses.color_pair(COLOR_PAIR_NORMAL_TEXT)
)
stdscr.addch(
i, x + width - 1,
curses.ACS_VLINE,
curses.color_pair(COLOR_PAIR_NORMAL_TEXT)
)
# Bottom left corner
#
stdscr.addch(
y + height - 1, x,
curses.ACS_LLCORNER,
curses.color_pair(COLOR_PAIR_NORMAL_TEXT)
)
# Bottom middle
#
for i in range(x + 1, x + width - 1):
stdscr.addch(
y + height - 1, i,
curses.ACS_HLINE,
curses.color_pair(COLOR_PAIR_NORMAL_TEXT)
)
# Bottom right corner
#
stdscr.addch(
y + height - 1, x + width - 1,
curses.ACS_LRCORNER,
curses.color_pair(COLOR_PAIR_NORMAL_TEXT)
)
def wsetup_screen_get_scaled_x(stdscr, val):
height, width = stdscr.getmaxyx()
return math.floor((val / WSETUP_NATIVE_W) * width)
def wsetup_screen_get_scaled_y(stdscr, val):
height, width = stdscr.getmaxyx()
return math.floor((val / WSETUP_NATIVE_H) * height)

View File

@@ -1,7 +1,9 @@
import curses
import os
import subprocess
from wsetup_brand import *
from wsetup_pkg import *
from wsetup_screen import *
def wsetup_step_init(stdscr):
@@ -211,4 +213,111 @@ def wsetup_step_confirm_system(stdscr):
elif user_option == curses.KEY_ENTER or \
user_option == ord("\n") or \
user_option == ord("\r"):
return 0 # TODO: Continue to install
return 6
def wsetup_step_install_base(stdscr):
wsetup_screen_clear(stdscr)
wsetup_screen_write_direct(
stdscr,
wsetup_screen_get_scaled_y(stdscr, WSETUP_MAIN_Y + 3),
wsetup_screen_get_scaled_x(stdscr, 40) - 22,
" Please wait while Setup copies files \n" +
" to the Windows installation folders. \n" +
"This might take several minutes to complete.",
curses.color_pair(COLOR_PAIR_NORMAL_TEXT)
)
# Main box
#
box_h = 7
box_w = 68
box_y = wsetup_screen_get_scaled_y(stdscr, 20)
box_x = wsetup_screen_get_scaled_x(stdscr, 40) - int(box_w / 2)
wsetup_screen_draw_box(
stdscr,
box_y,
box_x,
box_h,
box_w
)
wsetup_screen_write_direct(
stdscr,
box_y + 1,
box_x + 2,
"Setup is copying files...",
curses.color_pair(COLOR_PAIR_NORMAL_TEXT)
)
# Progress box
#
progbox_h = 3
progbox_w = box_w - 10
progbox_y = box_y + 3
progbox_x = box_x + 5
wsetup_screen_draw_box(
stdscr,
progbox_y,
progbox_x,
progbox_h,
progbox_w
)
wsetup_screen_write_instructions(
stdscr,
[
"ENTER=Continue"
]
)
# Install the base packages to get to phase 2
#
pkgcmd = ""
pkgfmt = os.environ.get("WSETUP_DIST_PKGFMT")
pkgnames = wsetup_pkg_get_pkgnames_basesystem()
if pkgfmt == "deb":
pkgcmd = f"apt-get install -y -o APT::Status-Fd=2 {pkgnames}"
else:
raise Exception(f"No install command for format {pkgfmt}")
process = subprocess.Popen(
pkgcmd.split(),
bufsize=1,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE,
universal_newlines=True
)
while True:
cmd_out = process.stderr.readline()
if process.poll() is not None:
break
if cmd_out:
wsetup_screen_write_simple(
stdscr,
1, 0,
cmd_out.strip(),
curses.color_pair(COLOR_PAIR_NORMAL_TEXT)
)
stdscr.refresh()
wsetup_screen_write_simple(
stdscr,
1, 0,
"Finito",
curses.color_pair(COLOR_PAIR_NORMAL_TEXT)
)
# Input
#
while True:
user_option = stdscr.getch()
if user_option == curses.KEY_F0 + 3:
return 0