diff --git a/.github/workflows/Dockerfile_medley b/.github/workflows/Dockerfile_medley new file mode 100644 index 00000000..6a26d93a --- /dev/null +++ b/.github/workflows/Dockerfile_medley @@ -0,0 +1,78 @@ +#******************************************************************************* +# +# Dockerfile to build Medley image from latest Maiko image +# plus latest release tars from github +# +# Copyright 2022-2023 by Interlisp.org +# +# ****************************************************************************** + +FROM ubuntu:22.10 +ARG TARGETPLATFORM + +# Handle ARGs, ENV variables, and LABELs +ARG BUILD_DATE=unknown +ARG MEDLEY_RELEASE=unknown +ARG MAIKO_RELEASE=unknown +ARG REPO_OWNER=Interlisp +LABEL name="Medley" +LABEL description="The Medley Interlisp environment" +LABEL url="https://github.com/${REPO_OWNER}/medley" +LABEL build-date=$BUILD_DATE +LABEL medley_release=$MEDLEY_RELEASE +LABEL maiko_release=$MAIKO_RELEASE + +ENV MEDLEY_DOCKER_BUILD_DATE=$BUILD_DATE +ENV MEDLEY_RELEASE=$MEDLEY_RELEASE +ENV MAIKO_RELEASE=$MAIKO_RELEASE + +ENV LANG=C.UTF-8 + +# Copy over the release deb files +ADD ./*.deb /tmp + +# Install Medley/Maiko and add tightvnc server and xclip to the image +RUN apt-get update \ + && apt-get install -y apt-utils \ + && apt-get install -y tigervnc-standalone-server \ + && apt-get install -y xclip \ + && apt-get install -y man-db \ + && apt-get install -y nano \ + && apt-get install -y sudo \ + && p=$(echo "${TARGETPLATFORM}" | sed -e "s#linux/##") \ + && p=$( \ + if [ "$p" = "amd64" ]; \ + then echo "x86_64"; \ + elif [ "$p" = "arm64" ]; \ + then echo "aarch64"; \ + elif [ "$p" = "arm/v7" ]; \ + then echo "armv7l"; \ + else \ + echo "x86_64"; \ + fi \ + ) \ + && deb="medley-full-${MEDLEY_RELEASE#medley-}" \ + && deb=${deb}_${MAIKO_RELEASE#maiko-}-linux-${p}.deb \ + && apt-get install -y /tmp/${deb} \ + && chown --recursive root:root /usr/local/interlisp \ + && (if [ -n "$(which unminimize)" ]; then (yes | unminimize); fi) + +# "Finalize" image +EXPOSE 5900 +RUN adduser --gecos "" medley \ + && adduser --gecos "" ubuntu \ + && adduser medley sudo \ + && adduser ubuntu sudo \ + && (echo 'medley:yeldem' | chpasswd ) \ + && (echo 'ubuntu:utnubu' | chpasswd ) \ + && echo "medley ALL=(ALL) NOPASSWD:ALL" >>/etc/sudoers \ + && echo "ubuntu ALL=(ALL) NOPASSWD:ALL" >>/etc/sudoers \ + && mkdir -p /home/medley/il \ + && chown medley:medley /home/medley/il + +ENV TERM=xterm +USER medley +WORKDIR /home/medley +#ENTRYPOINT USER=medley Xvnc -SecurityTypes none -geometry 1280x720 :0 & DISPLAY=:0 medley --full -g 1280x720 +ENTRYPOINT /bin/bash + diff --git a/.github/workflows/buildDocker.yml b/.github/workflows/buildDocker.yml index 7046ef75..c9171daa 100644 --- a/.github/workflows/buildDocker.yml +++ b/.github/workflows/buildDocker.yml @@ -136,60 +136,60 @@ jobs: # Checkout latest commit - name: Checkout Medley uses: actions/checkout@v3 + + # Find latest release (draft or normal) + # and download its assets + - name: Download linux debs from latest (draft) release + run: | + tag="" + if [ "${{ needs.inputs.outputs.draft }}" = "true" ]; + then + tag=$(gh release list | grep Draft | head -n 1 | awk '{ print $3 }') + fi + if [ -z "${tag}" ]; + then + tag=$(gh release list | grep Latest | head -n 1 | awk '{ print $3 }') + fi + mkdir -p release_debs + gh release download ${tag} -D release_debs -p '*-linux-*.deb' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + # Get Maiko and Medley release information from name of deb files + # just downloaded from the Medley latest release + - name: Get info about Miako and Medley releases + id: release_info + run: | + regex="^[^0-9]*\([^_]*\)_\([^-]*-[^-]*\)-\([^-]*\)-\([^.]*\).*\$" + ls -1 release_debs | head -n 1 > debname.tmp + medley_release="medley-$(sed -e "s/${regex}/\1/" debname.tmp)" + maiko_release="maiko-$(sed -e "s/${regex}/\2/" debname.tmp)" + rm -f debname.tmp + echo "MEDLEY_RELEASE=${medley_release}" >> ${GITHUB_ENV} + echo "MAIKO_RELEASE=${maiko_release}" >> ${GITHUB_ENV} # Set repo env variables - name: Set repo/docker env variables id: repo_env run: | - REPO_NAME=${GITHUB_REPOSITORY#*/} - echo "REPO_NAME=${REPO_NAME}" >> ${GITHUB_ENV} - echo "repo_name=${REPO_NAME}" >> ${GITHUB_OUTPUT} - DOCKER_NAMESPACE=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]') - echo "DOCKER_NAMESPACE=${DOCKER_NAMESPACE}" >> ${GITHUB_ENV} - echo "docker_namespace=${DOCKER_NAMESPACE}" >> ${GITHUB_OUTPUT} - - # Get tag of latest Medley release. - - name: Get Medley Release Information - id: release_info - uses: abatilo/release-info-action@v1.3.2 - with: - owner: ${{ github.repository_owner }} - repo: medley - - # Get asset tars from latest Medley release - - name: Download Release Assets - uses: robinraju/release-downloader@v1.7 - with: - repository: ${{ github.repository_owner }}/medley - token: ${{ secrets.GITHUB_TOKEN }} - latest: true - fileName: "*" - out-file-path: "release_tars" - - # Get Maiko release information about latest Maiko Docker Image - - name: Get info from latest Maiko image - id: maiko_setup - run: | - docker pull ${DOCKER_NAMESPACE}/maiko:latest - MAIKO_RELEASE=$(docker run --entrypoint /bin/bash ${DOCKER_NAMESPACE}/maiko:latest -c "echo \${MAIKO_RELEASE}") - echo "MAIKO_RELEASE=${MAIKO_RELEASE}" >> ${GITHUB_ENV} - echo "maiko_release=${MAIKO_RELEASE}" >> ${GITHUB_OUTPUT} - - # Setup environment variables - - name: Setup Environment Variables - id: setup_env - run: | - RELEASE_TAG=${{ steps.release_info.outputs.latest_tag }} - DOCKER_IMAGE=${DOCKER_NAMESPACE}/${REPO_NAME} + repo_name="${GITHUB_REPOSITORY#*/}" + docker_namespace="$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]')" + docker_image="${docker_namespace}/${repo_name}" if [ "${{ needs.inputs.outputs.draft }}" = "false" ]; - then DOCKER_TAGS="${DOCKER_IMAGE}:latest,${DOCKER_IMAGE}:${RELEASE_TAG#*-}_${MAIKO_RELEASE#*-}" - else DOCKER_TAGS="${DOCKER_IMAGE}:draft" + then + docker_tags="${docker_image}:latest,${docker_image}:${MEDLEY_RELEASE#*-}_${MAIKO_RELEASE#*-}" + platforms="linux/amd64,linux/arm64" + else + docker_tags="${docker_image}:draft" + platforms="linux/amd64" fi - echo "docker_tags=${DOCKER_TAGS}" >> ${GITHUB_OUTPUT} - echo "docker_image=${DOCKER_IMAGE}" >> ${GITHUB_OUTPUT} - echo "build_time=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> ${GITHUB_OUTPUT} - echo "release_tag=${RELEASE_TAG}" >> ${GITHUB_OUTPUT} - echo "release_tag=${RELEASE_TAG}" >> ${GITHUB_ENV} + echo "REPO_NAME=${repo_name}" >> ${GITHUB_ENV} + echo "DOCKER_NAMESPACE=${docker_namespace}" >> ${GITHUB_ENV} + echo "DOCKER_IMAGE=${docker_image}" >> ${GITHUB_ENV} + echo "DOCKER_TAGS=${docker_tags}" >> ${GITHUB_ENV} + echo "BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> ${GITHUB_ENV} + echo "PLATFORMS=${platforms}" >> ${GITHUB_ENV} + #linux/amd64,linux/arm64,linux/arm/v7 # Setup the Docker Machine Emulation environment. - name: Set up QEMU @@ -217,17 +217,16 @@ jobs: with: builder: ${{ steps.buildx.outputs.name }} build-args: | - BUILD_DATE=${{ steps.setup_env.outputs.build_time }} - RELEASE_TAG=${{ steps.setup_env.outputs.release_tag }} - MAIKO_RELEASE=${{ steps.setup_env.outputs.maiko_release }} - DOCKER_NAMESPACE=${{ steps.repo_env.outputs.docker_namespace }} + BUILD_DATE=${{ env.BUILD_DATE }} + MEDLEY_RELEASE=${{ env.MEDLEY_RELEASE }} + MAIKO_RELEASE=${{ env.MAIKO_RELEASE }} REPO_OWNER=${{ github.repository_owner }} - context: ./release_tars - file: ./Dockerfile - platforms: linux/amd64,linux/arm64,linux/arm/v7 + context: ./release_debs + file: ./.github/workflows/Dockerfile_medley + platforms: ${{ env.PLATFORMS }} # Push the result to DockerHub push: true - tags: ${{ steps.setup_env.outputs.docker_tags }} + tags: ${{ env.DOCKER_TAGS }} ###################################################################################### diff --git a/.github/workflows/buildLoadup.yml b/.github/workflows/buildLoadup.yml index 28810135..efae66d6 100644 --- a/.github/workflows/buildLoadup.yml +++ b/.github/workflows/buildLoadup.yml @@ -49,6 +49,9 @@ on: required: false type: string default: 'false' + secrets: + OIO_SSH_KEY: + required: true defaults: run: @@ -113,6 +116,8 @@ jobs: ###################################################################################### + + # # Do the loadup # @@ -120,6 +125,12 @@ jobs: runs-on: ubuntu-latest + outputs: + combined_release_tag: ${{ steps.job_outputs.outputs.COMBINED_RELEASE_TAG }} + medley_release_tag: ${{ steps.job_outputs.outputs.MEDLEY_RELEASE_TAG }} + medley_short_release_tag: ${{ steps.job_outputs.outputs.MEDLEY_SHORT_RELEASE_TAG }} + debs_filename_base: ${{ steps.debs.outputs.DEBS_FILENAME_BASE }} + needs: [inputs, sentry] if: | needs.sentry.outputs.release_not_built == 'true' @@ -143,20 +154,6 @@ jobs: id: tag uses: ./../actions/release-tag-action - # Setup environment variables - - name: Setup Environment Variables - id: setup_env - run: | - echo "build_time=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> ${GITHUB_OUTPUT} - echo "TARBALL_DIR=installers/deb/tmp/tarballs" >>${GITHUB_ENV} - echo "DEBS_DIR=installers/deb/debs" >>${GITHUB_ENV} - echo "TARS_DIR=installers/deb/tars" >>${GITHUB_ENV} - echo "MEDLEY_RELEASE_TAG=${RELEASE_TAG}" >>${GITHUB_ENV} - - # Setup some needed dirs in workspace - - name: Create work dirs - run: mkdir -p ${TARBALL_DIR} - # Get Maiko release information, retrieves the name of the latest # release. Used to download the correct Maiko release - name: Get Maiko Release Information @@ -166,6 +163,33 @@ jobs: owner: ${{ github.repository_owner }} repo: maiko + # Setup environment variables & establish job outputs + - name: Setup Environment Variables + run: | + echo "build_time=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> ${GITHUB_OUTPUT} + echo "TARBALL_DIR=installers/deb/tmp/tarballs" >>${GITHUB_ENV} + echo "DEBS_DIR=installers/deb/debs" >>${GITHUB_ENV} + echo "TARS_DIR=installers/deb/tars" >>${GITHUB_ENV} + echo "MEDLEY_RELEASE_TAG=${RELEASE_TAG}" >>${GITHUB_ENV} + echo "MAIKO_RELEASE_TAG=${{ steps.maiko.outputs.latest_tag }}" >>${GITHUB_ENV} + - name: More Environment Variables + run: | + echo "MEDLEY_SHORT_RELEASE_TAG=${MEDLEY_RELEASE_TAG#medley-}" >>${GITHUB_ENV} + echo "MAIKO_SHORT_RELEASE_TAG=${MAIKO_RELEASE_TAG#maiko-}" >>${GITHUB_ENV} + - name: Even More Environment Variables + run: | + echo "COMBINED_RELEASE_TAG=${MEDLEY_SHORT_RELEASE_TAG}_${MAIKO_SHORT_RELEASE_TAG}" >>${GITHUB_ENV} + - name: Establish job outputs + id: job_outputs + run: | + echo "COMBINED_RELEASE_TAG=${COMBINED_RELEASE_TAG}" >> $GITHUB_OUTPUT; + echo "MEDLEY_RELEASE_TAG=${MEDLEY_RELEASE_TAG}" >> $GITHUB_OUTPUT; + echo "MEDLEY_SHORT_RELEASE_TAG=${MEDLEY_SHORT_RELEASE_TAG}" >> $GITHUB_OUTPUT; + + # Setup some needed dirs in workspace + - name: Create work dirs + run: mkdir -p ${TARBALL_DIR} + # Download Maiko Release Assets - name: Download Release Assets uses: robinraju/release-downloader@v1.6 @@ -174,11 +198,11 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} latest: true out-file-path: ${{ env.TARBALL_DIR }} - fileName: "${{ steps.maiko.outputs.latest_tag }}-linux.*.tgz" + fileName: "${{ env.MAIKO_RELEASE_TAG }}-linux.*.tgz" - name: Untar Maiko Release for use in loadup run: | - tar -xzf "${TARBALL_DIR}/${{ steps.maiko.outputs.latest_tag }}-linux.x86_64.tgz" + tar -xzf "${TARBALL_DIR}/${{ env.MAIKO_RELEASE_TAG }}-linux.x86_64.tgz" # Checkout Notecards and tar it in the tarballsdir - name: Checkout Notecards @@ -192,7 +216,7 @@ jobs: cd .. tar cfz medley/${TARBALL_DIR}/notecards.tgz notecards - # + # Install vnc - name: Install vnc run: sudo apt-get update && sudo apt-get install -y tightvncserver @@ -202,7 +226,7 @@ jobs: export DISPLAY=":0" PATH="$PWD/maiko:$PATH" scripts/loadup-all.sh -apps - + - name: Build loadups release tar run: | cd .. @@ -240,11 +264,16 @@ jobs: medley/internal + # Build the deb files as well as the tgz files - name: Build .deb files for 3 architectures + id: debs run: | cd installers/deb - ./build_deb.sh + debs_filename_base=$(./build_deb.sh) + echo "DEBS_FILENAME_BASE=${debs_filename_base}" >> $GITHUB_ENV; + echo "DEBS_FILENAME_BASE=${debs_filename_base}" >> $GITHUB_OUTPUT; + # Push the release up to github releases - name: Delete existing release with same tag (if any) uses: cb80/delrel@latest with: @@ -267,41 +296,114 @@ jobs: generateReleaseNotes: true token: ${{ secrets.GITHUB_TOKEN }} - - name: Update the downloads page and the man page to the OIO satic page host + + # + # Create the Windows installer, push it up to the release on github and + # update the downloads page on OIO + # + windows_installer: + + runs-on: windows-latest + + needs: [inputs, sentry, loadup] + if: | + needs.sentry.outputs.release_not_built == 'true' + || needs.inputs.outputs.force == 'true' + + steps: + # Checkout latest commit + - name: Checkout Medley + uses: actions/checkout@v3 + + # Store the values output from loadup job as environment variables + - name: Environment Variables + shell: powershell run: | - maiko_release_tag="${{ steps.maiko.outputs.latest_tag }}" - medley_short_release_tag="${MEDLEY_RELEASE_TAG#medley-}" - full_release_filename="${MEDLEY_RELEASE_TAG/medley/medley-full}_${maiko_release_tag#maiko-}" - # Need info about where github stores assets because draft releases are not tagged - release_url="${{ steps.push_release.outputs.html_url }}" - github_subdir="$( echo "${release_url}" | sed -e "s#^.*/\([^/]\+\)\$#\1#g" )" - # + $crt="${{ needs.loadup.outputs.combined_release_tag }}" + echo "COMBINED_RELEASE_TAG=$crt" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append + $mrt="${{ needs.loadup.outputs.medley_release_tag }}" + echo "MEDLEY_RELEASE_TAG=$mrt" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append + $msrt="${{ needs.loadup.outputs.medley_short_release_tag }}" + echo "MEDLEY_SHORT_RELEASE_TAG=$msrt" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append + $debs="${{ needs.loadup.outputs.debs_filename_base }}" + echo "DEBS_FILENAME_BASE=$debs" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append + + # Download vnc viewer + - name: Download vncviewer + shell: powershell + run: | + $url = "https://sourceforge.net/projects/tigervnc/files/stable/1.12.0/vncviewer64-1.12.0.exe" + $output = "installers\win\vncviewer64-1.12.0.exe" + (New-Object System.Net.WebClient).DownloadFile($url, $output) + + # Run iscc.exe to compile the installer + - name: Compile medley.iss + shell: powershell + run: | + iscc installers\win\medley.iss + $filename="medley-install_${env:COMBINED_RELEASE_TAG}_x64.exe" + echo "INSTALLER_FILENAME=$filename" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append + + # Upload windows installer to release + - name: Upload windows installer to release + id: push + uses: ncipollo/release-action@v1 + with: + allowUpdates: true + artifacts: installers/win/${{ env.INSTALLER_FILENAME }} + tag: ${{ env.MEDLEY_RELEASE_TAG }} + token: ${{ secrets.GITHUB_TOKEN }} + omitBodyDuringUpdate: true + omitDraftDuringUpdate: true + omitNameDuringUpdate: true + omitPrereleaseDuringUpdate: true + + # Install the OpenSSH Client + - name: Install the OpenSSH Client + shell: powershell + run: | + Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0 + + # Update the downloads page and the man page on OIO + - name: Update the downloads page and the man page to the OIO static page host + shell: bash + run: | + # Figure out filenames + download_url="${{ steps.push.outputs.html_url }}" + download_url="${download_url/\/tag\//\/download\/}" local_template="installers/downloads_page/medley_downloads.html" local_filename="medley_downloads.html" + local_manpath="docs/man-page/man_medley.html" if [ "${{ needs.inputs.outputs.draft }}" = "true" ]; then remote_filename="draft_downloads" + remote_manname="man_draft.html" else remote_filename="${local_filename%.html}" + remote_manname="man_medley.html" fi remote_filepath="/srv/oio/static/${remote_filename}" + remote_manpath="/srv/oio/static/${remote_manname}" + # Fill in downloads page template sed \ - -e "s/@@@FULL.RELEASE.FILENAME@@@/${full_release_filename}/g" \ - -e "s/@@@GITHUB.SUBDIR@@@/${github_subdir}/g" \ - -e "s/@@@MEDLEY.SHORT.RELEASE.TAG@@@/${medley_short_release_tag}/g" \ + -e "s/@@@MEDLEY.SHORT.RELEASE.TAG@@@/${MEDLEY_SHORT_RELEASE_TAG}/g" \ + -e "s~@@@DOWNLOAD_URL@@@~${download_url}~g" \ + -e "s/@@@DEBS.FILENAME.BASE@@@/${DEBS_FILENAME_BASE}/g" \ + -e "s/@@@WINDOWS.INSTALLER.FILENAME@@@/${INSTALLER_FILENAME}/g" \ < "${local_template}" > "${local_filename}" - local_manpath="docs/man-page/man_medley.html" - remote_manpath="/srv/oio/static/man_medley.html" + # Create sftp instruction file echo "-rm ${remote_filepath}.oldold" > batch echo "-rename ${remote_filepath}.old ${remote_filepath}.oldold" >> batch echo "-rename ${remote_filepath}.html ${remote_filepath}.old" >> batch echo "-put ${local_filename} ${remote_filepath}.html" >> batch echo "-put ${local_manpath} ${remote_manpath}" >> batch + # Do the sftp eval $(ssh-agent) ssh-add - <<< "${SSH_KEY}" sftp -o StrictHostKeyChecking=no -b batch ubuntu@online.interlisp.org env: SSH_KEY: ${{ secrets.OIO_SSH_KEY }} + ###################################################################################### @@ -316,7 +418,7 @@ jobs: outputs: build_successful: ${{ steps.output.outputs.build_successful }} - needs: [inputs, sentry, loadup] + needs: [inputs, sentry, loadup, windows_installer] steps: # Checkout the actions for this repo owner @@ -340,3 +442,21 @@ jobs: echo "build_successful='true'" >> $GITHUB_OUTPUT ###################################################################################### + + + +# - name: Download the Windows installer created in windows job +# uses: actions/download-artifact@v3 +# with: +# name: windows_installer +# path: installers/win + +# - name: Rename the Windows installer w/ version tag +# run: | +# maiko_release_tag="${{ steps.maiko.outputs.latest_tag }}" +# combined_release_tag="${MEDLEY_RELEASE_TAG#medley-}_${maiko_release_tag#maiko-}" +# windows_installer_filename="medley_install_${combined_release_tag}_x64.exe" +# cd installers/win +# mv medley_install_vXXXVERSIONXXX_x64.exe "${windows_installer_filename}" +# echo "WINDOWS_INSTALLER_FILENAME=${windows_installer_filename}" >>${GITHUB_ENV} + diff --git a/.github/workflows/buildReleaseInclDocker.yml b/.github/workflows/buildReleaseInclDocker.yml index aac9b2f9..c45fc532 100644 --- a/.github/workflows/buildReleaseInclDocker.yml +++ b/.github/workflows/buildReleaseInclDocker.yml @@ -94,7 +94,9 @@ jobs: with: draft: ${{ needs.inputs.outputs.draft }} force: ${{ needs.inputs.outputs.force }} - + secrets: + OIO_SSH_KEY: ${{ secrets.OIO_SSH_KEY }} + ###################################################################################### @@ -109,6 +111,5 @@ jobs: DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - ###################################################################################### diff --git a/.github/workflows/testLogin.yml b/.github/workflows/testLogin.yml deleted file mode 100644 index ac943ac7..00000000 --- a/.github/workflows/testLogin.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: 'Test Docker Login' - -# Run this workflow on ... -on: - workflow_dispatch: - -defaults: - run: - shell: bash - - -jobs: - - login_test: - runs-on: ubuntu-latest - steps: - - id: only_step - uses: docker/login-action@v1 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - - diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 405675f5..00000000 --- a/Dockerfile +++ /dev/null @@ -1,55 +0,0 @@ -#******************************************************************************* -# -# Dockerfile to build Medley image from latest Maiko image -# plus latest release tars from github -# -# Copyright 2022-2023 by Interlisp.org -# -# ****************************************************************************** - -ARG DOCKER_NAMESPACE=interlisp - -FROM ${DOCKER_NAMESPACE}/maiko:latest - -# Add tightvnc server and xclip to the image -RUN apt-get update && apt-get install -y tightvncserver && apt-get install -y xclip - -# Handle ARGs, ENV variables, and LABELs -ARG BUILD_DATE=unknown -ARG RELEASE_TAG=unknown -ARG MAIKO_RELEASE=unknown -ARG REPO_OWNER=Interlisp -LABEL name="Medley" -LABEL description="The Medley Interlisp environment" -LABEL url="https://github.com/${REPO_OWNER}/medley" -LABEL build-time=$BUILD_DATE -LABEL release_tag=$RELEASE_TAG -LABEL maiko_release=$MAIKO_RELEASE - -ENV MEDLEY_BUILD_DATE=$BUILD_DATE -ENV MEDLEY_RELEASE=$RELEASE_TAG - -ARG IL_INSTALLDIR=/usr/local/interlisp -ENV IL_INSTALLDIR=${IL_INSTALLDIR} -ENV MAIKO_INSTALLDIR=${IL_INSTALLDIR}/maiko -ENV MEDLEY_INSTALLDIR=${IL_INSTALLDIR}/medley - -ARG DOCKER_NAMESPACE=interlisp -ENV DOCKER_NAMESPACE=${DOCKER_NAMESPACE} - -ENV LANG=C.UTF-8 - -# Copy over the release tars -RUN mkdir -p ${IL_INSTALLDIR} -ADD ./*.tgz ${IL_INSTALLDIR} - -# Link run_medley script into /usr/local/bin -RUN mkdir -p /usr/local/bin && \ - ln -s ${MEDLEY_INSTALLDIR}/run-medley /usr/local/bin/run-medley - -# "Finalize" image -EXPOSE 5900 -RUN adduser --disabled-password --gecos "" medley -USER medley -WORKDIR /home/medley -ENTRYPOINT USER=medley Xvnc -geometry 1280x720 :0 & DISPLAY=:0 ${MEDELY_INSTALLDIR}/run-medley -full -g 1280x720 -sc 1280x720 diff --git a/docs/man-page/man_medley.html b/docs/man-page/man_medley.html index b1b97048..44149e06 100644 --- a/docs/man-page/man_medley.html +++ b/docs/man-page/man_medley.html @@ -37,35 +37,50 @@

Sets the size of the virtual display as seen from Medley’s point of view. The Medley window is an unscaled viewport onto this virtual display. If --screensize is not specified but --geometry is, then the virtual display size will be set so that the entire virtual display fits into the given window geometry. If neither --screensize nor --geometry is provided, then the screen size is set to 1440x900.

-t STRING, --title STRING
-

Use STRING as title of Medley window. Not relevent when the --vnc flag is set.

+

Use STRING as title of Medley window. Ignored when when the --vnc flag is set or when running on Windows (Docker) installations.

-
-d :N, --display :N
-

Use X display :N. Defaults to the value of $DISPLAY. Not relevant when the --vnc flag is set.

+
-d :N, --display :N ** Not applicable to Windows (Docker) installations **
+

Use X display :N. Defaults to the value of $DISPLAY. This flag is ignored when the --vnc flag is set as well as on Windows (Docker) installations.

-
-v, --vnc (Applicable only to Windows System for Linux installations)
-

Use a VNC window running on the Windows side instead of an X window. The VNC window will folllow the Windows desktop scaling setting allowing for much more usable Medley on high resolution displays. On WSL, X windows do not scale well.

+
-v, --vnc ** Applicable only to WSL installations **
+

Use a VNC window running on the Windows side instead of an X window. The VNC window will folllow the Windows desktop scaling setting allowing for much more usable Medley on high resolution displays. On WSL, X windows do not scale well. This flag is always set for WSL1 installations.

-i [ID_STRING | - | --], --id [ID_STRING | - | --]

Use ID_STRING as the id for this run of Medley, iunless ID_STRING is “-” or “--”. If ID_STRING is “-”, then use the basename of $MEDLEYDIR as the id. If ID_STRING is “--”, then use the basename of the parent directory of $MEDLEYDIR as the id. Only one instance of Medley with a given id can run at a time. The id is used to distinguish the virtual memory stores so that multiple instances of Medley can run simultaneously. Default id is “default”.

-m N, --mem N
-

Set Medley to run in N MB of virtual memory. Defaults to 256MB.

+

Set Medley to run in N MB of virtual memory. Defaults to 256MB.

-p FILE, --vmem FILE
-

Use FILE as the Medley virtual memory (vmem) store. FILE must be writeable by the current user. Care must be taken not to use the same vmem FILE for two instances of Medley running simultaneously. The --id flag will not protect against vmem collisions when the --vmem flag is used. Default is to store the vmem in LOGINDIR/vmem/lisp_XXX.virtualmem, where XXX is the id of this Medley run (see --id flag above). See --logindir below for setting of LOGINDIR.

+

Use FILE as the Medley virtual memory (vmem) store. FILE must be writeable by the current user. Care must be taken not to use the same vmem FILE for two instances of Medley running simultaneously. The --id flag will not protect against vmem collisions when the --vmem flag is used. Default is to store the vmem in LOGINDIR/vmem/lisp_XXX.virtualmem, where XXX is the id of this Medley run (see --id flag above). See --logindir below for setting of LOGINDIR. On Windows (Docker) installations, FILE is specified in the Medley file system, not the host Windows file system.

-r [FILE | -], --greet [FILE | -]
-

Use FILE as the Medley greetfile, unless FILE is “-” in which case Medley will start up without using a greetfile. The default Medley greetfile is $MEDLEYDIR/greetfiles/MEDLEYDIR-INIT, except when the --apps flag is used in which case it is $MEDLEYDIR/greetfiles/APPS-INIT.

+

Use FILE as the Medley greetfile, unless FILE is “-” in which case Medley will start up without using a greetfile. The default Medley greetfile is $MEDLEYDIR/greetfiles/MEDLEYDIR-INIT, except when the --apps flag is used in which case it is $MEDLEYDIR/greetfiles/APPS-INIT. On Windows (Docker) installations, FILE is specified in the Medley file system, not the host Windows file system.

-
-x [DIR | -], --logindir [DIR | -]
-

use DIR as LOGINDIR in Medley, unless DIR is “-”, in which case use $MEDLEYDIR/logindir. DIR (or $MEDLEYDIR/logindir) must be writeable by the current user. LOGINDIR defaults to $HOME/il. LOGINDIR is used by Medley as the working directory on start-up and where it loads any “personal” initialization file from.

+
-x [DIR | -], --logindir [DIR | -] ** On Linux and WSL installations **
+

Use DIR as LOGINDIR in Medley, unless DIR is “-”, in which case use $MEDLEYDIR/logindir. DIR (or $MEDLEYDIR/logindir) must be writeable by the current user. LOGINDIR defaults to $HOME/il. LOGINDIR is used by Medley as the working directory on start-up and where it loads any “personal” initialization file from.

+
+
-x [DIR | -], --logindir [DIR | -] ** On Windows (Docker) installations **
+

Map DIR in the Windows host file system to /home/medley/il in the Medley file system (in the Docker container). LOGINDIR is always /home/medley/il from Medley’s standpoint. The “-” value is not valid in this case.

+
+
-u, --update ** Windows (Docker) installations only **
+

Before running Medley, do a pull to retrieve the latest interlisp/medley docker image from Docker Hub.

+
+
-b, --background ** Windows (Docker) installations only **
+

Run Medley in background rather than foreground.

+
+
-p PORT, --port PORT ** Windows (Docker) installations only **
+

Use PORT as the port that VNC viewer uses to contact the VNC server within the Docker container. Default is 5900.

+
+
-w [DISTRO | -], --wsl [DISTRO | -] ** Windows (Docker) installations only **
+

Run Medley in the context of the named WSL DISTRO instead of within Docker. If DISTRO is “-”, used the default WSL distro. Equivalent to typing “wsl -d DISTRO medley ...” into a Command or Powershell window.

Other Options

SYSOUT_FILE
-

The pathname of the file to use as a sysout for Medley to start from. If SYSOUT_FILE is not provided and none of the flags (--apps, --full, --lisp) is used, then Medley will start from the saved virtual memory file from the previous session with the same ID_STRING as this run. If no such virtual memory file exists, then Medley will start from the standard full.sysout (equivalent to specifying the --full flag).

+

The pathname of the file to use as a sysout for Medley to start from. If SYSOUT_FILE is not provided and none of the flags (--apps, --full, --lisp) is used, then Medley will start from the saved virtual memory file from the previous session with the same ID_STRING as this run. If no such virtual memory file exists, then Medley will start from the standard full.sysout (equivalent to specifying the --full flag). On Windows (Docker) installations, SYSOUT_FILE is specified in the Medley file system, not the host Windows file system.

PASS_ON_ARGS

All arguments after the “--” flag, are passed unaltered to lde via run-medley.

diff --git a/docs/man-page/medley.1 b/docs/man-page/medley.1 index 6dbe6a6a..a5a0a746 100644 --- a/docs/man-page/medley.1 +++ b/docs/man-page/medley.1 @@ -95,18 +95,21 @@ size is set to 1440x900. .TP .B \-t \f[I]STRING\f[R], \-\-title \f[I]STRING\f[R] Use STRING as title of Medley window. -Not relevent when the \-\-vnc flag is set. +Ignored when when the \-\-vnc flag is set or when running on Windows +(Docker) installations. .TP -.B \-d \f[I]:N\f[R], \-\-display \f[I]:N\f[R] +.B \-d \f[I]:N\f[R], \-\-display \f[I]:N\f[R]\ \ \ \ ** \f[B]Not applicable to Windows (Docker) installations\f[R] ** Use X display :N. Defaults to the value of $DISPLAY. -Not relevant when the \-\-vnc flag is set. +This flag is ignored when the \-\-vnc flag is set as well as on Windows +(Docker) installations. .TP -.B \-v, \-\-vnc (Applicable only to Windows System for Linux installations) +.B \-v, \-\-vnc\ \ \ \ ** \f[B]Applicable only to WSL installations\f[R] ** Use a VNC window running on the Windows side instead of an X window. The VNC window will folllow the Windows desktop scaling setting allowing for much more usable Medley on high resolution displays. On WSL, X windows do not scale well. +This flag is always set for WSL1 installations. .TP .B \-i [\f[I]ID_STRING\f[R] | \- | \-\-], \-\-id [\f[I]ID_STRING\f[R] | \- | \-\-] Use ID_STRING as the id for this run of Medley, iunless ID_STRING is @@ -121,7 +124,7 @@ instances of Medley can run simultaneously. Default id is \[lq]default\[rq]. .TP .B \-m \f[I]N\f[R], \-\-mem \f[I]N\f[R] -Set Medley to run in N MB of virtual memory. +Set Medley to run in \f[I]N\f[R] MB of virtual memory. Defaults to 256MB. .TP .B \-p \f[I]FILE\f[R], \-\-vmem \f[I]FILE\f[R] @@ -134,6 +137,8 @@ The \-\-id flag will not protect against vmem collisions when the Default is to store the vmem in LOGINDIR/vmem/lisp_XXX.virtualmem, where XXX is the id of this Medley run (see \-\-id flag above). See \-\-logindir below for setting of LOGINDIR. +On Windows (Docker) installations, \f[I]FILE\f[R] is specified in the +Medley file system, not the host Windows file system. .TP .B \-r [\f[I]FILE\f[R] | \-], \-\-greet [\f[I]FILE\f[R] | \-] Use FILE as the Medley greetfile, unless FILE is \[lq]\-\[rq] in which @@ -141,14 +146,41 @@ case Medley will start up without using a greetfile. The default Medley greetfile is $MEDLEYDIR/greetfiles/MEDLEYDIR\-INIT, except when the \-\-apps flag is used in which case it is $MEDLEYDIR/greetfiles/APPS\-INIT. +On Windows (Docker) installations, \f[I]FILE\f[R] is specified in the +Medley file system, not the host Windows file system. .TP -.B \-x [\f[I]DIR\f[R] | \-], \-\-logindir [\f[I]DIR\f[R] | \-] -use DIR as LOGINDIR in Medley, unless DIR is \[lq]\-\[rq], in which case +.B \-x [\f[I]DIR\f[R] | \-], \-\-logindir [\f[I]DIR\f[R] | \-]\ \ \ \ ** \f[B]On Linux and WSL installations\f[R] ** +Use DIR as LOGINDIR in Medley, unless DIR is \[lq]\-\[rq], in which case use $MEDLEYDIR/logindir. DIR (or $MEDLEYDIR/logindir) must be writeable by the current user. LOGINDIR defaults to $HOME/il. LOGINDIR is used by Medley as the working directory on start\-up and where it loads any \[lq]personal\[rq] initialization file from. +.TP +.B \-x [\f[I]DIR\f[R] | \-], \-\-logindir [\f[I]DIR\f[R] | \-]\ \ \ \ ** \f[B]On Windows (Docker) installations\f[R] ** +Map DIR in the Windows host file system to /home/medley/il in the Medley +file system (in the Docker container). +LOGINDIR is always /home/medley/il from Medley\[cq]s standpoint. +The \[lq]\-\[rq] value is not valid in this case. +.TP +.B \-u, \-\-update\ \ \ \ ** \f[B]Windows (Docker) installations only\f[R] ** +Before running Medley, do a pull to retrieve the latest interlisp/medley +docker image from Docker Hub. +.TP +.B \-b, \-\-background\ \ \ \ ** \f[B]Windows (Docker) installations only\f[R] ** +Run Medley in background rather than foreground. +.TP +.B \-p \f[I]PORT\f[R], \-\-port \f[I]PORT\f[R]\ \ \ \ ** \f[B]Windows (Docker) installations only\f[R] ** +Use \f[I]PORT\f[R] as the port that VNC viewer uses to contact the VNC +server within the Docker container. +Default is 5900. +.TP +.B \-w [\f[I]DISTRO\f[R] | \-], \-\-wsl [\f[I]DISTRO\f[R] | \-]\ \ \ \ ** \f[B]Windows (Docker) installations only\f[R] ** +Run Medley in the context of the named WSL \f[I]DISTRO\f[R] instead of +within Docker. +If \f[I]DISTRO\f[R] is \[lq]\-\[rq], used the default WSL distro. +Equivalent to typing \[lq]wsl \-d \f[I]DISTRO\f[R] medley \&...\[rq] +into a Command or Powershell window. .SS Other Options .PP \ @@ -161,6 +193,8 @@ virtual memory file from the previous session with the same ID_STRING as this run. If no such virtual memory file exists, then Medley will start from the standard full.sysout (equivalent to specifying the \-\-full flag). +On Windows (Docker) installations, \f[I]SYSOUT_FILE\f[R] is specified in +the Medley file system, not the host Windows file system. .TP .B \f[I]PASS_ON_ARGS\f[R] All arguments after the \[lq]\-\-\[rq] flag, are passed unaltered to lde diff --git a/docs/man-page/medley.1.gz b/docs/man-page/medley.1.gz index 11dd5f37..a73df928 100644 Binary files a/docs/man-page/medley.1.gz and b/docs/man-page/medley.1.gz differ diff --git a/docs/man-page/medley.1.md b/docs/man-page/medley.1.md index 8b4d7e7e..0f0ed85d 100644 --- a/docs/man-page/medley.1.md +++ b/docs/man-page/medley.1.md @@ -41,7 +41,7 @@ Flags -z, \-\-man : Show the man page for medley --f, \-\-full +-f, \-\-full : Start Medley from the standard "full" sysout. full.sysout includes a complete Interlisp and CommonLisp environment with a standard set of development tools. It does not include any of the applications built using Medley. (See *SYSOUT_FILE* below for more information on starting sysouts.) @@ -80,17 +80,18 @@ The Medley window is an unscaled viewport onto this virtual display. If \-\-scre window geometry. If neither \-\-screensize nor \-\-geometry is provided, then the screen size is set to 1440x900. -t *STRING*, \-\-title *STRING* -: Use STRING as title of Medley window. Not relevent when the \-\-vnc flag is set. +: Use STRING as title of Medley window. Ignored when when the \-\-vnc flag is set or when running on Windows (Docker) +installations. --d *:N*, \-\-display *:N* -: Use X display :N. Defaults to the value of $DISPLAY. Not relevant when -the \-\-vnc flag is set. +-d *:N*, \-\-display *:N*    \*\* **Not applicable to Windows (Docker) installations** \*\* +~ Use X display :N. Defaults to the value of $DISPLAY. This flag is ignored when the \-\-vnc flag is set as +well as on Windows (Docker) installations. --v, \-\-vnc (Applicable only to Windows System for Linux installations) +-v, \-\-vnc    \*\* **Applicable only to WSL installations** \*\* : Use a VNC window running on the Windows side instead of an X window. The VNC window will folllow the Windows desktop scaling setting allowing for much more usable Medley on high resolution displays. On WSL, X windows -do not scale well. +do not scale well. This flag is always set for WSL1 installations. -i [*ID_STRING* | - | \-\-], \-\-id [*ID_STRING* | - | \-\-] : Use ID_STRING as the id for this run of Medley, iunless ID_STRING is "-" or "\-\-". @@ -101,27 +102,45 @@ The id is used to distinguish the virtual memory stores so that multiple instances of Medley can run simultaneously. Default id is "default". -m *N*, \-\-mem *N* -: Set Medley to run in N MB of virtual memory. Defaults to 256MB. +: Set Medley to run in *N* MB of virtual memory. Defaults to 256MB. -p *FILE*, \-\-vmem *FILE* : Use FILE as the Medley virtual memory (vmem) store. FILE must be writeable by the current user. Care must be taken not to use the same vmem FILE for two instances of Medley running simultaneously. The \-\-id flag will not protect against vmem collisions when the \-\-vmem flag is used. -Default is to store the vmem in LOGINDIR/vmem/lisp_XXX.virtualmem, where XXX is the id of this -Medley run (see \-\-id flag above). See \-\-logindir below for setting of LOGINDIR. +Default is to store the vmem in LOGINDIR/vmem/lisp_XXX.virtualmem, where XXX is the id of this +Medley run (see \-\-id flag above). See \-\-logindir below for setting of LOGINDIR. On Windows (Docker) installations, *FILE* is specified in the Medley file system, not the host Windows file system. -r \[*FILE* | -], \-\-greet \[*FILE* | -] : Use FILE as the Medley greetfile, unless FILE is "-" in which case Medley will start up without using a greetfile. The default Medley greetfile is $MEDLEYDIR/greetfiles/MEDLEYDIR-INIT, except when the \-\-apps flag is used -in which case it is $MEDLEYDIR/greetfiles/APPS-INIT. +in which case it is $MEDLEYDIR/greetfiles/APPS-INIT. On Windows (Docker) installations, *FILE* is +specified in the Medley file system, not the host Windows file system. --x \[*DIR* | -], \-\-logindir \[*DIR* | -] -: use DIR as LOGINDIR in Medley, unless DIR is "-", in which case use +-x \[*DIR* | -], \-\-logindir \[*DIR* | -]    \*\* **On Linux and WSL installations** \*\* +: Use DIR as LOGINDIR in Medley, unless DIR is "-", in which case use \$MEDLEYDIR/logindir. DIR (or \$MEDLEYDIR/logindir) must be writeable by the current user. LOGINDIR defaults to \$HOME/il. LOGINDIR is used by Medley as the working directory on start-up and where it loads any "personal" initialization file from. +-x \[*DIR* | -], \-\-logindir \[*DIR* | -]    \*\* **On Windows (Docker) installations** \*\* +: Map DIR in the Windows host file system to /home/medley/il in the Medley +file system (in the Docker container). LOGINDIR is always /home/medley/il from Medley's standpoint. The "-" value is not valid in this case. + +-u, \-\-update    \*\* **Windows (Docker) installations only** \*\* +: Before running Medley, do a pull to retrieve the latest interlisp/medley docker image from Docker Hub. + +-b, \-\-background    \*\* **Windows (Docker) installations only** \*\* +: Run Medley in background rather than foreground. + +-p *PORT*, \-\-port *PORT*    \*\* **Windows (Docker) installations only** \*\* +: Use *PORT* as the port that VNC viewer uses to contact the VNC server within the Docker container. Default is 5900. + +-w \[*DISTRO* | -], \-\-wsl \[*DISTRO* | -]    \*\* **Windows (Docker) installations only** \*\* +: Run Medley in the context of the named WSL *DISTRO* instead of within Docker. If *DISTRO* is "-", used the default WSL distro. Equivalent to typing "wsl -d *DISTRO* medley ..." into a Command or Powershell window. + + Other Options -------------   @@ -130,8 +149,9 @@ Other Options : The pathname of the file to use as a sysout for Medley to start from. If SYSOUT_FILE is not provided and none of the flags (\-\-apps, \-\-full, \-\-lisp) is used, then Medley will start from the saved virtual memory file from the previous session with the same ID_STRING as this run. -If no such virtual memory file exists, then Medley will start from the standard full.sysout -(equivalent to specifying the \-\-full flag). +If no such virtual memory file exists, then Medley will start from the standard full.sysout +(equivalent to specifying the \-\-full flag). On Windows (Docker) installations, *SYSOUT_FILE* is +specified in the Medley file system, not the host Windows file system. *PASS_ON_ARGS* : All arguments after the "\-\-" flag, are passed unaltered to lde via run-medley. diff --git a/installers/deb/build_deb.sh b/installers/deb/build_deb.sh index 27096f10..5beb7314 100755 --- a/installers/deb/build_deb.sh +++ b/installers/deb/build_deb.sh @@ -11,6 +11,15 @@ ############################################################################### # set -x +# mess with file desscriptors so we get only one line on stdout +# so we can communicate only what we want back to any githib runner +# stash fd 1 in fd 3 +exec 3>&1 +# make fd 1 (stdout) be the same as stdout +# so none of the std output from this file will be captured by +# $() but it will still be written out to the tty (via stderr) +exec 1>&2 + tarball_dir=tmp/tarballs # Make sure we are in the right directory @@ -60,6 +69,7 @@ fi pushd ${tarball_dir} >/dev/null 2>/dev/null medley_release=$(echo medley-*-loadups.tgz | sed "s/medley-\(.*\)-loadups.tgz/\1/") maiko_release=$(echo maiko-*-linux.x86_64.tgz | sed "s/maiko-\(.*\)-linux.x86_64.tgz/\1/") +debs_filename_base="medley-full-${medley_release}_${maiko_release}" popd >/dev/null 2>/dev/null @@ -120,9 +130,13 @@ do cp -p tmp/vncviewer64-1.12.0.exe ${il_dir}/wsl/vncviewer64-1.12.0.exe fi # + # Make sure all files are owned by root + # + sudo su <<< "chown --recursive root:root ${il_dir}" + # # Create tar file for this arch # - filename="medley-full-${medley_release}_${maiko_release}-${wslp}-${arch}" + filename="${debs_filename_base}-${wslp}-${arch}" mkdir -p tars echo "Creating tar file tars/${filename}.tgz" tar -C ${il_dir} -czf tars/${filename}.tgz . @@ -137,3 +151,8 @@ do done done +# send just one line back to github $() construct +# do this by restoring fd 1 to what it was orginally +exec 1>&3 +echo "${debs_filename_base}" + diff --git a/installers/deb/control-linux b/installers/deb/control-linux index 885c36ef..8fee0cd4 100644 --- a/installers/deb/control-linux +++ b/installers/deb/control-linux @@ -1,9 +1,9 @@ Package: medley-interlisp -Version: 1.0.0 +Version: 1.0.1 Release: --RELEASE-- Maintainer: info@interlisp.org Description: Medley Interlisp for Linux Homepage: https://github.com/interlisp/medley Architecture: --ARCH-- -Depends: xdg-utils +Depends: man-db, xdg-utils diff --git a/installers/downloads_page/medley_downloads.html b/installers/downloads_page/medley_downloads.html index 2dd89cb7..e41529a9 100644 --- a/installers/downloads_page/medley_downloads.html +++ b/installers/downloads_page/medley_downloads.html @@ -2,37 +2,44 @@
  • MEDLEY DOWNLOADS

  • +
  • WINDOWS 10/11 (Medley runs in a Docker container)

    + +

    Release @@@MEDLEY.SHORT.RELEASE.TAG@@@ for Windows x64 machines

  • diff --git a/installers/downloads_page/medley_downloads.md b/installers/downloads_page/medley_downloads.md index fe1420f7..7d251244 100644 --- a/installers/downloads_page/medley_downloads.md +++ b/installers/downloads_page/medley_downloads.md @@ -1,38 +1,42 @@ * # MEDLEY DOWNLOADS - * ## Standard Installations (for Debian-based distros) + * ## LINUX (including Windows System for Linux) - * ### Standard Linux + * ### Standard Installations (for Debian-based distros) - [Release @@@MEDLEY.SHORT.RELEASE.TAG@@@ for x86\_64 machines](https://github.com/Interlisp/medley/releases/download/@@@GITHUB.SUBDIR@@@/@@@FULL.RELEASE.FILENAME@@@-linux-x86\_64.deb) + * #### Standard Linux - [Release @@@MEDLEY.SHORT.RELEASE.TAG@@@ for ARM64 machines](https://github.com/Interlisp/medley/releases/download/@@@GITHUB.SUBDIR@@@/@@@FULL.RELEASE.FILENAME@@@-linux-aarch64.deb) + [Release @@@MEDLEY.SHORT.RELEASE.TAG@@@ for x86\_64 machines](@@@DOWNLOAD_URL@@@/@@@DEBS.FILENAME.BASE@@@-linux-x86\_64.deb) - [Release @@@MEDLEY.SHORT.RELEASE.TAG@@@ for ARMv7 machines](https://github.com/Interlisp/medley/releases/download/@@@GITHUB.SUBDIR@@@/@@@FULL.RELEASE.FILENAME@@@-linux-armv7l.deb) + [Release @@@MEDLEY.SHORT.RELEASE.TAG@@@ for ARM64 machines](@@@DOWNLOAD_URL@@@/@@@DEBS.FILENAME.BASE@@@-linux-aarch64.deb) - * ### Windows System for Linux + [Release @@@MEDLEY.SHORT.RELEASE.TAG@@@ for ARMv7 machines](@@@DOWNLOAD_URL@@@/@@@DEBS.FILENAME.BASE@@@-linux-armv7l.deb) - [Release @@@MEDLEY.SHORT.RELEASE.TAG@@@ for x86\.64 machines](https://github.com/Interlisp/medley/releases/download/@@@GITHUB.SUBDIR@@@/@@@FULL.RELEASE.FILENAME@@@-wsl-x86\_64.deb) + * #### Windows System for Linux - [Release @@@MEDLEY.SHORT.RELEASE.TAG@@@ for ARM64 machines](https://github.com/Interlisp/medley/releases/download/@@@GITHUB.SUBDIR@@@/@@@FULL.RELEASE.FILENAME@@@-wsl-aarch64.deb) + [Release @@@MEDLEY.SHORT.RELEASE.TAG@@@ for x86\.64 machines](@@@DOWNLOAD_URL@@@/@@@DEBS.FILENAME.BASE@@@-wsl-x86\_64.deb) - * ## Local Installations (for any Linux distro) + [Release @@@MEDLEY.SHORT.RELEASE.TAG@@@ for ARM64 machines](@@@DOWNLOAD_URL@@@/@@@DEBS.FILENAME.BASE@@@-wsl-aarch64.deb) - * ### Standard Linux + * ### Local Installations (for any Linux distro) - [Release @@@MEDLEY.SHORT.RELEASE.TAG@@@ for x86\_64 machines](https://github.com/Interlisp/medley/releases/download/@@@GITHUB.SUBDIR@@@/@@@FULL.RELEASE.FILENAME@@@-linux-x86\_64.tgz) + * #### Standard Linux - [Release @@@MEDLEY.SHORT.RELEASE.TAG@@@ for ARM64 machines](https://github.com/Interlisp/medley/releases/download/@@@GITHUB.SUBDIR@@@/@@@FULL.RELEASE.FILENAME@@@-linux-aarch64.tgz) + [Release @@@MEDLEY.SHORT.RELEASE.TAG@@@ for x86\_64 machines](@@@DOWNLOAD_URL@@@/@@@DEBS.FILENAME.BASE@@@-linux-x86\_64.tgz) - [Release @@@MEDLEY.SHORT.RELEASE.TAG@@@ for ARMv7 machines](https://github.com/Interlisp/medley/releases/download/@@@GITHUB.SUBDIR@@@/@@@FULL.RELEASE.FILENAME@@@-linux-armv7l.tgz) + [Release @@@MEDLEY.SHORT.RELEASE.TAG@@@ for ARM64 machines](@@@DOWNLOAD_URL@@@/@@@DEBS.FILENAME.BASE@@@-linux-aarch64.tgz) - * ### Windows System for Linux - - [Release @@@MEDLEY.SHORT.RELEASE.TAG@@@ for x86\_64 machines](https://github.com/Interlisp/medley/releases/download/@@@GITHUB.SUBDIR@@@/@@@FULL.RELEASE.FILENAME@@@-wsl-x86\_64.tgz) - - [Release @@@MEDLEY.SHORT.RELEASE.TAG@@@ for ARM64 machines](https://github.com/Interlisp/medley/releases/download/@@@GITHUB.SUBDIR@@@/@@@FULL.RELEASE.FILENAME@@@-wsl-aarch64.tgz) + [Release @@@MEDLEY.SHORT.RELEASE.TAG@@@ for ARMv7 machines](@@@DOWNLOAD_URL@@@/@@@DEBS.FILENAME.BASE@@@-linux-armv7l.tgz) + * #### Windows System for Linux + [Release @@@MEDLEY.SHORT.RELEASE.TAG@@@ for x86\_64 machines](@@@DOWNLOAD_URL@@@/@@@DEBS.FILENAME.BASE@@@-wsl-x86\_64.tgz) + + [Release @@@MEDLEY.SHORT.RELEASE.TAG@@@ for ARM64 machines](@@@DOWNLOAD_URL@@@/@@@DEBS.FILENAME.BASE@@@-wsl-aarch64.tgz) + + * ## WINDOWS 10/11 (Medley runs in a Docker container) + + [Release @@@MEDLEY.SHORT.RELEASE.TAG@@@ for Windows x64 machines](@@@DOWNLOAD_URL@@@/@@@WINDOWS.INSTALLER.FILENAME@@@) diff --git a/installers/win/.gitignore b/installers/win/.gitignore new file mode 100644 index 00000000..7c4c3101 --- /dev/null +++ b/installers/win/.gitignore @@ -0,0 +1,3 @@ +medley-install_*.exe +vncviewer*.exe + diff --git a/installers/win/Medley.ico b/installers/win/Medley.ico new file mode 100644 index 00000000..6f0f1972 Binary files /dev/null and b/installers/win/Medley.ico differ diff --git a/installers/win/editpath/EditPath.iss b/installers/win/editpath/EditPath.iss new file mode 100644 index 00000000..0312dcaa --- /dev/null +++ b/installers/win/editpath/EditPath.iss @@ -0,0 +1,165 @@ +; Copyright (C) 2021-2023 by Bill Stewart (bstewart at iname.com) +; +; This program is free software; you can redistribute it and/or modify it under +; the terms of the GNU Lesser General Public License as published by the Free +; Software Foundation; either version 3 of the License, or (at your option) any +; later version. +; +; This program is distributed in the hope that it will be useful, but WITHOUT +; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +; FOR A PARTICULAR PURPOSE. See the GNU General Lesser Public License for more +; details. +; +; You should have received a copy of the GNU Lesser General Public License +; along with this program. If not, see https://www.gnu.org/licenses/. + +; Sample Inno Setup (https://www.jrsoftware.org/isinfo.php) script +; demonstrating use of PathMgr.dll. +; +; This script uses PathMgr.dll in the following ways: +; * Copies PathMgr.dll to the target machine (required for uninstall) +; * Defines a task in [Tasks] that should modify the Path +; * Imports the AddDirToPath() DLL function at setup time +; * Imports the RemoveDirFromPath() DLL function at uninstall time +; * Stores task state as custom setting using RegisterPreviousData() +; * Retrieves task state custom setting during setup and uninstall initialize +; * At post install, adds app dir to Path if task selected +; * At uninstall, removes dir from Path if custom setting present +; * Unloads and deletes DLL and removes app dir at uninstall deinitialize + +#if Ver < EncodeVer(6,0,0,0) + #error This script requires Inno Setup 6 or later +#endif + +[Setup] +AppId={{A17D2D05-C729-4F2A-9CC7-E04906C5A842} +AppName=EditPath +AppVersion=4.0.4.0 +UsePreviousAppDir=false +DefaultDirName={autopf}\EditPath +Uninstallable=true +OutputDir=. +OutputBaseFilename=EditPath_Setup +ArchitecturesInstallIn64BitMode=x64 +PrivilegesRequired=none +PrivilegesRequiredOverridesAllowed=dialog + +[Files] +; Install PathMgr.dll for use with both setup and uninstall; use +; uninsneveruninstall flag because DeinitializeSetup() will delete after +; unloading the DLL; install the 32-bit version of PathMgr.dll because both +; setup and uninstall executables are 32-bit +Source: "i386\PathMgr.dll"; DestDir: "{app}"; Flags: uninsneveruninstall + +; Other files to install on target system +Source: "i386\EditPath.exe"; DestDir: "{app}"; Check: not Is64BitInstallMode() +Source: "x86_64\EditPath.exe"; DestDir: "{app}"; Check: Is64BitInstallMode() +Source: "EditPath.md"; DestDir: "{app}" + +[Tasks] +Name: modifypath; Description: "&Add to Path" + +[Code] +const + MODIFY_PATH_TASK_NAME = 'modifypath'; // Specify name of task + +var + PathIsModified: Boolean; // Cache task selection from previous installs + ApplicationUninstalled: Boolean; // Has application been uninstalled? + +// Import AddDirToPath() at setup time ('files:' prefix) +function DLLAddDirToPath(DirName: string; PathType, AddType: DWORD): DWORD; + external 'AddDirToPath@files:PathMgr.dll stdcall setuponly'; + +// Import RemoveDirFromPath() at uninstall time ('{app}\' prefix) +function DLLRemoveDirFromPath(DirName: string; PathType: DWORD): DWORD; + external 'RemoveDirFromPath@{app}\PathMgr.dll stdcall uninstallonly'; + +// Wrapper for AddDirToPath() DLL function +function AddDirToPath(const DirName: string): DWORD; +var + PathType, AddType: DWORD; +begin + // PathType = 0 - use system Path + // PathType = 1 - use user Path + // AddType = 0 - add to end of Path + // AddType = 1 - add to beginning of Path + if IsAdminInstallMode() then + PathType := 0 + else + PathType := 1; + AddType := 0; + result := DLLAddDirToPath(DirName, PathType, AddType); +end; + +// Wrapper for RemoveDirFromPath() DLL function +function RemoveDirFromPath(const DirName: string): DWORD; +var + PathType: DWORD; +begin + // PathType = 0 - use system Path + // PathType = 1 - use user Path + if IsAdminInstallMode() then + PathType := 0 + else + PathType := 1; + result := DLLRemoveDirFromPath(DirName, PathType); +end; + +procedure RegisterPreviousData(PreviousDataKey: Integer); +begin + // Store previous or current task selection as custom user setting + if PathIsModified or WizardIsTaskSelected(MODIFY_PATH_TASK_NAME) then + SetPreviousData(PreviousDataKey, MODIFY_PATH_TASK_NAME, 'true'); +end; + +function InitializeSetup(): Boolean; +begin + result := true; + // Was task selected during a previous install? + PathIsModified := GetPreviousData(MODIFY_PATH_TASK_NAME, '') = 'true'; +end; + +function InitializeUninstall(): Boolean; +begin + result := true; + // Was task selected during a previous install? + PathIsModified := GetPreviousData(MODIFY_PATH_TASK_NAME, '') = 'true'; + ApplicationUninstalled := false; +end; + +procedure CurStepChanged(CurStep: TSetupStep); +begin + if CurStep = ssPostInstall then + begin + // Add app directory to Path at post-install step if task selected + if PathIsModified or WizardIsTaskSelected(MODIFY_PATH_TASK_NAME) then + AddDirToPath(ExpandConstant('{app}')); + end; +end; + +procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep); +begin + if CurUninstallStep = usUninstall then + begin + // Remove app directory from path during uninstall if task was selected; + // use variable because we can't use WizardIsTaskSelected() at uninstall + if PathIsModified then + RemoveDirFromPath(ExpandConstant('{app}')); + end + else if CurUninstallStep = usPostUninstall then + begin + ApplicationUninstalled := true; + end; +end; + +procedure DeinitializeUninstall(); +begin + if ApplicationUninstalled then + begin + // Unload and delete PathMgr.dll and remove app dir when uninstalling + UnloadDLL(ExpandConstant('{app}\PathMgr.dll')); + DeleteFile(ExpandConstant('{app}\PathMgr.dll')); + RemoveDir(ExpandConstant('{app}')); + end; +end; diff --git a/installers/win/editpath/EditPath.md b/installers/win/editpath/EditPath.md new file mode 100644 index 00000000..bce1768a --- /dev/null +++ b/installers/win/editpath/EditPath.md @@ -0,0 +1,118 @@ +# EditPath + +EditPath is a Windows console (text-based, command-line) program for managing the system Path and user Path. + +# Author + +Bill Stewart - bstewart at iname dot com + +# License + +EditPath.exe is covered by the GNU Lesser Public License (LPGL). See the file `LICENSE` for details. + +# Download + +https://github.com/Bill-Stewart/PathMgr/releases/ + +# Background + +The system Path is found in the following location in the Windows registry: + +Root: `HKEY_LOCAL_MACHINE` +Subkey: `SYSTEM\CurrentControlSet\Control\Session Manager\Environment` +Value name: `Path` + +The current user Path is found in the following location in the registry: + +Root: `HKEY_CURRENT_USER` +Subkey: `Environment` +Value name: `Path` + +In both cases, the `Path` value is (or should be) the registry type `REG_EXPAND_SZ`, which means that it is a string that can contain values surrounded by `%` characters that Windows will automatically expand to environment variable values. (For example, `%SystemRoot%` will be expanded to `C:\Windows` on most systems.) + +The `Path` value contains a `;`-delimited list of directory names that the system should search for executables, library files, scripts, etc. Windows appends the content of the current user Path to the system Path and expands the environment variable references. The resulting string is set as the `Path` environment variable for processes. + +EditPath provides a command-line interface for managing the `Path` value in the system location (in `HKEY_LOCAL_MACHINE`) and the current user location (in `HKEY_CURRENT_USER`). + +# Usage + +The following describes the command-line usage for the program. Parameters are case-sensitive. + +**EditPath** [_options_] _type_ _action_ + +You must specify only one of the following _type_ parameters: + +| _type_ | Abbreviation | Description +| ------- | ------------ | ----------- +| **--system** | **-s** | Specifies the system Path +| **--user** | **-u** | Specifies the user Path + +You must specify only one of the following _action_ parameters: + +| _action_ | Abbreviation | Description +| -------- | ------------ | ----------- +| **--list** | **-l** | Lists directories in Path +| **--test "**_dirname_**"** | **-t "**_dirname_**"** | Tests if directory exists in Path +| **--add "**_dirname_**"** | **-a "**_dirname_**"** | Adds directory to Path +| **--remove "**_dirname_**"** | **-r "**_dirname_**"** | Removes directory from Path + +The following parameters are optional: + +| _options_ | Abbreviation | Description +| --------- | ------------ | ----------- +| **--quiet** | **-q** | Suppresses result messages +| **--expand** | **-x** | Expands environment variables (**--list** only) +| **--beginning** | **-b** | Adds to beginning of Path (**--add** only) + +# Exit Codes + +The following table lists typical exit codes when not using **--test** (**-t**). + +| Exit Code | Description +| --------- | ----------- +| 0 | No errors +| 2 | The Path value is not present in the registry +| 3 | The specified directory does not exist in the Path +| 5 | Access is denied +| 87 | Incorrect parameter(s) +| 183 | The specified directory already exists in the Path + +The following table lists typical exit codes when using **--test** (**-t**). + +| Exit Code | Description +| --------- | ----------- +| 1 | The specified directory exists in the unexpanded Path +| 2 | The specified directory exists in the expanded Path +| 3 | The specified directory does not exist in the Path + +# Remarks + +* Anything on the command line after **--test**, **--add**, or **--remove** is considered to be the argument for the parameter. To avoid ambiguity, specify the _action_ parameter last on the command line. + +* Uexpanded vs. expanded refers to whether the environment variable references (i.e., names between `%` characters) are expanded after retrieving the Path value from the registry. For example, `%SystemRoot%` is unexpanded but `C:\Windows` is expanded. + +* The **--add** (**-a**) parameter checks whether the specified directory exists in both the unexpanded and expanded copies of the Path before adding the directory. For example, if the environment variable `TESTAPP` is set to `C:\TestApp` and `%TESTAPP%` is in the Path, specifying `--add C:\TestApp` will return exit code 183 (i.e., the directory already exists in the Path) because `%TESTAPP%` expands to `C:\TestApp`. + +* The **--remove** (**-r**) parameter does not expand environment variable references. For example, if the environment variable `TESTAPP` is set to `C:\TestApp` and `%TESTAPP%` is in the Path, specifying `--remove "C:\TestApp"` will return exit code 3 (i.e., the directory does not exist in the Path) because **--remove** does not expand `%TESTAPP%` to `C:\TestApp`. For the command to succeed, you would have to specify `--remove "%TESTAPP%"` instead. + +* The program will exit with error code 87 if a parameter (or an argument to a parameter) is missing or not valid, if mutually exclusive parameters are specified, etc. + +* The program will exit with error code 5 if the current user does not have permission to update the Path value in the registry (for example, if you try to update the system Path using a standard user account or an unelevated administrator account). + +# Examples + +1. `EditPath --expand --system --list` + + This command outputs the directories in the system Path, with environment variables expanded. You can also write this command as `EditPath -x -s -l`. + +2. `EditPath --user --add "%LOCALAPPDATA%\Programs\MyApp"` + + Adds the specified directory name to the user Path. + +3. `EditPath -s -r "C:\Program Files\MyApp\bin"` + + Removes the specified directory from the system Path. + +4. `EditPath -s --test "C:\Program Files (x86)\MyApp\bin"` + + Returns an exit code of 3 if the specified directory is not in the system Path, 1 if the specified directory is in the unexpanded copy of the system Path, or 2 if the specified directory is in the expanded copy of the system Path. diff --git a/installers/win/editpath/README.TXT b/installers/win/editpath/README.TXT new file mode 100644 index 00000000..c922ee30 --- /dev/null +++ b/installers/win/editpath/README.TXT @@ -0,0 +1,3 @@ +Editpath installed here is extracted from Release 1.04 from https://github.com/Bill-Stewart/PathMgr. + + diff --git a/installers/win/editpath/i386/EditPath.exe b/installers/win/editpath/i386/EditPath.exe new file mode 100644 index 00000000..7e9f2837 Binary files /dev/null and b/installers/win/editpath/i386/EditPath.exe differ diff --git a/installers/win/editpath/x86_64/EditPath.exe b/installers/win/editpath/x86_64/EditPath.exe new file mode 100644 index 00000000..6e79f161 Binary files /dev/null and b/installers/win/editpath/x86_64/EditPath.exe differ diff --git a/installers/win/makeflix.iss b/installers/win/makeflix.iss new file mode 100644 index 00000000..d74615b3 --- /dev/null +++ b/installers/win/makeflix.iss @@ -0,0 +1,128 @@ +; -- makeflix.iss -- +; fgh 2016-08-19 + +#define x86_or_x64 "x86" +#define version "1.0.1" + +#if x86_or_x64 == "x86" +#define exe_dir "Win32" +#else +#define exe_dir "x64" +#endif + +[Setup] +ArchitecturesAllowed={#x86_or_x64} +AppName=Makeflix +AppVersion={#version} +AppPublisher=Lellan, Inc. +AppPublisherURL=http://www.lellan.com/ +AppCopyright=Copyright (C) 2012-2017 Lellan, Inc. +DefaultDirName={pf}\Lellan\Makeflix +DefaultGroupName=Lellan +UninstallDisplayIcon={app}\makeflix.exe +Compression=lzma2 +SolidCompression=yes +; "ArchitecturesInstallIn64BitMode=x64" requests that the install be +; done in "64-bit mode" on x64, meaning it should use the native +; 64-bit Program Files directory and the 64-bit view of the registry. +ArchitecturesInstallIn64BitMode=x64 +; Source Dir is lellan/toolchain/makeflix/windows +SourceDir="..\" +OutputDir="deploy" +OutputBaseFilename="makeflix_v{#version}_{#x86_or_x64}" +SetupIconFile="..\images\Lellan_Logo_20130221.ico" +LicenseFile="..\deploy\EULA.rtf" +DisableWelcomePage=no + +[Files] +Source: "makeflix\{#exe_dir}\Release\makeflix.exe"; DestDir: "{app}"; DestName: "makeflix.exe"; Flags: ignoreversion +Source: "deploy\DLLs\{#x86_or_x64}\Qt5Core.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "deploy\DLLs\{#x86_or_x64}\Qt5Gui.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "deploy\DLLs\{#x86_or_x64}\Qt5Widgets.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "deploy\DLLs\{#x86_or_x64}\Qt5Network.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "deploy\DLLs\{#x86_or_x64}\platforms\qwindows.dll"; DestDir: "{app}\platforms"; Flags: ignoreversion +Source: "deploy\gstreamer\{#x86_or_x64}\*"; DestDir: "{app}\gstreamer"; Flags: recursesubdirs ignoreversion +Source: "deploy\vc_redist\vc_redist.{#x86_or_x64}.exe"; DestDir: "{tmp}"; Flags: deleteafterinstall +Source: "deploy\bonjour\Bonjour.{#x86_or_x64}.msi"; DestDir: "{tmp}" ; Flags: deleteafterinstall + +Source: "..\deploy\Makeflix_Open_Source_Libraries.pdf"; DestDir: "{app}" + +[Icons] +Name: "{group}\Makeflix"; Filename: "{app}\makeflix.exe" +Name: "{group}\Uninstall Makeflix"; Filename: "{uninstallexe}" + + +[Run] +#define VCmsg "Installing Microsoft Visual C++ Redistributable ..." +Filename: "{tmp}\vc_redist{#x86_or_x64}.exe"; StatusMsg: "{#VCmsg}"; Check: not VCinstalled +#define BonjourMsg "Installing Apple Bonjour support ..." +Filename: "msiexec"; Parameters: "/i {tmp}\Bonjour.{#x86_or_x64}.msi"; StatusMsg: "{#BonjourMsg}"; Check: not BonjourInstalled + +[Registry] +Root: HKLM; Subkey: "SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\makeflix.exe"; ValueType: string; ValueName: "(Default)"; ValueData: "{app}\makeflix.exe"; Flags: uninsdeletekey +Root: HKLM; Subkey: "SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\makeflix.exe"; ValueType: string; ValueName: "Path"; ValueData: "{app}\gstreamer\bin"; Flags: uninsdeletekey + +[Code] +function VCinstalled: Boolean; + // By Michael Weiner + // Function for Inno Setup Compiler + // 13 November 2015 + // Modified by Frank G Halasz to handle WOW case + // 23 August 2016 + // Returns True if Microsoft Visual C++ Redistributable is installed, otherwise False. + // The programmer may set the year of redistributable to find; see below. + var + names: TArrayOfString; + i: Integer; + dName, key, year, platfm: String; + begin + // Year of redistributable to find; leave null to find installation for any year. + year := '2015'; + Result := False; + if Is64BitInstallMode then + begin + platfm := 'x64'; + key := 'Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall'; + end + else if not IsWin64 then + begin + platfm := 'x86'; + key := 'Software\Microsoft\Windows\CurrentVersion\Uninstall'; + end + else + begin + platfm := 'x86'; + key := 'Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall'; + end; + // Get an array of all of the uninstall subkey names. + if RegGetSubkeyNames(HKEY_LOCAL_MACHINE, key, names) then + // Uninstall subkey names were found. + begin + i := 0 + while ((i < GetArrayLength(names)) and (Result = False)) do + // The loop will end as soon as one instance of a Visual C++ redistributable is found. + begin + // For each uninstall subkey, look for a DisplayName value. + // If not found, then the subkey name will be used instead. + if not RegQueryStringValue(HKEY_LOCAL_MACHINE, key + '\' + names[i], 'DisplayName', dName) then + dName := names[i]; + // See if the value contains both of the strings below. + Result := (Pos(Trim('Visual C++ ' + year),dName) * Pos('Redistributable',dName) * Pos(platfm, dName) <> 0) + i := i + 1; + end; + end; + end; + + function BonjourInstalled: Boolean; + // Returns True if Apple Bonjour is installed, otherwise False. + // Ignores date/version of Bonjour. + begin + Result := False; + // If this key exists, then + // bonjour services must already be installed + if RegKeyExists(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Services\Bonjour Service') then + // Uninstall subkey names were found. + begin + Result := True; + end; + end; diff --git a/installers/win/medley.iss b/installers/win/medley.iss new file mode 100644 index 00000000..8e6ade8f --- /dev/null +++ b/installers/win/medley.iss @@ -0,0 +1,65 @@ +;############################################################################### +;# +;# medley.iss - Inno Setup compiler script for creating a Windows +;# installer for the medley.ps1 powrshell script for +;# running Medley within a docker container on Windows +;# +;# 2023-02-12 Frank Halasz +;# +;# Copyright 2023 Interlisp.org +;# +;############################################################################### + +#define x86_or_x64 "x64" +#if GetEnv('COMBINED_RELEASE_TAG') != "" +#define VERSION=GetEnv('COMBINED_RELEASE_TAG') +#else +#define VERSION="local" +#endif + +[Setup] +PrivilegesRequired=lowest +ArchitecturesAllowed={#x86_or_x64} +AppName=Medley +AppVersion={#version} +AppPublisher=Interlisp.org +AppPublisherURL=https://interlisp.org/ +AppCopyright=Copyright (C) 2023 Interlisp.org +DefaultDirName={localappdata}\Medley\Scripts +DefaultGroupName=Medley +Compression=lzma2 +SolidCompression=yes +; "ArchitecturesInstallIn64BitMode=x64" requests that the install be +; done in "64-bit mode" on x64, meaning it should use the native +; 64-bit Program Files directory and the 64-bit view of the registry. +ArchitecturesInstallIn64BitMode=x64 +OutputDir="." +OutputBaseFilename="medley-install_{#version}_{#x86_or_x64}" +SetupIconFile="Medley.ico" +DisableWelcomePage=no +MissingRunOnceIdsWarning=no +DisableProgramGroupPage=yes +WizardImageFile=medley_logo.bmp +WizardSmallImageFile=medley_logo_small.bmp +WizardImageStretch=no +UninstallDisplayIcon="{app}\Medley.ico" + + + +[Files] +Source: "..\..\scripts\medley\medley.ps1"; DestDir: "{app}"; DestName: "medley.ps1"; Flags: ignoreversion +Source: "..\..\scripts\medley\medley.cmd"; DestDir: "{app}"; DestName: "medley.cmd"; Flags: ignoreversion +Source: "editpath\x86_64\EditPath.exe"; DestDir: "{app}"; DestName: "EditPath.exe"; Flags: ignoreversion +Source: "Medley.ico"; DestDir: "{app}"; DestName: "Medley.ico"; Flags: ignoreversion +Source: "vncviewer64-1.12.0.exe"; DestDir: "{app}"; DestName: "vncviewer64-1.12.0.exe"; Flags: ignoreversion +[Icons] +Name: "{group}\Medley\Uninstall_Medley"; Filename: "{uninstallexe}" +Name: "{group}\Medley\Medley"; Filename: "powershell"; Parameters: "-NoExit -File {app}\medley.ps1 --help"; IconFilename: "{app}\Medley.ico" + + +[Run] +Filename: "{app}\EditPath.exe"; Parameters: "--user --add {app}"; Flags: runhidden + +[UninstallRun] +Filename: "{app}\EditPath.exe"; Parameters: "--user --remove {app}"; Flags: runhidden + diff --git a/installers/win/medley_logo.bmp b/installers/win/medley_logo.bmp new file mode 100644 index 00000000..9efbe3af Binary files /dev/null and b/installers/win/medley_logo.bmp differ diff --git a/installers/win/medley_logo.png b/installers/win/medley_logo.png new file mode 100644 index 00000000..24c466b6 Binary files /dev/null and b/installers/win/medley_logo.png differ diff --git a/installers/win/medley_logo_small.bmp b/installers/win/medley_logo_small.bmp new file mode 100644 index 00000000..643d6ac4 Binary files /dev/null and b/installers/win/medley_logo_small.bmp differ diff --git a/scripts/medley/medley.cmd b/scripts/medley/medley.cmd new file mode 100644 index 00000000..9fdbeef5 --- /dev/null +++ b/scripts/medley/medley.cmd @@ -0,0 +1,3 @@ +@echo off +powershell medley.ps1 %* + diff --git a/scripts/medley/medley.ps1 b/scripts/medley/medley.ps1 new file mode 100755 index 00000000..87021c74 --- /dev/null +++ b/scripts/medley/medley.ps1 @@ -0,0 +1,410 @@ +############################################################################### +# +# 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 +# +############################################################################### + diff --git a/scripts/medley/medley.sh b/scripts/medley/medley.sh index 0fb942e9..e8f54761 100755 --- a/scripts/medley/medley.sh +++ b/scripts/medley/medley.sh @@ -56,13 +56,39 @@ export MEDLEYDIR=$(cd ${SCRIPTDIR}; cd ../..; pwd) IL_DIR=$(cd ${MEDLEYDIR}; cd ..; pwd) export LOGINDIR=${HOME}/il -# Are we running under WSL? -grep --ignore-case --quiet wsl /proc/sys/kernel/osrelease -if [ $? -eq 0 ]; +# Are we running under Docker or if not under WSL? +if [ -n "${MEDLEY_DOCKER_BUILD_DATE}" ]; then - wsl='true' -else + docker='true' wsl='false' +else + docker='false' + wsl_ver=0 + # WSL2 + grep --ignore-case --quiet wsl /proc/sys/kernel/osrelease + if [ $? -eq 0 ]; + then + wsl='true' + wsl_ver=2 + else + # WSL1 + grep --ignore-case --quiet microsoft /proc/sys/kernel/osrelease + if [ $? -eq 0 ]; + then + if [ $(uname -m) = x86_64 ]; + then + wsl='true' + wsl_ver=1 + else + echo "ERROR: Running Medley on WSL1 requires an x86_64-based PC." + echo "This is not an x86_64-based PC." + echo "Exiting" + exit 23 + fi + else + wsl='false' + fi + fi fi # process args @@ -79,7 +105,7 @@ then exit 3 fi -# Set the LDEDESTSYSOUT env variable based on id +# Set LDEDESTSYSOUT env variable based on id if [ -z ${LDEDESTSYSOUT} ]; then if [ "${run_id}" = "default" ]; @@ -104,12 +130,12 @@ fi mkdir -p ${LOGINDIR}/vmem # Call run-medley with or without vnc -if [[ ${wsl} = false || ${use_vnc} = false ]]; +if [[ ( ${wsl} = false || ${use_vnc} = false ) && ${docker} = false ]]; then # If not using vnc, just call run-medley - ${MEDLEYDIR}/run-medley -id "${run_id}" ${geometry} ${screensize} "${run_args[@]}" + ${MEDLEYDIR}/run-medley -id "${run_id}" ${geometry} ${screensize} ${run_args[@]} else - # do the vnc thing on wsl + # do the vnc thing on wsl or docker source ${SCRIPTDIR}/medley_vnc.sh fi diff --git a/scripts/medley/medley_args.sh b/scripts/medley/medley_args.sh old mode 100644 new mode 100755 index 10a05d5c..7275d0db --- a/scripts/medley/medley_args.sh +++ b/scripts/medley/medley_args.sh @@ -14,27 +14,53 @@ # load usage function source ${SCRIPTDIR}/medley_usage.sh -# Process args +# Defaults +apps_flag=false +err_msg="" +full_flag=false +geometry="" +greet_specified=false +lisp_flag=false +noscroll=false +pass_args=false run_args=() run_id="default" -use_vnc='false' -geometry="" screensize="" -noscroll='false' -pass_args=false -lisp_flag=false -full_flag=false -apps_flag=false sysout_flag=false sysout_arg="" -err_msg="" -greet_specified='false' +use_vnc=false +windows=false +# Loop thru args and process while [ "$#" -ne 0 ]; do if [ ${pass_args} = false ]; then case "$1" in + -a | --apps) + sysout_arg="apps" + apps_flag=true + ;; + -d | --display) + check_for_dash_or_end "$1" "$2" + run_args+=(-d $2) + shift + ;; + -e | --interlisp) + export MEDLEY_EXEC="inter" + ;; + -f | --full) + sysout_arg="-full" + full_flag=true + ;; + -g | --geometry) + check_for_dash_or_end "$1" "$2" + geometry="$2" + shift + ;; + -h | --help) + usage + ;; -i | --id) if [ "$2" = "-" ]; then @@ -48,6 +74,47 @@ do fi shift ;; + -k | --vmem) + check_for_dash_or_end "$1" "$2" + check_file_writeable_or_creatable "$1" "$2" + export LDEDESTSYSOUT="$2" + shift + ;; + -l | --lisp) + sysout_arg="-lisp" + lisp_flag=true + ;; + -m | --mem) + check_for_dash_or_end "$1" "$2" + run_args+=(-m $2) + shift + ;; + -n | --noscroll) + noscroll=true + run_args+=("-noscroll") + ;; + -r | --greet) + if [[ "$2" = "-" || "$2" = "--" ]]; + then + run_args+=("--nogreet") + else + check_for_dash_or_end "$1" "$2" + check_file_readable "$1" "$2" + run_args+=("-greet" "$2") + fi + greet_specified='true' + shift + ;; + -s | --screensize) + check_for_dash_or_end "$1" "$2" + screensize="$2" + shift + ;; + -t | --title) + check_for_dash_or_end "$1" "$2" + run_args+=(-title $2) + shift + ;; -v | --vnc) if [[ ${wsl} = true && $(uname -m) = x86_64 ]]; then @@ -60,68 +127,6 @@ do use_vnc=false fi ;; - -g | --geometry) - check_for_dash_or_end "$1" "$2" - geometry="$2" - shift - ;; - -s | --screensize) - check_for_dash_or_end "$1" "$2" - screensize="$2" - shift - ;; - -n | --noscroll) - noscroll=true - run_args+=("-noscroll") - ;; - -e | --interlisp) - export MEDLEY_EXEC="inter" - ;; - -a | --apps) - sysout_arg="apps" - apps_flag=true - ;; - -f | --full) - sysout_arg="-full" - full_flag=true - ;; - -l | --lisp) - sysout_arg="-lisp" - lisp_flag=true - ;; - -m | --mem) - check_for_dash_or_end "$1" "$2" - run_args+=(-m $2) - shift - ;; - -t | --title) - check_for_dash_or_end "$1" "$2" - run_args+=(-title $2) - shift - ;; - -d | --display) - check_for_dash_or_end "$1" "$2" - run_args+=(-d $2) - shift - ;; - -r | --greet) - if [[ "$2" = "-" || "$2" = "--" ]]; - then - run_args+=("--nogreet") - else - check_for_dash_or_end "$1" "$2" - check_file_readable "$1" "$2" - run_args+=("-greet" "$2") - fi - greet_specified='true' - shift - ;; - -p | --vmem) - check_for_dash_or_end "$1" "$2" - check_file_writeable_or_creatable "$1" "$2" - export LDEDESTSYSOUT="$2" - shift - ;; -x | --logindir) if [[ "$2" = "-" || "$2" = "--" ]]; then @@ -134,13 +139,14 @@ do fi shift ;; - -h | --help) - usage - ;; -z | --man) /usr/bin/man -l "${MEDLEYDIR}/docs/man-page/medley.1.gz" exit 0 ;; + --windows) + # internal: called from Windows medley.ps1 (via docker) + windows=true + ;; --) pass_args=true ;; @@ -190,15 +196,23 @@ then fi if [ "${sysout_arg}" = "apps" ]; then - export LDESRCESYSOUT="$MEDLEYDIR/loadups/apps.sysout" + export LDESRCESYSOUT="${MEDLEYDIR}/loadups/apps.sysout" if [ "${greet_specified}" = "false" ]; then - export LDEINIT="$MEDLEYDIR/greetfiles/APPS-INIT.LCOM" + export LDEINIT="${MEDLEYDIR}/greetfiles/APPS-INIT.LCOM" fi else # pass on to run-medley - export LDESRCESYSOUT="" - run_args+=("${sysout_arg}") + unset LDESRCESYSOUT + if [ -n "${sysout_arg}" ]; + then + run_args+=("${sysout_arg}") + fi fi +# if running on WSL1, force use_vnc +if [[ ${wsl} = true && ${wsl_ver} -eq 1 ]]; +then + use_vnc=true +fi diff --git a/scripts/medley/medley_usage.sh b/scripts/medley/medley_usage.sh index 00ccb0b8..a0397b84 100644 --- a/scripts/medley/medley_usage.sh +++ b/scripts/medley/medley_usage.sh @@ -17,6 +17,34 @@ usage() { local err_msg local msg_path=/tmp/msg-$$ local lines=("$@") + + if [ ${wsl} = true ]; + then + wsl_incl="+w" + wsl_excl="-w" + else + wsl_incl="-w" + wsl_excl="+w" + fi + + if [ ${docker} = true ]; + then + docker_incl="+d" + docker_excl="-d" + else + docker_incl="-d" + docker_excl="+d" + fi + + if [ ${windows} = true ]; + then + windows_incl="+W" + windows_excl="-W" + else + windows_incl="-W" + windows_excl="+W" + fi + if [ $# -ne 0 ]; then echo > ${msg_path} @@ -26,7 +54,12 @@ usage() { else touch ${msg_path} fi - cat ${msg_path} - </dev/null + if [ $? -eq 1 ]; + then + result=${ctr} + break + else + (( ctr++ )) + fi fi done echo ${result} @@ -40,8 +48,13 @@ local result=-1 while [ ${ctr} -lt 6000 ]; do - ss -a | grep -q "LISTEN.*:${ctr}[^0-9]" - if [ $? -ne 0 ]; + if [[ ${wsl} = true && ${wsl_ver} -eq 1 ]]; + then + netstat.exe -a -n | awk '{ print $2 }' | grep -q ":${ctr}\$" + else + ss -a | grep -q "LISTEN.*:${ctr}[^0-9]" + fi + if [ $? -eq 1 ]; then result=${ctr} break @@ -53,102 +66,185 @@ } # - # Make sure prequisites for vnc support are in place + # Make sure prequisites for vnc support in wsl are in place # - win_userprofile="$(cmd.exe /c "/dev/null)" - vnc_dir="$(wslpath ${win_userprofile})/AppData/Local/Interlisp" - vnc_exe="vncviewer64-1.12.0.exe" - if [[ $(which Xvnc) = "" || $(Xvnc -version |& grep -iq tigervnc; echo $?) -eq 1 ]]; + if [ "${use_vnc}" = "true" ]; then - echo "Error: The -v or --vnc flag was set." - echo "But it appears that that TigerVNC \(Xvnc\) has not been installed." - echo "Please install TigerVNC using \"sudo apt install tigervnc-standalone-server tigervnc-xorg-extension\"" - echo "Exiting." - exit 4 - elif [ ! -e "${vnc_dir}/${vnc_exe}" ]; - then - if [ -e "${IL_DIR}/wsl/${vnc_exe}" ]; + win_userprofile="$(cmd.exe /c "/dev/null)" + vnc_dir="$(wslpath ${win_userprofile})/AppData/Local/Interlisp" + vnc_exe="vncviewer64-1.12.0.exe" + if [[ $(which Xvnc) = "" || $(Xvnc -version |& grep -iq tigervnc; echo $?) -eq 1 ]]; then - # make sure TigerVNC viewer is in a Windows (not Linux) directory. If its in a Linux directory - # there will be a long delay when it starts up - mkdir -p ${vnc_dir} - cp -p "${IL_DIR}/wsl/${vnc_exe}" "${vnc_dir}/${vnc_exe}" - else - echo "TigerVnc viewer is required by the -vnc option but is not installed." - echo -n "Ok to download from SourceForge? [y, Y, n or N, default n] " - read resp - if [ -z ${resp} ]; then resp=n; else resp=${resp:0:1}; fi - if [[ ${resp} = 'n' || ${resp} = 'N' ]]; + echo "Error: The -v or --vnc flag was set." + echo "But it appears that that TigerVNC \(Xvnc\) has not been installed." + echo "Please install TigerVNC using \"sudo apt install tigervnc-standalone-server tigervnc-xorg-extension\"" + echo "Exiting." + exit 4 + elif [ ! -e "${vnc_dir}/${vnc_exe}" ]; + then + if [ -e "${IL_DIR}/wsl/${vnc_exe}" ]; then - echo "Ok. You can download the Tiger VNC viewer \(v1.12.0\) .exe yourself and " - echo "place it in ${vnc_dir}/${vnc_exe}. Then retry." - echo "Exiting." - exit 5 + # make sure TigerVNC viewer is in a Windows (not Linux) directory. If its in a Linux directory + # there will be a long delay when it starts up + mkdir -p ${vnc_dir} + cp -p "${IL_DIR}/wsl/${vnc_exe}" "${vnc_dir}/${vnc_exe}" else - pushd "${vnc_dir}" >/dev/null - wget https://sourceforge.net/projects/tigervnc/files/stable/1.12.0/vncviewer64-1.12.0.exe - popd >/dev/null + echo "TigerVnc viewer is required by the -vnc option but is not installed." + echo -n "Ok to download from SourceForge? [y, Y, n or N, default n] " + read resp + if [ -z ${resp} ]; then resp=n; else resp=${resp:0:1}; fi + if [[ ${resp} = 'n' || ${resp} = 'N' ]]; + then + echo "Ok. You can download the Tiger VNC viewer \(v1.12.0\) .exe yourself and " + echo "place it in ${vnc_dir}/${vnc_exe}. Then retry." + echo "Exiting." + exit 5 + else + pushd "${vnc_dir}" >/dev/null + wget https://sourceforge.net/projects/tigervnc/files/stable/1.12.0/vncviewer64-1.12.0.exe + popd >/dev/null + fi fi fi fi - # - # Find an unused display, start Xvnc, run-medley, then start the vnc viewer on the windows side + # Start the log file so we can trace any issues with vnc, etc # - #set -x LOG=${LOGINDIR}/logs/medley_${run_id}.log mkdir -p $(dirname -- ${LOG}) echo "START" >${LOG} - OPEN_DISPLAY=`find_open_display` - if [ ${OPEN_DISPLAY} -eq -1 ]; + # + # If we're running under docker: + # set the VNC_PORT to the value of the --port flag (or its default value) + # set DISPLAY to :0 + # + #set -x + if [ "${docker}" = "true" ]; then - echo "Error: cannot find an unused DISPLAY between 1 and 63" - echo "Exiting" - exit 33 + export VNC_PORT=5900 + export DISPLAY=:0 else - echo "Using DISPLAY=${OPEN_DISPLAY}" + # are we running in background - used for pretty-fying the echos + case $(ps -o stat= -p $$) in + *+*) bg=false ;; + *) bg=true ;; + esac + # For not docker (i.e., for wsl/vnc) + # find an unused display and an available port + # + #set -x + OPEN_DISPLAY=`find_open_display` + if [ ${OPEN_DISPLAY} -eq -1 ]; + then + echo "Error: cannot find an unused DISPLAY between 1 and 63" + echo "Exiting" + exit 33 + else + if [ ${bg} = true ]; then echo; fi + echo "Using DISPLAY=:${OPEN_DISPLAY}" + fi + export DISPLAY=":${OPEN_DISPLAY}" + export VNC_PORT=`find_open_port` + if [ ${VNC_PORT} -eq -1 ]; + then + echo "Error: cannot find an unused port between 5900 and 5999" + echo "Exiting" + exit 33 + else + echo "Using VNC_PORT=${VNC_PORT}" + fi fi - VNC_PORT=`find_open_port` - if [ ${VNC_PORT} -eq -1 ]; - then - echo "Error: cannot find an unused port between 5900 and 5999" - echo "Exiting" - exit 33 - else - echo "Using VNC_PORT=${VNC_PORT}" - fi - export DISPLAY=":${OPEN_DISPLAY}" - # start vnc + # + # Start the Xvnc server + # mkdir -p ${LOGINDIR}/logs - /usr/bin/Xvnc ":${OPEN_DISPLAY}" \ + /usr/bin/Xvnc "${DISPLAY}" \ -rfbport ${VNC_PORT} \ -geometry "${geometry#-g }" \ -SecurityTypes None \ -NeverShared \ -DisconnectClients=0 \ + --MaxDisconnectionTime=10 \ >> ${LOG} 2>&1 & - xvnc_pid="" - while [ -z ${xvnc_pid} ]; - do - sleep .25 - xvnc_pid=$(ps h -C Xvnc -o pid,command | grep "Xvnc :${OPEN_DISPLAY}" | awk '{print $1}') - done - echo "XVNC_PID is ${xvnc_pid}" - # run Medley - ( ${MEDLEYDIR}/run-medley -id "${run_id}" ${geometry} ${screensize} "${run_args[@]}" 2>>${LOG} \ - ; \ - kill -9 ${xvnc_pid} ${xvnc_pid} >>${LOG} 2>&1 - ) & - # Give medley time to startup - sleep 2 - # Start vnc viewer on Windows side - pushd ${vnc_dir} >/dev/null - ( ./${vnc_exe} -geometry "+50+50" \ - -ReconnectOnError=off \ - −AlertOnFatalError=off \ - $(ip_addr):${VNC_PORT} \ - >>${LOG} 2>&1 \ - ; \ - kill -9 ${xvnc_pid} >>${LOG} 2>&1 \ - ) & - popd >/dev/null + + # Leaving pid wait for all but docker, + # which seems to need it. For all others + # it seems like its not needed but we'll have + # to see how it runs on slower/faster machines + # FGH 2023-02-16 + if [ ${docker} = true ]; + then + xvnc_pid="" + end_time=$(expr $(date +%s) + 10) + while [ -z "${xvnc_pid}" ]; + do + if [ $(date +%s) -gt $end_time ]; + then + echo "Xvnc server failed to start." + echo "See log file at ${LOG}" + echo "Exiting" + exit 3 + fi + sleep .125 + xvnc_pid=$(pgrep -f "Xvnc ${DISPLAY}") + done + # echo "XVNC_PID is ${xvnc_pid}" + fi + # + # Run Medley in foreground if docker, else in background + # + tmp_dir=$(if [[ -d /run/shm && ! -h /run/shm ]]; then echo "/run/shm"; else echo "/tmp"; fi) + medley_run=$(mktemp --tmpdir=${tmp_dir} medley-XXXXX) + cat > ${medley_run} <<..EOF + #!/bin/bash + ${MEDLEYDIR}/run-medley -id '${run_id}' ${geometry} ${screensize} ${run_args[@]} \ + 2>&1 | tee -a ${LOG} | grep -v "broken (explicit kill" + if [ -n "\$(pgrep -f "${vnc_exe}.*:${VNC_PORT}")" ]; then vncconfig -disconnect; fi +..EOF + #cat ${medley_run} + chmod +x ${medley_run} + if [ "${docker}" = "true" ]; + then + ${medley_run}; rm ${medley_run} + else + (${medley_run}; rm ${medley_run}) & + # + # If not docker (i.e., if wsl/vnc), start the vncviewer on the windows side + # + + # First give medley time to startup + # sleep .25 + # SLeep appears not to be needed, but faster/slower machines ???? + # FGH 2023-02-08 + + # Then start vnc viewer on Windows side + start_time=$(date +%s) + ${vnc_dir}/${vnc_exe} \ + -geometry "+50+50" \ + -ReconnectOnError=off \ + −AlertOnFatalError=off \ + $(ip_addr):${VNC_PORT} \ + >>${LOG} 2>&1 & + wait $! + if [ $( expr $(date +%s) - ${start_time} ) -lt 5 ]; + then + if [ -z "$(pgrep -f "Xvnc ${DISPLAY}")" ]; + then + echo "Xvnc server failed to start." + echo "See log file at ${LOG}" + echo "Exiting" + exit 3 + else + echo "VNC viewer failed to start."; + echo "See log file at ${LOG}"; + echo "Exiting" ; + exit 4; + fi + fi + fi + # + # Done, "Go back" to medley.sh + # + true + +#######################################