1
0
mirror of synced 2026-01-13 07:29:52 +00:00
Frank Halasz 4b95a8b5d3
Windows installer and medley script for running Medley in Docker on Windows (#1077)
* Update docker file build to use new deb linux installers;  move Dockefile to .github/workflows since its really only useable from the buildDocker.yml workflow

* Fix typo in dockerfile location

* remove extraneous " in >>GITHUB_ENV statements

* Fix handling of TARGETPLATFORM in Dockerfile

* Trying with just one platform

* Fix issues with missing man-db in docker build workflow; added man-db to depends in deb builds for linux

* Sicthed docker from tightvnc to tigervnc to match oio.  This getting the apt package name right.

* Going back to single platform to debug this thing

* Trying with just arm64

* Removing arm/v7 from docker images.  Takes too long to build and just wastes our github actions minutes.  This is assuming its a never used feature since docker is not big on raspberry pis and their ilk.

* Fix typo in control-linux; update build_deb so that files in /usr/local installed by deb are owned by root; add ubuntu user and nano in docker file for dbebugging;  when in draft only create for x86_64 platform

* Fix typo in buildDocker.yml

* Add sudo to docker image; in docker image ensure that all /usr/local/interlisp files are owned by root

* Add securityTypes none to docker entrypoint

* Updated docker base to Ubuntu 22.10 to get fixed xrdp; add xrdp to the docker image; updated user permission in docker image;

* In Dockerfile make xrdp install noninteractive

* Update medley.sh scripts to handle docker case

* Fix a couple of typos

* BuildDcoker: added pulling latest draft release (if any) when this is a draft docker build; removed checkout of medley code cause its not used

* BuildDocker: added medley checkout backin - turns pout its needed by a bunch of actions even though I dont really think they use it

* BuildDocker: moved download assets to use gh instaed of a marketplace action becauase that action could not handle draft releases.

* Tweaking medley.sh and associated tweaks to work Windows via wsl medley and docker

* adding first pass at powershell script for windows docker and wsl

* Tuning how Xvnc, medley, and vncviewer handle the various ways of exiting - eg logout vs closing viewer window.

* Tuning vncviewer launch to make sure that tty works as expected when medley.sh runs in background

* Minor typo fixes and added extra check to use of /run/shm in medley_vnc.sh

* Added SSH_KEY secret to buildReleaseIncDocker workflow

* Gertting the add SSH_KEY secret into orkflows right this time, hopefully

* Adding TERM env variable and setting USER to medley in docker image

* Debugging medley.ps1 and adding a couple of arguments

* Typo in Dockerfile medley

* Synchronizing flag processing and usage for medley.ps1 and medley.sh; refactored medley_args.sh and medley_usage.sh code.

* Adding first pass at windows installer

* Adding first pass an inno setup script for Windows installation

* Update buildLoadup workflow and downloads page for windows installer

* Fix typo in buildLoadup

* BuildLoadup make sure windows runner uses powershell

* Another typo in buildLoadup

* Another typo in buildLoadup; damn those double quotes

* Updating handling of windows installer in buildLoadup, added vncviewer to medley.iss install

* Unknown syntax error in buildLoadup

* Another damn typo from double quotes

* buildLoadup: fixed loadup job outputs

* buidLoadup: fixed bug with COMBINED_RELEASE_TAG; fixed Upload script in windows job to be compatible with actions.script v6.

* buidLoadup: upload win installer adapted to find draft releases as well as full releases

* BuildLoadup: fixing up javascript in actions in windows job to use / instead of \ in pathname

* BuildLoadup: changing win installer update to same action used for other release assets

* Fix windows installer file name; in BuildLoadup move update downl;oad page to the Windows runner because uploading the window-installer changes the release download url, so updating the downloads page must be done after the windows installer upload.; General buildLoadup cleanup

* Run md2html to update downloads page

* Fix typo in build_deb.sh

* Removing some leftover crud in medley_usage.sh

* Fixing up windows installer a bit, mostly cosmetic

* Adding support for WSL1; mostly forcing --vnc and changing how to find open ports and displays since WSL1 networking is different tha WSL2

* Update manual page for new Windows Medley script

* First pass done for man page that incorporates new Windows medley script.  Add Xvnc wait before calling run-medley in case of docker to prevent occasonal missing X windows server error.

* Change buildLoadup to update man page to a draft if this is a draft run.
2023-02-18 06:19:57 -08:00

411 lines
12 KiB
PowerShell
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

###############################################################################
#
# medley.ps1 - PowerShell script for running Medley Interlisp in a Docker
# container on Windows. This script will pull the
# interlisp/medley docker container, run the container
# using the Linux medley script as the entrypoint
# passing on the flags as given to this script, and
# then start a vncviewer onto medley running in the
# container.
#
# This script can also be used to start medley in a WSL
# distro, although the same can easily be accomplished
# using the wsl command.
#
# 2023-02-10 Frank Halasz
#
# Copyright 2023 Interlisp.org
#
###############################################################################
#
# Various useful functions
#
# Function to check if docker is installed on this system
function Test-DockerInstalled {
$ErrorActionPreference = "SilentlyContinue"
if (Get-Command "docker" -Syntax)
{ return $true }
else
{ return $false }
}
# Function to check if docker is running on this system
function Test-DockerRunning {
$ErrorActionPreference = "SilentlyContinue"
docker info 2>&1 >$null
if ( $LastExitCode -eq 0 )
{ return $true }
else
{ return $false }
}
# Function to test if WSL is installed on this machine
function Test-WSLInstalled {
#$ErrorActionPreference = "SilentlyContinue"
if ((Get-Command "wsl" -Syntax) -and
(((wsl --list --verbose) -replace "`0" | Measure-Object -Line | Select -ExpandProperty Lines) -gt 1))
{ return $true }
else
{ return $false }
}
# Function to test if a named WSL distro is actually present
function Test-WSLDistro {
param($distro="unknown")
$paddedDistro= " " + $distro + " "
if ( (wsl --list --verbose) -replace "`0" | Select-String -Pattern $paddedDistro )
{ return $true }
else
{ return $false }
}
# Function to test if medley is installed (using standard installation)
# in the wsl distro whose name is the first and only arg. Defaults
# to the default wsl distro
function Test-MedleyInstalled {
param($distro)
if($distro -and (-not (Test-WSLDistro $distro)))
{
return $false
}
if ($distro)
{
$is_installed = wsl -d $distro bash -c "test -e /usr/local/interlisp; echo \`$?"
}
else
{
$is_installed = wsl bash -c "test -e /usr/local/interlisp; echo \`$?"
}
if ($is_installed -eq 0)
{
return $true
}
else
{
return $false
}
}
# Function to find an unused port between 5900 and 5999
function Find-OpenPort {
$min_port=5900
$max_port=5999
$udp_openPorts = Get-NetUDPEndpoint | Where-Object { ($_.LocalPort -ge $min_port) -and ($_.LocalPort -le $max_port) }
$tcp_openPorts = Get-NetTCPConnection | Where-Object { ($_.LocalPort -ge $min_port) -and ($_.LocalPort -le $max_port) }
$openPorts = ($udp_openPorts + $tcp_openPorts) | Select-Object -Property LocalPort | Sort-Object -Property LocalPort -Unique
$expected=$min_port;
foreach ($port in $openPorts)
{
if ( $port.LocalPort -ne $expected )
{
break;
}
else
{
${expected}++
}
}
if ($expected -gt $max_port)
{
Write-Output "Error: No available ports between 5900 and 5999."
Write-Output "Exiting."
exit 34
}
else
{
return $expected
}
}
#
# Function that processes all the arguments to this script
#
function Process-Args {
# Default values for script-scoped varaibles
$script:bg = $false
$script:draft = "latest"
$script:logindir = "${env:USERPROFILE}\AppData\Local\Medley\il"
$script:medleyArgs = @()
$script:noviewer = $false
$script:port = $false
$script:update = $false
$script:wsl = $false
$displayFlag = $false
$display = ""
# Variables local this function
$passRest = $false
$vncRequested = $false
# Loop thru args
for ( $idx = 0; $idx -lt $args.count; $idx++ ) {
$arg = $args[$idx]
if ($passRest)
{
$script:medleyArgs += $args
continue
}
switch($arg) {
{ @("-b", "--background") -contains $_ }
{
$script:bg= $true
}
{ @("-d", "--display") -contains $_ }
{
$displayFlag = $true
$display = $args[$idx+1]
if ( ($idx + 1 -gt $args.count) -or ($display -match "^-") )
{
Write-Output "Error: the `"--display`" flag is missing its value" "Exiting"
exit 33
}
if ( $display -notmatch ":[0-9]+" )
{
Write-Output "Error: the `"--display`" value is not of the form `":N`, where N is number between 0 and 63: $display" "Exiting"
exit 33
}
}
{ @("-h", "--help", "-z", "--man") -contains $_ }
{
$script:noviewer = $true
$script:medleyArgs += $_
}
{ @("-p", "--port") -contains $_ }
{
if ( ($idx + 1 -gt $args.count) -or ($args[$idx+1] -match "^-") )
{
Write-Output "Error: the `"-p / --port`" flag is missing its value" "Exiting"
exit 33
}
$script:port = $args[$idx+1]
if (( $script:port -notmatch "^[0-9]*`$" ) -or ( $script:port -le 1024) -or ( $script:port -gt 65535 ))
{
Write-Output "Error: the value of `"-p / --port`" flag is not an integer between 1025 and 65535: $script:port " "Exiting"
exit 33
}
$idx++
}
{ @("-u", "--update") -contains $_ }
{
$script:update = $true
}
{ @("-v", "--vnc") -contains $_ }
{
$vncRequested = $true
}
{ @("-w", "--wsl") -contains $_ }
{
if (-not (Test-WSLInstalled))
{
Write-Output "Error: The `"-w / --wsl`" flag was used, But WSL is not installed." "Exiting"
exit 33
}
if ( ($idx + 1 -gt $args.count) -or ($args[$idx+1] -match "^-") )
{
Write-Output "Error: the `"--wsl`" flag is missing its value" "Exiting"
exit 33
}
$script:wsl = $true
$script:wslDistro = $args[$idx + 1]
if (($script:wslDistro -ne "-") -and (-not (Test-WSLDistro $script:wslDistro)))
{
Write-Output "Error: value of `"--wsl`" flag is not an installed WsL distro: $script:wslDistro." "Exiting"
exit 33
}
if (-not (Test-MedleyInstalled $script:wslDistro))
{
Write-Output "Error: value of `"--wsl`" flag is an installed WsL distro, but Medley is not installed in standard location: $script:wslDistro." "Exiting"
exit 33
}
$idx++
}
{ @("-x", "--logindir") -contains $_ }
{
$script:logindir=$args[$idx+1]
$idx++
}
{ @("-y", "--draft") -contains $_ }
{
$script:draft="draft"
}
{ $_ -eq "--" }
{
$passRest=$true
$script:medleyArgs += $_
}
default
{
$script:medleyArgs += $_
}
}
}
if ($script:logindir)
{
if ($script:wsl)
{
$script:medleyArgs = @( "--logindir", $script:logindir) + $script:medleyArgs
}
}
if ($script:update -and $script:wsl)
{
Write-Output "Warning: Both the -u or --update flag and the -w or --wsl flags were given. "
Write-Output "The -u or --update flag is not relevant for wsl."
Write-Output "Ignoring the -u or --update flag."
}
if ($vncRequested)
{
if (-not $script:wsl)
{
Write-Output "Warning: The -v or --vnc flag is not relevant when running under docker"
Write-Output "Ignoring the -v or --vnc flag."
}
else
{
$script:medleyArgs = @( "--vnc") + $script:medleyArg
}
}
if ($script:wsl -and $displayFlag)
{
$script:medleyArgs = @( "--display", "$display") + $script:medleyArg
}
}
###############################################################################
#
# Main script
#
#
# Process the arguments
#
Process-Args @args
#
# If we're not calling wsl, check if docker is installed and running,
# check if logindir is a legitamte directory, do the pull if required.
#
if (-not $wsl)
{
# Make sure docker is installed
if (-not (Test-DockerInstalled) )
{
Write-Output "Error: Docker is not installed on this system."
Write-Output "This medley app requires Docker unless the --wsl flag is used"
Write-Output "Exiting."
exit 34
}
# Make sure docker is running
if (-not (Test-DockerRunning) )
{
Write-Output "Error: The Docker engine is installed but not currently running on this system."
Write-Output "This medley app requires the Docker Engine running unless the --wsl flag is used"
Write-Output "Exiting."
exit 33
}
# Check/create logindir
if (-not (Test-Path -Path $logindir -PathType Container))
{
try
{
$null = New-Item -ItemType Directory -Path ${logindir} -Force -ErrorAction Stop
}
catch
{
Write-Output "Error: The specified logindir does not exist and cannot be created: ${logindir}"
Write-Output "Exiting."
exit 35
}
}
# Do a pull if required
if ($update -or (-not (docker image ls interlisp/medley:${draft} | Select-String medley)))
{
docker pull interlisp/medley:${draft}
}
}
#
# Call wsl or run docker
#
if ($wsl)
{
#
# Call wsl
#
if ( $wslDistro -eq "-" )
{
$distro = @()
}
else
{
$distro = @( "-d", $wslDistro )
}
wsl @distro medley @medleyArgs
}
else
{
#
# Run docker and vncviewer
#
# Find an open port to use for vnc
if (-not $port) { $port=Find-OpenPort }
Write-Output "Using VNC_PORT=$port"
# Unless $noviewer is set (i.e., if --help and --man flag are set),
# start the vncviwer in the background.
# But wait for the docker container to actually come up
# before starting it
if (-not $noviewer)
{
Start-Job -InputObject "$port" -ScriptBlock {
$port = $input.Clone()
$stopTime = (Get-Date).AddSeconds(10)
$hit=$false
while ((-not $hit) -and ((Get-Date) -lt $stopTime))
{
docker container ls | Select-String 'medley' | Select-String "${port}->5900" | Set-Variable "hit"
if (-not $hit) { Start-Sleep -Milliseconds 250 }
}
if ($hit)
{
Write-Host $hit
vncviewer64-1.12.0.exe -geometry '+50+50' -ReconnectOnError=off AlertOnFatalError=off localhost:${port}
}
} >$null
}
#
# Run the docker container using medley as the entrypoint and passing on the args
# Run in the foreground unless requested to run in the background by the -b flag.
#
if (-not $bg)
{
docker run -it --rm -p ${port}:5900 -v ${logindir}:/home/medley/il --entrypoint medley --env TERM=xterm interlisp/medley:${draft} --windows @medleyArgs
}
else
{
$dockerArgs=@("run", "--rm", "-p", "${port}:5900", "-v", "${logindir}:/home/medley/il", "--entrypoint", "medley", "interlisp/medley:${draft}", "--windows") + $medleyArgs
Start-Process -NoNewWindow -FilePath "docker" -ArgumentList $dockerArgs
}
}
###############################################################################
#
# Done
#
###############################################################################