Skip to content

Commit

Permalink
new install fixes
Browse files Browse the repository at this point in the history
- BalenaCli
  - support win
  - version: get correct version
- BalenaEtcher: added
- drive getType: sudoc is not needed
- function.sh
  - AvailableTimeoutGet: return default value if no value in bootstrap-config.sh
  - GetDnsSearch: do not show error if /etc/resolv.conf is not present
  - IsXServerRunning: check if the X Server is available
  - ScriptErrEnd: added
  - sudoc
    - do not prompt for a password if stdin is not available
    - ensure prompt is visible
    - show more detail if sudo --validate fails
  - UserCreate: only show generated passwords
- inst
  - i: allow regular function calls (simplify winPath calls)
  - appCoreStart appCoreEnd: expose for install
  - BalenaCli: app name to work with BalenaCli helper script
  - Password: check if user exists
  - gwsl: fix executable check
- network: currentUpdate: add quick check
- password: add user existence check
  • Loading branch information
JohnButare committed Nov 29, 2024
1 parent 1a82026 commit 84f349c
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 27 deletions.
4 changes: 3 additions & 1 deletion BalenaCli
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ init()
{
defaultCommand="start"
program="$P/balena-cli/balena"
IsPlatform win && program+=".exe"
return 0
}

closeCommand() { ! isRunningCommand && return 0; ProcessClose "$program"; }
Expand All @@ -21,6 +23,6 @@ programCommand() { echo "$program"; }
startArgs() { startArgs=( "$@" ); (( shift+=$# )); return 0; }
startCommand() { AppInstallCheck && "$program" "${startArgs[@]}" "${otherArgs[@]}"; }
startupCommand() { isRunningCommand && return; startCommand; }
versionCommand() { AppInstallCheck && AppVersion "$program"; }
versionCommand() { AppInstallCheck && "$program" --version; }

ScriptRun "$@"
26 changes: 26 additions & 0 deletions BalenaEtcher
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/env bash
. "${BASH_SOURCE[0]%/*}/function.sh" app script || exit

usage()
{
ScriptUsage "$1" "\
Usage: $(ScriptName) [OPTION]... [start|program|IsInstalled|IsRunning|version](start)
$(ScriptName) commands."
}

init()
{
defaultCommand="start"
program="$UADATA/balena_etcher/balenaEtcher.exe"
}

closeCommand() { ! isRunningCommand && return 0; ProcessClose "$program"; }
isInstalledCommand() { [[ -f "$program" ]]; }
isRunningCommand() { IsProcessRunning "$program"; }
programCommand() { echo "$program"; }
startArgs() { startArgs=( "$@" ); (( shift+=$# )); return 0; }
startCommand() { AppInstallCheck && "$program" "${startArgs[@]}" "${otherArgs[@]}"; }
startupCommand() { isRunningCommand && return; startCommand; }
versionCommand() { AppInstallCheck && AppVersion "$program"; }

ScriptRun "$@"
2 changes: 1 addition & 1 deletion app
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ discord() { IsProcessRunning Discord.exe || taskStart "$UADATA/Discord/app-0.0.3
docker() { runService "docker"; }
duet() { taskStart "$P/Kairos/Duet Display/duet.exe"; }
Explorer() { [[ "$command" == "startup" ]] && ! IsProcessRunning explorer.exe && start explorer; }
FixTime() { [[ ! $force ]] && ClockHelper check && return; printf "time."; ClockHelper --quiet fix $force $verbose; }
FixTime() { [[ ! $force ]] && ClockHelper check && return; printf "time."; ClockHelper fix $force $verbose; }
GlassWire() { IsProcessRunning "GlassWire.exe" || taskStart "$P32/GlassWire/glasswire.exe" "" -hide; }
Greenshot() { IsProcessRunning "Greenshot.exe" || taskStart "$P/Greenshot/Greenshot.exe" "" ; }
incron() { runService "incron"; }
Expand Down
2 changes: 1 addition & 1 deletion drive
Original file line number Diff line number Diff line change
Expand Up @@ -671,7 +671,7 @@ getType()

# blkid
if InPath blkid; then
local type="$(eval $(sudoc blkid "/dev/$device" -o export); echo $TYPE)" || return
local type="$(eval $(blkid "/dev/$device" -o export); echo $TYPE)" || return
echo "$type"; return
fi

Expand Down
61 changes: 48 additions & 13 deletions function.sh
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ ActualUser() { echo "${SUDO_USER-$USER}"; }
CreateId() { echo "$((1000 + RANDOM % 9999))"; }
UserDelete() { local user="$1"; ! UserExists "$user" && return; IsPlatform mac && { sudoc dscl . delete "/Users/$group"; return; }; sudoc userdel "$user"; }
UserExists() { IsPlatform mac && { dscl . -list "/Users" | ${G}grep --quiet "^${1}$"; return; }; getent passwd "$1" >& /dev/null; }
UserExistsWin() { IsPlatform win || return; net.exe user "$1" >& /dev/null; }
UserInGroup() { id "$1" 2> /dev/null | ${G}grep --quiet "($2)"; } # UserInGroup USER GROUP
UserList() { IsPlatform mac && { dscl . -list "/Users"; return; }; getent passwd | cut -d: -f1 | sort; }
GroupDelete() { local group="$1"; ! GroupExists "$group" && return; IsPlatform mac && { sudoc dscl . delete "/Groups/$group"; return; }; sudoc groupdel "$group"; }
Expand Down Expand Up @@ -285,7 +286,7 @@ PasswordSet() { PasswordGet | cred set "$@" - ; }
# --ssh-copy copy the current users SSH configuration to the new user
UserCreate()
{
local admin system sslCopy user password;
local admin system sslCopy user password passwordShow;

# options
while (( $# != 0 )); do
Expand All @@ -303,7 +304,7 @@ UserCreate()
done

[[ ! $user ]] && { MissingOperand "user" "UserCreate"; return 1; }
[[ ! $password ]] && { password="$(pwgen 14 1)" || return; }
[[ ! $password ]] && { passwordShow="true"; password="$(pwgen 14 1)" || return; }

# create user
if ! UserExists "$user"; then
Expand All @@ -323,7 +324,7 @@ UserCreate()

fi

echo "User '$user' password is $password"
[[ "$passwordShow" ]] && echo "User '$user' password is $password"
fi

# make user administrator
Expand Down Expand Up @@ -2387,7 +2388,11 @@ NetworkCurrentUpdate()
# network: host availability
#

AvailableTimeoutGet() { local t="$(UpdateGet "hostTimeout")"; echo "${t:-$(ConfigGet "hostTimeout")}"; }
AvailableTimeoutGet()
{
local t="$(UpdateGet "hostTimeout")"; [[ ! $t ]] && t="$(ConfigGet "hostTimeout")"
echo "${t:-200}"
}

AvailableTimeoutSet()
{
Expand All @@ -2407,7 +2412,7 @@ IsAvailable()
# - mDNS name resolution is intermitant (double check this on various platforms)
# - Windows ping.exe name resolution is slow for non-existent hosts
local ip; ip="$(GetIpAddress --quiet "$host")" || return

if IsPlatform wsl1; then # WSL 1 ping does not timeout quickly for unresponsive hosts, ping.exe does
RunWin ping.exe -n 1 -w "$timeout" "$ip" |& grep "bytes=" &> /dev/null
elif InPath fping; then
Expand Down Expand Up @@ -2579,10 +2584,16 @@ WaitForPort() # WaitForPort HOST PORT [TIMEOUT_MILLISECONDS] [WAIT_SECONDS]
#

AddDnsSuffix() { GetArgs2; HasDnsSuffix "$1" && echo "$1" || echo "$1.$2"; } # AddDnsSuffix HOST DOMAIN - add the specified domain to host if a domain is not already present
GetDnsSearch() { cat "/etc/resolv.conf" | grep "^search " | cut -d" " -f2-; } # GetDnsSearch - get the system DNS search domains
GetDnsSuffix() { GetArgs; ! HasDnsSuffix "$1" && return; printf "${@#*.}"; } # GetDnsSuffix HOST - the DNS suffix of the HOST
HasDnsSuffix() { GetArgs; local p="\."; [[ "$1" =~ $p ]]; } # HasDnsSuffix HOST - true if the specified host includes a DNS suffix

# GetDnsSearch - get the system DNS search domains
GetDnsSearch()
{
local f="/etc/resolv.conf"; [[ ! -f "$f" ]] && return 1
cat "$f" | grep "^search " | cut -d" " -f2-
}

# RemoveDnsSuffix HOST - remove the DNS suffix if present
RemoveDnsSuffix()
{
Expand Down Expand Up @@ -4349,6 +4360,7 @@ RunFunctions()
ScriptArgs() { PrintErr "$1: "; shift; printf "\"%s\" " "$@" >&2; echo >&2; } # ScriptArgs SCRIPT_NAME ARGS... - display script arguments
ScriptCheckMac() { IsMacAddress "$1" && return; ScriptErr "'$1' is not a valid MAC address"; }
ScriptErr() { [[ $1 ]] && HilightErr "$(ScriptPrefix "$2")$1" || HilightErr; return 1; } # ScriptErr MESSAGE SCRIPT_NAME - hilight a script error message as SCRIPT_NAME: MESSAGE
ScriptErrEnd() { [[ $1 ]] && HilightErrEnd "$(ScriptPrefix "$2")$1" || HilightErrEnd; return 1; }
ScriptErrQuiet() { [[ $quiet ]] && return 1; ScriptErr "$@"; }
ScriptExit() { [[ "$-" == *i* ]] && return "${1:-1}" || exit "${1:-1}"; }; # ScriptExit [STATUS](1) - return or exist from a script with the specified status
ScriptFileCheck() { [[ -f "$1" ]] && return; [[ ! $quiet ]] && ScriptErr "file '$1' does not exist"; return 1; }
Expand Down Expand Up @@ -4534,6 +4546,9 @@ sudoc()
# set variables
local prompt="[sudoc] password for $USER on $HOSTNAME: "
local command=( "$(FindInPath "sudo")" )

# do not prompt no prompt if there is no stdin
! IsStdIn && noPrompt="--no-prompt"

# determine environment variables need to be preserved when running sudo
if [[ $preserve ]]; then
Expand All @@ -4559,7 +4574,7 @@ sudoc()
if [[ ! $stderr ]] && IsStdOut; then
PrintEnd "$prompt" || return
elif IsStdErr; then
EchoEnd "$prompt || return"
PrintErr "$prompt" || return
else
noPrompt="--no-prompt"
fi
Expand All @@ -4568,11 +4583,12 @@ sudoc()
# validate sudo to cache credentials
# - do separately from running the command so can use stdin in the command
if [[ $password ]]; then
echo "$password" | "${command[@]}" --prompt="" --stdin --validate || return
echo "$password" | "${command[@]}" --prompt="" --stdin --validate
else
[[ $noPrompt ]] && command+=(--non-interactive)
"${command[@]}" --prompt="" --validate || return
"${command[@]}" --prompt="" --validate
fi
(( ? != 0 )) && { ScriptErrEnd "unable to run command '"${args[@]}"'" "sudoc"; return 1; }

# run the command
# - do not use -- to allow environment variables, i.e. sudoc TEST=1 ls
Expand Down Expand Up @@ -4858,7 +4874,6 @@ GetVmType() # vmware|hyperv
#

HasWindowManager() { ! IsSsh || IsXServerRunning; } # assume if we are not in an SSH shell we are running under a Window manager
IsXServerRunning() { InPath xhost && xhost >& /dev/null; } # was xprop -root >& /dev/null
RestartGui() { IsPlatform win && { RestartExplorer; return; }; IsPlatform mac && { RestartDock; return; }; }
WinExists() { ! IsPlatform win && return 1; ! tasklist.exe /fi "WINDOWTITLE eq $1" | grep --quiet "No tasks are running"; }

Expand All @@ -4884,12 +4899,12 @@ InitializeXServer()

# display
if [[ $force || ! $DISPLAY ]]; then
if IsPlatform wsl2 && ! IsSsh && CanElevate; then
if [[ $SSH_CONNECTION ]]; then
export DISPLAY="$(GetWord "$SSH_CONNECTION" 1):0"
elif IsPlatform wsl2 && CanElevate; then
local ip="0.0.0.0"; ! wsl supports mirrored && ip="$(GetWslGateway)"
export DISPLAY="$ip:0"
export LIBGL_ALWAYS_INDIRECT=1
elif [[ $SSH_CONNECTION ]]; then
export DISPLAY="$(GetWord "$SSH_CONNECTION" 1):0"
else
export DISPLAY=:0
fi
Expand Down Expand Up @@ -4921,6 +4936,26 @@ InitializeXServer()
X_SERVER_CHECKED="true"
}

# IsXServerRunning - was xprop -root >& /dev/null
IsXServerRunning()
{
[[ ! $DISPLAY ]] && return 1
local ip="$(GetWord "$DISPLAY" 1 ":")"

if IsIpAddress "$ip"; then
local timeout="$(AvailableTimeoutGet)"

# quick timeout if the X Server is local
if [[ "$ip" == @(0.0.0.0) ]] || { IsPlatform wsl && [[ "$ip" == @(GetWslGateway) ]]; }; then
timeout=10
fi

IsAvailablePort "$ip" 6000 "$timeout" || return
fi

InPath xhost && xhost >& /dev/null
}

WinSetStateUsage()
{
EchoWrap "\
Expand Down
2 changes: 1 addition & 1 deletion hashi
Original file line number Diff line number Diff line change
Expand Up @@ -4321,7 +4321,7 @@ productVerify()
local product="$1"; [[ ! $product ]] && MissingOperand "product"
productIsInstalled "$product" && return
ScriptErrQuiet "$product is not installed"
Z
}

# productVersion PRODUCT WHAT - show the versionof the specified product
productVersion()
Expand Down
21 changes: 13 additions & 8 deletions inst
Original file line number Diff line number Diff line change
Expand Up @@ -1223,6 +1223,9 @@ iApp()
# apps to ignore
[[ "${app,,}" =~ ^(gitkrakendeb)$ ]] && return

# call a regular (non-install) function
IsFunction "$app" && { "$app"; return; }

# find the name of the function used to install the application
app="$(appGetInstallFunction "$app")" || return

Expand Down Expand Up @@ -1321,6 +1324,7 @@ isInstallable()
IsInArray -ci "$check" debRh && IsPlatform debian,rh && return
IsInArray -ci "$check" mac && IsPlatform mac && return
IsInArray -ci "$check" macDeb && IsPlatform mac,debian && return
IsInArray -ci "$check" macDebQnap && IsPlatform mac,debian,qnap && return
IsInArray -ci "$check" macDebRh && IsPlatform debian,mac,rh && return
IsInArray -ci "$check" macWin && IsPlatform mac,win && return
IsInArray -ci "$check" pi && IsPlatform pi && return
Expand Down Expand Up @@ -2185,13 +2189,13 @@ AppCoreInstall()
muteInstallable="true"

# install
appCoreStart && winPathFix && i AppCoreCommon AppPlatform AppNetwork AppHardware AppHost && appCoreEnd && rebootIfNeeded;
i AppCoreStart winPathFix AppCoreCommon AppPlatform AppNetwork AppHardware AppHost AppCoreEnd rebootIfNeeded;
}

appCoreStart() { header "App Core Start"; RunPlatform appCoreStart; }
AppCoreStartInstall() { header "App Core Start"; RunPlatform appCoreStart; }
appCoreStartWsl() { header "App Core Start WSL"; return 0; } # service stop dbus; pkill dbus-daemon; dbus service causes restart prompts on fresh install

appCoreEnd()
AppCoreEndInstall()
{
header "App Core End"
! UpdateNeeded "install-app-core-end" && return
Expand Down Expand Up @@ -2749,7 +2753,7 @@ bootstrapStartWin()
header "Bootstrap Start Win"

# Hidden Start - install early if possible to prevent excessive UAC dialogs
CanElevate && ! IsDomainRestricted && { { winPathFix && i HiddenStartConfigure; } || return; }
CanElevate && ! IsDomainRestricted && { i winPathFix HiddenStartConfigure || return; }

# Set default user to aid troubleshooting - only supported in WSL 2+
! IsPlatform wsl1 && { wsl dist user set --user="$USER" || return; }
Expand Down Expand Up @@ -5144,7 +5148,7 @@ PowerCoreInstall()
BalenaCliInstall()
{
local v; v="$(versionGetCurrent "BalenaCli")" || return
local file="balena-cli-v$v"; run "$(balenaCliDir)/$file-windows-x64-standalone.zip|$file-macOS-x64-standalone.zip|$file-linux-x64-standalone.zip" --dest "balena-cli" --elevate --version=$v || return
local file="balena-cli-v$v"; run --name="BalenaCli" "$(balenaCliDir)/$file-windows-x64-standalone.zip|$file-macOS-x64-standalone.zip|$file-linux-x64-standalone.zip" --dest "balena-cli" --elevate --version=$v || return
}

BalenaCliDownload()
Expand Down Expand Up @@ -9977,7 +9981,7 @@ PassInstall()

PasswordInstall()
{
header "Passwords"
header "Password"
! IsPlatform win && return
[[ ! $force ]] && ! UpdateNeeded "install-password" && return

Expand All @@ -9986,7 +9990,8 @@ PasswordInstall()
password win --password "$password" || return

local password; password="$(credential get system default --quiet --fallback)" || return
password win --user "$(ConfigGet "systemUser")" --password "$password" || return
local user=$(ConfigGet "systemUser");
UserExistsWin "$user" && { password win --user "$user" --password "$password" || return; }

UpdateDone "install-password"
}
Expand Down Expand Up @@ -12627,7 +12632,7 @@ xServerWin() { IsDomainRestricted && return; IsVm && return; i gwsl && wsl wslg
# GWSL - donation
gwslInstall()
{
local gwsl="$UADATA/Microsoft/WindowsApps/gwsl"
local gwsl="$UADATA/Microsoft/WindowsApps/gwsl.exe"
[[ -f "$gwsl" && ! $force ]] && return
run --name "GWSL" --store "9NL6KD1H33V3"
}
Expand Down
10 changes: 8 additions & 2 deletions network
Original file line number Diff line number Diff line change
Expand Up @@ -288,8 +288,11 @@ currentUpdateCommand()
# get cached network
local network; network="$(UpdateGetForce "network")" || return

# return if recently updated
local cache="network-current-update"; [[ $network ]] && ! UpdateNeeded "$cache" && return
# return if recently updated and we pass quick checks
local cache="network-current-update";
if [[ $network ]] && updateCheckQuick && ! UpdateNeeded "$cache"; then
return
fi

# check if the current network is the same (the default gateway is the same and the DNS server is valid)
if [[ ! $force ]] && updateCheckGateway && updateCheckDns; then
Expand Down Expand Up @@ -339,6 +342,9 @@ updateCheckGateway()
return 1
}

updateCheckQuick() { RunPlatform updateCheckQuick; }
updateCheckQuickWsl() { [[ -f "/etc/resolv.conf" ]]; }

# updateDns NETWORK
updateDns() { RunPlatform updateDns && updateHosts; }

Expand Down
1 change: 1 addition & 0 deletions password
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ smbCommand()
winCommand()
{
! IsPlatform win && return
UserExistsWin "$user" || { ScriptErr "Windows user '$user' does not exist"; return 1; }
JumpCloud IsInstalled && return # password managed by JumpCloud

getPassword || return
Expand Down

0 comments on commit 84f349c

Please sign in to comment.