Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
M
MbetterLiveCD
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Mbetter
MbetterLiveCD
Commits
53413811
Commit
53413811
authored
Dec 09, 2025
by
Stefy Lanza (nextime / spora )
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Change from openbox to xfce4
parent
5de4db6d
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
20 additions
and
1011 deletions
+20
-1011
auto-installer.sh
config/includes.chroot/usr/local/bin/auto-installer.sh
+0
-1010
live.list.chroot
config/package-lists/live.list.chroot
+20
-1
No files found.
config/includes.chroot/usr/local/bin/auto-installer.sh
deleted
100755 → 0
View file @
5de4db6d
#!/bin/bash
# MBetter Offline Automatic Installer Script
# Copies the live system to disk for completely offline installation
# NO internet connection required
set
-e
INSTALL_LOG
=
"/var/log/auto-installer.log"
TARGET_DISK
=
""
# Will be detected automatically
TARGET_MOUNT
=
"/target"
PRESEED_FILE
=
""
LIVE_SYSTEM
=
"/"
USB_DEVICE
=
""
# Will track USB device to avoid installing over it
# Colors for output
RED
=
'\033[0;31m'
GREEN
=
'\033[0;32m'
YELLOW
=
'\033[1;33m'
BLUE
=
'\033[0;34m'
NC
=
'\033[0m'
# Progress tracking
TOTAL_STEPS
=
10
CURRENT_STEP
=
0
log
()
{
echo
"
$(
date
)
:
$1
"
|
tee
-a
"
$INSTALL_LOG
"
}
# Progress tracking functions
update_progress
()
{
local
step
=
$1
local
message
=
"
$2
"
CURRENT_STEP
=
$step
local
percent
=
$((
step
*
100
/
TOTAL_STEPS
))
# Terminal-based progress bar
local
width
=
50
local
filled
=
$((
percent
*
width
/
100
))
local
empty
=
$((
width
-
filled
))
# Create progress bar
local
bar
=
""
for
((
i
=
0
;
i<filled
;
i++
))
;
do
bar
=
"
${
bar
}
█"
;
done
for
((
i
=
0
;
i<empty
;
i++
))
;
do
bar
=
"
${
bar
}
░"
;
done
# Clear previous progress and show new one
echo
-ne
"
\r
${
BLUE
}
[PROGRESS]
${
NC
}
$message
\n
${
BLUE
}
[
${
bar
}
]
${
NC
}
${
percent
}
%"
print_status
"
$message
(
$percent
%)"
}
start_progress_display
()
{
# Terminal progress - no initialization needed
echo
-e
"
${
BLUE
}
========================================
${
NC
}
"
echo
-e
"
${
BLUE
}
MBetter Installation Progress
${
NC
}
"
echo
-e
"
${
BLUE
}
========================================
${
NC
}
"
}
cleanup_progress
()
{
# Terminal cleanup - just add newline
echo
-e
"
\n
${
GREEN
}
[INFO]
${
NC
}
Progress tracking completed"
}
print_status
()
{
echo
-e
"
${
GREEN
}
[INFO]
${
NC
}
$1
"
log
"INFO:
$1
"
}
print_warning
()
{
echo
-e
"
${
YELLOW
}
[WARNING]
${
NC
}
$1
"
log
"WARNING:
$1
"
}
print_error
()
{
echo
-e
"
${
RED
}
[ERROR]
${
NC
}
$1
"
log
"ERROR:
$1
"
}
print_header
()
{
echo
-e
"
${
BLUE
}
================================
${
NC
}
"
echo
-e
"
${
BLUE
}
$1
${
NC
}
"
echo
-e
"
${
BLUE
}
================================
${
NC
}
"
}
# Detect USB device we're booting from
detect_usb_device
()
{
print_status
"Detecting USB boot device..."
# Find the device containing the live system
local
live_dev
=
""
# Check different possible mount points for live media
for
mount_point
in
/lib/live/mount/medium /cdrom /run/live/medium
;
do
if
[
-d
"
$mount_point
"
]
;
then
live_dev
=
$(
df
"
$mount_point
"
2>/dev/null |
tail
-1
|
awk
'{print $1}'
|
sed
's/[0-9]*$//'
)
if
[
-n
"
$live_dev
"
]
&&
[
-b
"
$live_dev
"
]
;
then
USB_DEVICE
=
"
$live_dev
"
print_status
"Detected live media device:
$USB_DEVICE
"
return
0
fi
fi
done
# Fallback: check for mounted filesystems with live or boot labels
USB_DEVICE
=
$(
lsblk
-rno
NAME,MOUNTPOINT,LABEL |
grep
-E
"(live|boot|LIVE)"
|
head
-1
|
awk
'{print "/dev/" $1}'
|
sed
's/[0-9]*$//'
)
if
[
-n
"
$USB_DEVICE
"
]
&&
[
-b
"
$USB_DEVICE
"
]
;
then
print_status
"Detected USB device:
$USB_DEVICE
"
else
print_warning
"Could not detect USB device, assuming /dev/sdb"
USB_DEVICE
=
"/dev/sdb"
# Common fallback when sda is the target
fi
}
# Find available target disk (not the USB device)
detect_target_disk
()
{
print_status
"Detecting target installation disk..."
# Get all available disk devices
local
disks
=
$(
lsblk
-rno
NAME,TYPE |
grep
disk |
awk
'{print "/dev/" $1}'
)
for
disk
in
$disks
;
do
# Skip the USB device we're booting from
if
[
"
$disk
"
=
"
$USB_DEVICE
"
]
;
then
print_status
"Skipping USB boot device:
$disk
"
continue
fi
# Skip if disk is too small (less than 4GB)
local
size_bytes
=
$(
lsblk
-rbno
SIZE
"
$disk
"
2>/dev/null |
head
-1
|
tr
-d
' '
||
echo
0
)
# Ensure size_bytes is a valid number
if
!
[[
"
$size_bytes
"
=
~ ^[0-9]+
$
]]
;
then
size_bytes
=
0
fi
local
size_gb
=
$((
size_bytes
/
1024
/
1024
/
1024
))
if
[
"
$size_gb
"
-lt
4
]
;
then
print_status
"Skipping small disk:
$disk
(
$size_gb
GB)"
continue
fi
# Found suitable target disk
TARGET_DISK
=
"
$disk
"
print_status
"Selected target disk:
$TARGET_DISK
(
$size_gb
GB)"
return
0
done
print_error
"No suitable target disk found!"
print_error
"Available disks:"
lsblk
-rno
NAME,SIZE,TYPE |
grep
disk
return
1
}
# Find preseed file (USB-aware)
find_preseed
()
{
print_status
"Searching for preseed file..."
# Extended search paths for USB environments
local
search_paths
=(
"/cdrom/preseed.cfg"
"/lib/live/mount/medium/preseed.cfg"
"/run/live/medium/preseed.cfg"
"/tmp/installer/preseed.cfg"
"/media/*/preseed.cfg"
"/mnt/*/preseed.cfg"
)
for
path
in
"
${
search_paths
[@]
}
"
;
do
# Handle wildcard paths
if
[[
"
$path
"
==
*
"*"
*
]]
;
then
for
expanded_path
in
$path
;
do
if
[
-f
"
$expanded_path
"
]
;
then
PRESEED_FILE
=
"
$expanded_path
"
break
2
fi
done
elif
[
-f
"
$path
"
]
;
then
PRESEED_FILE
=
"
$path
"
break
fi
done
if
[
-z
"
$PRESEED_FILE
"
]
;
then
print_warning
"Preseed file not found, using defaults"
return
0
fi
print_status
"Using preseed file:
$PRESEED_FILE
"
}
# Parse preseed for values
get_preseed_value
()
{
local
key
=
"
$1
"
if
[
-f
"
$PRESEED_FILE
"
]
;
then
grep
"^d-i
$key
"
"
$PRESEED_FILE
"
|
cut
-d
' '
-f3-
|
sed
's/^password //'
||
echo
""
fi
}
# Enhanced network configuration for installed system
configure_network
()
{
print_header
"Network Configuration for Installed System"
# Network configuration variables
NETWORK_CONFIG
=
""
SELECTED_INTERFACE
=
""
WIFI_SSID
=
""
WIFI_PASSWORD
=
""
WIFI_SECURITY
=
""
STATIC_IP
=
""
STATIC_GATEWAY
=
""
STATIC_DNS
=
""
# Skip network config if user doesn't want it
echo
""
echo
"Do you want to configure network for the installed system?"
echo
-n
"(y/n, default=n): "
read
-r
config_network
case
"
$config_network
"
in
y|Y|yes|YES
)
;;
*
)
print_status
"Skipping network configuration - can be done after installation"
return
0
;;
esac
# Detect available interfaces
print_status
"Scanning network interfaces..."
# Get ethernet interfaces
ETHERNET_INTERFACES
=
$(
ip
link
show |
grep
-E
'^[0-9]+:.*e(n|th)'
|
cut
-d
:
-f2
|
tr
-d
' '
)
# Get wireless interfaces
WIRELESS_INTERFACES
=
$(
iw dev 2>/dev/null |
grep
Interface |
awk
'{print $2}'
||
true
)
# Show available interfaces
echo
""
echo
"Available network interfaces:"
interface_count
=
0
for
iface
in
$ETHERNET_INTERFACES
;
do
interface_count
=
$((
interface_count
+
1
))
echo
"
$interface_count
.
$iface
(Ethernet)"
done
for
iface
in
$WIRELESS_INTERFACES
;
do
interface_count
=
$((
interface_count
+
1
))
echo
"
$interface_count
.
$iface
(Wireless)"
done
if
[
$interface_count
-eq
0
]
;
then
print_warning
"No network interfaces detected"
return
0
fi
# Select interface
echo
""
echo
-n
"Select interface number (1-
$interface_count
): "
read
-r
interface_selection
# Get selected interface name
current_count
=
0
for
iface
in
$ETHERNET_INTERFACES
;
do
current_count
=
$((
current_count
+
1
))
if
[
"
$current_count
"
=
"
$interface_selection
"
]
;
then
SELECTED_INTERFACE
=
"
$iface
"
INTERFACE_TYPE
=
"ethernet"
break
fi
done
if
[
-z
"
$SELECTED_INTERFACE
"
]
;
then
for
iface
in
$WIRELESS_INTERFACES
;
do
current_count
=
$((
current_count
+
1
))
if
[
"
$current_count
"
=
"
$interface_selection
"
]
;
then
SELECTED_INTERFACE
=
"
$iface
"
INTERFACE_TYPE
=
"wireless"
break
fi
done
fi
if
[
-z
"
$SELECTED_INTERFACE
"
]
;
then
print_error
"Invalid interface selection"
return
1
fi
print_status
"Selected interface:
$SELECTED_INTERFACE
(
$INTERFACE_TYPE
)"
# Configure wireless if needed
if
[
"
$INTERFACE_TYPE
"
=
"wireless"
]
;
then
print_status
"Scanning for wireless networks..."
# Enable interface for scanning
ip
link set
"
$SELECTED_INTERFACE
"
up
sleep
2
# Scan for networks
AVAILABLE_NETWORKS
=
$(
iw dev
"
$SELECTED_INTERFACE
"
scan |
grep
-E
"SSID:"
|
sed
's/.*SSID: //'
|
sort
-u
|
head
-20
)
if
[
-n
"
$AVAILABLE_NETWORKS
"
]
;
then
echo
""
echo
"Available wireless networks:"
network_count
=
0
echo
"
$AVAILABLE_NETWORKS
"
|
while
read
-r
network
;
do
network_count
=
$((
network_count
+
1
))
echo
"
$network_count
.
$network
"
done
echo
""
echo
-n
"Select network number or type SSID manually: "
read
-r
wifi_selection
# Check if it's a number or manual SSID
if
echo
"
$wifi_selection
"
|
grep
-q
'^[0-9]\+$'
;
then
WIFI_SSID
=
$(
echo
"
$AVAILABLE_NETWORKS
"
|
sed
-n
"
${
wifi_selection
}
p"
)
else
WIFI_SSID
=
"
$wifi_selection
"
fi
else
echo
""
echo
-n
"No networks found. Enter SSID manually: "
read
-r
WIFI_SSID
fi
if
[
-n
"
$WIFI_SSID
"
]
;
then
print_status
"Selected WiFi network:
$WIFI_SSID
"
# Ask for security type
echo
""
echo
"WiFi Security:"
echo
" 1. WPA/WPA2 (most common)"
echo
" 2. WEP (legacy)"
echo
" 3. Open (no password)"
echo
-n
"Select security type (1-3, default=1): "
read
-r
security_choice
case
"
$security_choice
"
in
2
)
WIFI_SECURITY
=
"WEP"
;;
3
)
WIFI_SECURITY
=
"NONE"
;;
*
)
WIFI_SECURITY
=
"WPA"
;;
esac
# Ask for password if needed
if
[
"
$WIFI_SECURITY
"
!=
"NONE"
]
;
then
echo
-n
"Enter WiFi password: "
read
-s
WIFI_PASSWORD
echo
""
fi
fi
fi
# Ask for IP configuration method
echo
""
echo
"IP Configuration:"
echo
" 1. DHCP (automatic)"
echo
" 2. Static IP (manual)"
echo
-n
"Select method (1-2, default=1): "
read
-r
ip_method
case
"
$ip_method
"
in
2
)
# Manual IP configuration
echo
""
echo
-n
"Enter IP address (e.g., 192.168.1.100): "
read
-r
STATIC_IP
echo
-n
"Enter gateway (e.g., 192.168.1.1): "
read
-r
STATIC_GATEWAY
echo
-n
"Enter DNS server (e.g., 8.8.8.8): "
read
-r
STATIC_DNS
NETWORK_CONFIG
=
"static"
;;
*
)
NETWORK_CONFIG
=
"dhcp"
;;
esac
print_status
"Network configuration collected for installed system"
print_status
" Interface:
$SELECTED_INTERFACE
(
$INTERFACE_TYPE
)"
if
[
"
$INTERFACE_TYPE
"
=
"wireless"
]
&&
[
-n
"
$WIFI_SSID
"
]
;
then
print_status
" WiFi SSID:
$WIFI_SSID
"
print_status
" WiFi Security:
$WIFI_SECURITY
"
fi
print_status
" IP Method:
$NETWORK_CONFIG
"
# Store configuration for use during system configuration
cat
>
/tmp/network_config
<<
EOF
SELECTED_INTERFACE="
$SELECTED_INTERFACE
"
INTERFACE_TYPE="
$INTERFACE_TYPE
"
WIFI_SSID="
$WIFI_SSID
"
WIFI_PASSWORD="
$WIFI_PASSWORD
"
WIFI_SECURITY="
$WIFI_SECURITY
"
NETWORK_CONFIG="
$NETWORK_CONFIG
"
STATIC_IP="
$STATIC_IP
"
STATIC_GATEWAY="
$STATIC_GATEWAY
"
STATIC_DNS="
$STATIC_DNS
"
EOF
print_status
"Network configuration will be applied to installed system"
}
# Interactive timezone selection using tzselect
select_timezone
()
{
print_header
"Timezone Selection"
echo
""
echo
"Please select your timezone for the installed system."
echo
"This will determine the correct local time display."
echo
""
# Use tzselect to interactively select timezone
SELECTED_TIMEZONE
=
$(
tzselect
)
if
[
-n
"
$SELECTED_TIMEZONE
"
]
&&
[
"
$SELECTED_TIMEZONE
"
!=
"UTC"
]
;
then
print_status
"Selected timezone:
$SELECTED_TIMEZONE
"
# Store timezone for use during system configuration
echo
"
$SELECTED_TIMEZONE
"
>
/tmp/selected_timezone
else
print_status
"Using default timezone: UTC"
echo
"UTC"
>
/tmp/selected_timezone
fi
}
# User confirmation before destructive operations
confirm_installation
()
{
print_header
"Installation Confirmation Required"
# Show what will happen
print_status
"READY TO BEGIN INSTALLATION"
print_status
""
print_status
"Installation Summary:"
print_status
" Source: Live system (USB/CD:
${
USB_DEVICE
:-
unknown
}
)"
print_status
" Target:
$TARGET_DISK
(will be completely erased)"
# Get disk size for display
local
size_bytes
=
$(
lsblk
-rbno
SIZE
"
$TARGET_DISK
"
2>/dev/null |
head
-1
|
tr
-d
' '
||
echo
0
)
# Ensure size_bytes is a valid number
if
!
[[
"
$size_bytes
"
=
~ ^[0-9]+
$
]]
;
then
size_bytes
=
0
fi
local
size_gb
=
$((
size_bytes
/
1024
/
1024
/
1024
))
print_status
" Target size:
${
size_gb
}
GB"
# Show disk model if available
local
model
=
$(
lsblk
-rno
MODEL
"
$TARGET_DISK
"
2>/dev/null
||
echo
"Unknown"
)
print_status
" Target model:
$model
"
print_status
""
print_warning
"WARNING: This will COMPLETELY ERASE all data on
$TARGET_DISK
!"
print_warning
"All existing partitions and data will be permanently destroyed!"
print_status
""
# Use terminal confirmation for reliable operation
# GUI dialogs can hang in some terminal environments
print_status
"Using terminal confirmation for reliable operation..."
echo
""
echo
-e
"
${
RED
}
==================== INSTALLATION WARNING ====================
${
NC
}
"
echo
-e
"
${
RED
}
This will COMPLETELY ERASE all data on
$TARGET_DISK
!
${
NC
}
"
echo
-e
"
${
RED
}
All existing partitions and data will be permanently destroyed!
${
NC
}
"
echo
-e
"
${
RED
}
=============================================================
${
NC
}
"
echo
""
echo
"Target disk:
$TARGET_DISK
(
$size_gb
GB)"
echo
"Model:
$model
"
echo
""
echo
-e
"
${
YELLOW
}
Ready to begin installation?
${
NC
}
"
echo
-n
"Continue with installation? (type 'YES' to confirm): "
read
-r
confirmation
case
"
$confirmation
"
in
YES|yes|Y|y
)
return
0
;;
*
)
return
1
;;
esac
}
# Partition disk automatically
partition_disk
()
{
print_header
"Disk Partitioning"
if
[
!
-b
"
$TARGET_DISK
"
]
;
then
print_error
"Target disk
$TARGET_DISK
not found!"
return
1
fi
print_status
"Partitioning disk
$TARGET_DISK
..."
# Unmount any existing partitions
umount
"
${
TARGET_DISK
}
"
*
2>/dev/null
||
true
# Create partition table
parted
-s
"
$TARGET_DISK
"
mklabel msdos
parted
-s
"
$TARGET_DISK
"
mkpart primary ext4 1MiB 100%
parted
-s
"
$TARGET_DISK
"
set
1 boot on
# Wait for kernel to recognize partitions
sleep
2
partprobe
"
$TARGET_DISK
"
||
true
# Format partition
print_status
"Creating ext4 filesystem..."
mkfs.ext4
-F
"
${
TARGET_DISK
}
1"
-L
"root"
print_status
"Disk partitioning completed"
}
# Mount target
mount_target
()
{
print_status
"Mounting target filesystem..."
mkdir
-p
"
$TARGET_MOUNT
"
mount
"
${
TARGET_DISK
}
1"
"
$TARGET_MOUNT
"
print_status
"Target mounted at
$TARGET_MOUNT
"
}
# Copy live system to target (OFFLINE approach)
copy_live_system
()
{
print_header
"Copying Live System (Offline Installation)"
print_status
"This is an OFFLINE installation - copying the live system to disk"
print_status
"NO internet connection required!"
# Copy the live system excluding certain directories
print_status
"Copying system files..."
rsync
-av
--progress
\
--exclude
=
/target
\
--exclude
=
/proc
\
--exclude
=
/sys
\
--exclude
=
/dev
\
--exclude
=
/tmp
\
--exclude
=
/run
\
--exclude
=
/mnt
\
--exclude
=
/media
\
--exclude
=
/lost+found
\
--exclude
=
/lib/live
\
--exclude
=
/cdrom
\
--exclude
=
/var/cache/apt/archives/
*
.deb
\
--exclude
=
/var/log/
*
\
--exclude
=
/var/log/auto-installer.log
\
/
"
$TARGET_MOUNT
/"
print_status
"Live system copied successfully"
}
# Configure target system
configure_target_system
()
{
print_header
"Configuring Target System"
# Create necessary directories
mkdir
-p
"
$TARGET_MOUNT
"
/
{
proc,sys,dev,tmp,run,mnt,media
}
# Bind mount for configuration
mount
-t
proc proc
"
$TARGET_MOUNT
/proc"
mount
-t
sysfs sysfs
"
$TARGET_MOUNT
/sys"
mount
-o
bind
/dev
"
$TARGET_MOUNT
/dev"
mount
-t
devpts devpts
"
$TARGET_MOUNT
/dev/pts"
chroot
"
$TARGET_MOUNT
"
apt-get
-y
-qq
remove live-config live-config-sysvinit live-boot-doc live-boot-initramfs-tools live-config-doc live-tools user-setup
# Set root password from preseed, live system, or use default
ROOT_PASS
=
$(
get_preseed_value
"passwd/root-password"
)
ROOT_PASS_CRYPTED
=
$(
get_preseed_value
"passwd/root-password-crypted"
)
if
[
-n
"
$ROOT_PASS_CRYPTED
"
]
;
then
print_status
"Setting root password from crypted preseed file..."
log
"Setting root password from crypted preseed"
# Extract the crypted password (remove "password " prefix)
CRYPTED_PASS
=
$(
echo
"
$ROOT_PASS_CRYPTED
"
|
sed
's/^password //'
)
# Ensure we have a clean shadow file first - remove any duplicate root entries
sed
-i
'/^root:/d'
"
$TARGET_MOUNT
/etc/shadow"
# Add the root entry with the crypted password
echo
"root:
$CRYPTED_PASS
:19453:0:99999:7:::"
>>
"
$TARGET_MOUNT
/etc/shadow"
elif
[
-n
"
$ROOT_PASS
"
]
;
then
print_status
"Setting root password from preseed file..."
log
"Setting root password from preseed:
${
ROOT_PASS
:0:10
}
..."
# Set the password using chpasswd
echo
"root:
$ROOT_PASS
"
|
chroot
"
$TARGET_MOUNT
"
chpasswd
else
# Try to copy password from live system
LIVE_ROOT_HASH
=
$(
grep
'^root:'
/etc/shadow |
cut
-d
:
-f2
)
if
[
-n
"
$LIVE_ROOT_HASH
"
]
&&
[
"
$LIVE_ROOT_HASH
"
!=
"*"
]
&&
[
"
$LIVE_ROOT_HASH
"
!=
"!"
]
&&
[
"
$LIVE_ROOT_HASH
"
!=
"x"
]
;
then
# Copy the live system's root password hash directly to target shadow file
print_status
"Copying live system root password to installed system..."
log
"Copying live system root password hash to installed system"
# Get the full root line from live shadow
LIVE_ROOT_LINE
=
$(
grep
'^root:'
/etc/shadow
)
# Ensure clean shadow file and add the live system's root entry
sed
-i
'/^root:/d'
"
$TARGET_MOUNT
/etc/shadow"
echo
"
$LIVE_ROOT_LINE
"
>>
"
$TARGET_MOUNT
/etc/shadow"
if
[
$?
-eq
0
]
;
then
print_status
"Live system root password copied successfully"
log
"Live system root password hash copied to target system"
else
print_warning
"Failed to copy live password, using default"
echo
"root:mbetter123"
|
chroot
"
$TARGET_MOUNT
"
chpasswd
fi
else
# Set default password if none available
print_status
"No root password available, using default password: mbetter123"
log
"Using default root password: mbetter123"
echo
"root:mbetter123"
|
chroot
"
$TARGET_MOUNT
"
chpasswd
fi
fi
# Verify password was set and ensure account is properly configured
print_status
"Ensuring root account is properly configured..."
# Make sure the root account is unlocked and has proper password aging
chroot
"
$TARGET_MOUNT
"
passwd
-u
root 2>/dev/null
||
print_warning
"Could not unlock root account"
chroot
"
$TARGET_MOUNT
"
chage
-d
99999 root 2>/dev/null
||
print_warning
"Could not remove password expiration"
chroot
"
$TARGET_MOUNT
"
chage
-E
-1
root 2>/dev/null
||
print_warning
"Could not remove account expiration"
chroot
"
$TARGET_MOUNT
"
chage
-m
0 root 2>/dev/null
||
print_warning
"Could not set minimum password age"
chroot
"
$TARGET_MOUNT
"
chage
-M
99999 root 2>/dev/null
||
print_warning
"Could not set maximum password age"
# Verify the shadow entry is correct
ROOT_SHADOW_ENTRY
=
$(
grep
'^root:'
"
$TARGET_MOUNT
/etc/shadow"
)
if
[
-n
"
$ROOT_SHADOW_ENTRY
"
]
;
then
ROOT_PASS_FIELD
=
$(
echo
"
$ROOT_SHADOW_ENTRY
"
|
cut
-d
:
-f2
)
if
[
"
$ROOT_PASS_FIELD
"
!=
"x"
]
&&
[
"
$ROOT_PASS_FIELD
"
!=
"*"
]
&&
[
"
$ROOT_PASS_FIELD
"
!=
"!"
]
;
then
print_status
"Root password verification successful"
log
"Root password hash:
${
ROOT_PASS_FIELD
:0:20
}
..."
else
print_warning
"Root password appears to be disabled or invalid"
log
"Root password field:
$ROOT_PASS_FIELD
"
fi
else
print_error
"No root entry found in shadow file!"
fi
# Create mbetterclient user with no password for autologin
print_status
"Creating mbetterclient user for autologin..."
chroot
"
$TARGET_MOUNT
"
useradd
-m
-s
/bin/bash mbetterclient 2>/dev/null
||
true
chroot
"
$TARGET_MOUNT
"
passwd
-d
mbetterclient 2>/dev/null
||
true
# Remove password
# Configure mbetterclient user to launch startx on login
print_status
"Configuring mbetterclient user to launch startx..."
cat
>
"
$TARGET_MOUNT
/home/mbetterclient/.bashrc"
<<
'
EOF
'
# X session autolaunch configuration
if [ -n "
$SSH_CLIENT
" ] || [ -n "
$SSH_TTY
" ]; then
# SSH session - don't autolaunch
return
fi
# Check if we're on tty1 (autologin terminal)
if [ "
$(
tty
)
" = "/dev/tty1" ]; then
# Set XKB environment variables to fix keyboard issues
export XKB_DEFAULT_LAYOUT="us"
export XKB_DEFAULT_MODEL="pc105"
export XKB_DEFAULT_VARIANT=""
export XKB_DEFAULT_OPTIONS=""
# Launch X session (MBetterClient will be started by .xinitrc)
exec startx
fi
EOF
# Create .xinitrc for proper X session startup
cat
>
"
$TARGET_MOUNT
/home/mbetterclient/.xinitrc"
<<
'
EOF
'
#!/bin/sh
# X session initialization for mbetterclient
# Set keyboard layout
setxkbmap us
# Launch Openbox window manager
exec openbox-session &
# Give Openbox a moment to start
sleep 1
# Launch MBetterClient in a terminal
xterm -e '/usr/local/bin/MbetterClient_wrapper.sh --ssl --web-host 0.0.0.0'
EOF
chmod
+x
"
$TARGET_MOUNT
/home/mbetterclient/.xinitrc"
# Set proper ownership
chroot
"
$TARGET_MOUNT
"
chown
mbetterclient:mbetterclient /home/mbetterclient/.bashrc
chroot
"
$TARGET_MOUNT
"
chown
mbetterclient:mbetterclient /home/mbetterclient/.xinitrc
# Set timezone from selection or preseed or default
if
[
-f
/tmp/selected_timezone
]
;
then
TIMEZONE
=
$(
cat
/tmp/selected_timezone
)
print_status
"Setting timezone to selected:
$TIMEZONE
"
else
TIMEZONE
=
$(
get_preseed_value
"time/zone"
||
echo
"UTC"
)
print_status
"Setting timezone to
$TIMEZONE
..."
fi
chroot
"
$TARGET_MOUNT
"
ln
-sf
"/usr/share/zoneinfo/
$TIMEZONE
"
/etc/localtime
# Set hostname
echo
"debian"
>
"
$TARGET_MOUNT
/etc/hostname"
# Create fstab
ROOT_UUID
=
$(
blkid
-s
UUID
-o
value
"
${
TARGET_DISK
}
1"
)
cat
>
"
$TARGET_MOUNT
/etc/fstab"
<<
EOF
# <file system> <mount point> <type> <options> <dump> <pass>
UUID=
$ROOT_UUID
/ ext4 errors=remount-ro 0 1
proc /proc proc defaults 0 0
EOF
# Configure inittab for mbetterclient autologin
print_status
"Configuring inittab for mbetterclient autologin..."
cat
>
"
$TARGET_MOUNT
/etc/inittab"
<<
EOF
# /etc/inittab: init(8) configuration.
#
$Id
: inittab,v 1.91 2002/01/25 13:35:21 miquels Exp $
# The default runlevel.
id:2:initdefault:
# Boot-time system configuration/initialization script.
# This is run first except when booting in emergency (-b) mode.
si::sysinit:/etc/init.d/rcS
# What to do in single-user mode.
~~:S:wait:/sbin/sulogin
# /etc/init.d executes the S and K scripts upon change
# of runlevel.
#
# Runlevel 0 is halt.
# Runlevel 1 is single-user.
# Runlevel 2-5 are multi-user.
# Runlevel 6 is reboot.
l0:0:wait:/etc/init.d/rc 0
l1:1:wait:/etc/init.d/rc 1
l2:2:wait:/etc/init.d/rc 2
l3:3:wait:/etc/init.d/rc 3
l4:4:wait:/etc/init.d/rc 4
l5:5:wait:/etc/init.d/rc 5
l6:6:wait:/etc/init.d/rc 6
# Normally not reached, but fallthrough in case of emergency.
z6:6:respawn:/sbin/sulogin
# /sbin/getty invocations for the runlevels.
#
# The "id" field MUST be the same as the last
# characters of the device (after "tty").
#
# Format:
# <id>:<runlevels>:<action>:<process>
#
# Autologin for mbetterclient on tty1
1:2345:respawn:/sbin/getty --autologin mbetterclient --noclear 38400 tty1
# Normal getty for other terminals
2:23:respawn:/sbin/getty 38400 tty2
3:23:respawn:/sbin/getty 38400 tty3
4:23:respawn:/sbin/getty 38400 tty4
5:23:respawn:/sbin/getty 38400 tty5
6:23:respawn:/sbin/getty 38400 tty6
# Example how to put a getty on a serial line (for a terminal)
#
#T0:23:respawn:/sbin/getty -L ttyS0 9600 vt100
#T1:23:respawn:/sbin/getty -L ttyS1 9600 vt100
# Example how to put a getty on a modem line.
#
#T3:23:respawn:/sbin/mgetty -x0 -s 57600 ttyS3
EOF
# Configure network for installed system if configuration was collected
if
[
-f
/tmp/network_config
]
;
then
print_status
"Applying network configuration to installed system..."
# Source the network configuration
.
/tmp/network_config
if
[
-n
"
$SELECTED_INTERFACE
"
]
;
then
# Create interfaces configuration
cat
>
"
$TARGET_MOUNT
/etc/network/interfaces"
<<
NETEOF
# Network configuration applied during installation
auto lo
iface lo inet loopback
auto
$SELECTED_INTERFACE
NETEOF
if
[
"
$INTERFACE_TYPE
"
=
"wireless"
]
&&
[
-n
"
$WIFI_SSID
"
]
;
then
# Configure WiFi
echo
"iface
$SELECTED_INTERFACE
inet
$NETWORK_CONFIG
"
>>
"
$TARGET_MOUNT
/etc/network/interfaces"
if
[
"
$NETWORK_CONFIG
"
=
"static"
]
&&
[
-n
"
$STATIC_IP
"
]
;
then
echo
" address
$STATIC_IP
"
>>
"
$TARGET_MOUNT
/etc/network/interfaces"
echo
" gateway
$STATIC_GATEWAY
"
>>
"
$TARGET_MOUNT
/etc/network/interfaces"
fi
# WiFi-specific configuration
echo
" wireless-essid
$WIFI_SSID
"
>>
"
$TARGET_MOUNT
/etc/network/interfaces"
if
[
"
$WIFI_SECURITY
"
!=
"NONE"
]
&&
[
-n
"
$WIFI_PASSWORD
"
]
;
then
if
[
"
$WIFI_SECURITY
"
=
"WPA"
]
;
then
echo
" wpa-passphrase
$WIFI_PASSWORD
"
>>
"
$TARGET_MOUNT
/etc/network/interfaces"
else
# WEP
echo
" wireless-key
$WIFI_PASSWORD
"
>>
"
$TARGET_MOUNT
/etc/network/interfaces"
fi
fi
print_status
"WiFi configuration applied:
$WIFI_SSID
(
$WIFI_SECURITY
)"
else
# Configure Ethernet
echo
"iface
$SELECTED_INTERFACE
inet
$NETWORK_CONFIG
"
>>
"
$TARGET_MOUNT
/etc/network/interfaces"
if
[
"
$NETWORK_CONFIG
"
=
"static"
]
&&
[
-n
"
$STATIC_IP
"
]
;
then
echo
" address
$STATIC_IP
"
>>
"
$TARGET_MOUNT
/etc/network/interfaces"
echo
" gateway
$STATIC_GATEWAY
"
>>
"
$TARGET_MOUNT
/etc/network/interfaces"
fi
print_status
"Ethernet configuration applied:
$SELECTED_INTERFACE
(
$NETWORK_CONFIG
)"
fi
# Configure DNS if static
if
[
"
$NETWORK_CONFIG
"
=
"static"
]
&&
[
-n
"
$STATIC_DNS
"
]
;
then
echo
"nameserver
$STATIC_DNS
"
>
"
$TARGET_MOUNT
/etc/resolv.conf"
print_status
"DNS server configured:
$STATIC_DNS
"
fi
print_status
"Network configuration written to installed system"
fi
else
print_status
"No network configuration to apply - using defaults"
fi
# Generate SSH host keys for installed system
print_status
"Generating SSH host keys for installed system..."
# Remove any existing host keys
rm
-f
"
$TARGET_MOUNT
/etc/ssh/ssh_host_*_ke"
*
# Generate new SSH host keys silently
chroot
"
$TARGET_MOUNT
"
ssh-keygen
-q
-t
rsa
-b
4096
-f
/etc/ssh/ssh_host_rsa_key
-N
""
||
true
chroot
"
$TARGET_MOUNT
"
ssh-keygen
-q
-t
ecdsa
-b
521
-f
/etc/ssh/ssh_host_ecdsa_key
-N
""
||
true
chroot
"
$TARGET_MOUNT
"
ssh-keygen
-q
-t
ed25519
-f
/etc/ssh/ssh_host_ed25519_key
-N
""
||
true
# Remove live-specific configurations
rm
-f
"
$TARGET_MOUNT
/etc/systemd/system/getty@tty1.service.d/live-config.conf"
2>/dev/null
||
true
rm
-rf
"
$TARGET_MOUNT
/lib/live"
2>/dev/null
||
true
rm
-f
"
$TARGET_MOUNT
/etc/profile.d/zz-live-config_xinit.sh"
2>/dev/null
||
true
rm
-rf
"
$TARGET_MOUNT
/usr/share/initramfs-tools/hooks/live"
2>/dev/null
||
true
# Set suid on X server and xkbcomp for mbetterclient user to start X
print_status
"Setting suid on X server and xkbcomp for user X startup..."
chmod
u+s
"
$TARGET_MOUNT
/usr/bin/Xorg"
2>/dev/null
||
true
chmod
u+s
"
$TARGET_MOUNT
/usr/lib/xorg/Xorg"
2>/dev/null
||
true
chmod
u+s
"
$TARGET_MOUNT
/usr/bin/xkbcomp"
2>/dev/null
||
true
# Configure NTP for clock synchronization
print_status
"Configuring NTP for clock synchronization..."
# Enable systemd-timesyncd for automatic time synchronization
chroot
"
$TARGET_MOUNT
"
systemctl
enable
systemd-timesyncd 2>/dev/null
||
true
# Configure NTP servers
cat
>
"
$TARGET_MOUNT
/etc/systemd/timesyncd.conf"
<<
EOF
[Time]
NTP=pool.ntp.org
FallbackNTP=0.debian.pool.ntp.org 1.debian.pool.ntp.org 2.debian.pool.ntp.org 3.debian.pool.ntp.org
EOF
print_status
"Target system configuration completed"
}
# Install bootloader
install_bootloader
()
{
print_header
"Installing Bootloader"
# Ensure dhcpcd.conf has IPv6 disabled if it exists
if
[
-f
"
$TARGET_MOUNT
/etc/dhcpcd.conf"
]
;
then
if
!
grep
-q
"noipv6rs"
"
$TARGET_MOUNT
/etc/dhcpcd.conf"
;
then
echo
"noipv6rs"
>>
"
$TARGET_MOUNT
/etc/dhcpcd.conf"
fi
if
!
grep
-q
"noipv6"
"
$TARGET_MOUNT
/etc/dhcpcd.conf"
;
then
echo
"noipv6"
>>
"
$TARGET_MOUNT
/etc/dhcpcd.conf"
fi
fi
print_status
"Installing GRUB to
$TARGET_DISK
..."
chroot
"
$TARGET_MOUNT
"
grub-install
"
$TARGET_DISK
"
chroot
"
$TARGET_MOUNT
"
update-grub
print_status
"Bootloader installation completed"
}
# Run post-installation setup
run_post_install
()
{
print_header
"Post-Installation Setup"
# Run our post-install script if available
if
[
-f
/cdrom/setup-installed-system.sh
]
;
then
print_status
"Running post-installation setup..."
bash /cdrom/setup-installed-system.sh
"
$TARGET_MOUNT
"
fi
print_status
"Post-installation setup completed"
}
# Cleanup and unmount
cleanup
()
{
print_header
"Installation Complete"
# Remove auto-installer from installed system (cleanup)
print_status
"Removing auto-installer from installed system..."
rm
-f
"
$TARGET_MOUNT
/usr/local/bin/auto-installer.sh"
2>/dev/null
||
true
rm
-f
"
$TARGET_MOUNT
/var/log/auto-installer.log"
2>/dev/null
||
true
print_status
"Unmounting filesystems..."
umount
"
$TARGET_MOUNT
/dev/pts"
2>/dev/null
||
true
umount
"
$TARGET_MOUNT
/dev"
2>/dev/null
||
true
umount
"
$TARGET_MOUNT
/sys"
2>/dev/null
||
true
umount
"
$TARGET_MOUNT
/proc"
2>/dev/null
||
true
umount
"
$TARGET_MOUNT
"
2>/dev/null
||
true
print_header
"SUCCESS: Installation completed successfully!"
print_status
"The system has been installed to
$TARGET_DISK
"
print_status
"Installed system will:"
print_status
" - Autologin as mbetterclient user"
print_status
" - Start MbetterClient automatically on tty1"
print_status
" - Include VPN configuration if provided"
print_status
" - Allow root SSH login with configured password"
print_status
""
print_status
"System will reboot in 10 seconds..."
sleep
10
reboot
}
# Main installation process
main
()
{
print_header
"MBetter Offline Automatic Installer"
print_status
"Starting OFFLINE automated installation..."
print_status
"This installer copies the live system - NO internet required!"
print_status
"USB-aware: Works from CD/DVD or USB drive"
log
"Starting offline installation process"
# Start visual progress display
start_progress_display
trap
cleanup_progress EXIT
# Step 1: Device Detection
update_progress 1
"Detecting USB device and target disk..."
detect_usb_device
detect_target_disk
||
{
print_error
"Cannot proceed without a target disk"
exit
1
}
print_status
"Installation will use:"
print_status
" Source: Live system (USB/CD:
${
USB_DEVICE
:-
unknown
}
)"
print_status
" Target:
$TARGET_DISK
"
# Step 2: Timezone Selection
update_progress 2
"Selecting timezone..."
select_timezone
# Step 3: Network Configuration
update_progress 3
"Configuring network (optional)..."
configure_network
# Step 4: Find Configuration
update_progress 4
"Loading installation configuration..."
find_preseed
# Step 5: User Confirmation (REQUIRED before destructive operations)
update_progress 5
"Waiting for user confirmation..."
confirm_installation
||
{
print_error
"Installation cancelled by user"
exit
0
}
# Step 6: Disk Partitioning
update_progress 6
"Partitioning target disk..."
partition_disk
mount_target
# Step 7: System Copy (longest step)
update_progress 7
"Copying live system to disk (this may take several minutes)..."
copy_live_system
# Step 8: System Configuration
update_progress 8
"Configuring target system..."
configure_target_system
# Step 9: Bootloader Installation
update_progress 9
"Installing bootloader..."
install_bootloader
# Step 10: Post-Installation Setup
update_progress 10
"Finalizing installation..."
run_post_install
# Complete - terminal notification
print_header
"Installation Complete!"
print_status
"Installation completed successfully!"
print_status
"System will reboot in 10 seconds..."
cleanup
}
# Trap to cleanup on exit
trap
'umount "$TARGET_MOUNT"/{dev/pts,dev,sys,proc,} 2>/dev/null || true'
EXIT
# Run main function
main
"
$@
"
config/package-lists/live.list.chroot
View file @
53413811
...
...
@@ -6,7 +6,9 @@ openssh-server
openvpn
xserver-xorg
xinit
openbox
xfce4
lightdm
lightdm-gtk-greeter
debian-keyring
debian-archive-keyring
...
...
@@ -59,6 +61,10 @@ xserver-xorg-video-intel
xserver-xorg-video-amd
xserver-xorg-video-nouveau
xserver-xorg-video-nvidia
nvidia-modprobe
glx-alternative-nvidia
nvtop
linux-headers-amd64
xserver-xorg-video-radeon
xserver-xorg-video-ati
xserver-xorg-video-vmware
...
...
@@ -104,6 +110,14 @@ gstreamer1.0-pipewire
# Text editors
vim
# Font packages
fonts-noto-color-emoji
fonts-symbola
fonts-twemoji
fonts-recommended
fonts-dejavu
fonts-liberation
# Core utilities (essential command-line tools)
coreutils
...
...
@@ -169,3 +183,8 @@ libdrm2
libgtk-3-dev
libxcb1-dev
libxss1
# Additional packages
python3-pyconify
fontconfig
xfonts-utils
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment