diff --git a/.github/workflows/build-uinput.yml b/.github/workflows/build-uinput.yml index b86d418..61f0787 100644 --- a/.github/workflows/build-uinput.yml +++ b/.github/workflows/build-uinput.yml @@ -23,7 +23,7 @@ jobs: -e UNRAID_VERSION=${{ matrix.unraid_version }} shell: bash run: /opt/scripts/build.sh - + - name: get built kernel version id: kernel-version run: echo "::set-output name=kernel::$(ls ${{ github.workspace }}/packages/uinput/root/lib/modules/)" @@ -41,16 +41,26 @@ jobs: name: uinput-${{ steps.kernel-version.outputs.kernel }}.txz path: ${{ github.workspace }}/output/uinput-${{ steps.kernel-version.outputs.kernel }}.txz - - name: generate checksum + - name: generate checksum (md5) id: checksum run: md5sum ${{ github.workspace }}/output/uinput-${{ steps.kernel-version.outputs.kernel }}.txz > ${{ github.workspace }}/output/uinput-${{ steps.kernel-version.outputs.kernel }}.txz.md5 - - name: Upload checksum for ${{ steps.kernel-version.outputs.kernel }} + - name: Upload checksum for ${{ steps.kernel-version.outputs.kernel }} (md5) uses: actions/upload-artifact@v2 with: name: uinput-${{ steps.kernel-version.outputs.kernel }}.txz.md5 path: ${{ github.workspace }}/output/uinput-${{ steps.kernel-version.outputs.kernel }}.txz.md5 + - name: generate checksum (sha256) + id: checksum + run: sha256sum ${{ github.workspace }}/output/uinput-${{ steps.kernel-version.outputs.kernel }}.txz > ${{ github.workspace }}/output/uinput-${{ steps.kernel-version.outputs.kernel }}.txz.sha256 + + - name: Upload checksum for ${{ steps.kernel-version.outputs.kernel }} (sha256) + uses: actions/upload-artifact@v2 + with: + name: uinput-${{ steps.kernel-version.outputs.kernel }}.txz.sha256 + path: ${{ github.workspace }}/output/uinput-${{ steps.kernel-version.outputs.kernel }}.txz.sha256 + release: needs: docker-build runs-on: ubuntu-latest @@ -62,7 +72,7 @@ jobs: - name: Get current date id: date - run: echo "::set-output name=date::$(date +'%d.%m.%Y')" + run: echo "::set-output name=date::$(date +'%Y.%m.%d')" - uses: ncipollo/release-action@v1 with: diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f219dbe --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +package-dist/ diff --git a/DEVELOPING.md b/DEVELOPING.md new file mode 100644 index 0000000..cc53860 --- /dev/null +++ b/DEVELOPING.md @@ -0,0 +1,42 @@ +# Developer How-To + +## Prerequisites + +unRAID installs plugins from an HTTP server, so in order to install your locally-modified version you'll need some way to serve the files over HTTP. There is no HTTP server included with this distribution, but several popular development environments include an easy way to launch one. + +1. NodeJS. This is the one I use. Just run `npx http-server` in the top level of the plugin repo (the directory that contains this file). This will serve the files at `http://[your ip address]:8080/`. +2. Python (3+). This is untested, but it should work. Run `python -m http.server 8080` and the files will (should) be available at `http://[your ip address]:8080/`. + +## Getting Started + +Open up [`gow.plg`](gow.plg) and change the `gitPkgURL` entity to point to `http://[your ip address]:8080`. Be sure to use the IP address of the system you're doing the dev work on; this may not necessarily be your unRAID server. It should _not_ end with a trailing slash. Also change the `gitReleaseURL` entity to `http://[your ip address]:8080/package-dist`. It should likewise have no trailing slash. + +The majority of the functionality of this plugin is implemented in various "packages" (see the `packages/` directory); this provides a convenient mechanism to break the work down into manageable chunks with a standardized way of installing, uninstalling, reloading after reboot, etc. + +Installing and uninstalling packages is managed by the [`preinstall.sh`](scripts/preinstall.sh), [`install.sh`](scripts/install.sh), and [`uninstall.sh`](scripts/uninstall.sh) scripts. Any time you modify one of these, you'll need to update the MD5 and SHA256 hashes in [`gow.plg`](gow.plg). The SHA256 hash takes precedence if both exist, but the MD5 hash is left in for older versions of unRAID. (TODO: it's possible we don't need these anymore) + +Now it's time to try installing your development version of the plugin. Open a terminal on your unRAID server and uninstall the old version of GoW (if you have one installed), then install the new version: +```sh +$ plugin remove gow.plg +$ plugin install http://[your ip address]:8080/gow.plg +``` + +## How to add a new package + +1. Create a new directory under `packages/`, let's say `packages/new-pkg`. +2. In `packages/new-pkg`, add a file called `root/install/slack-desc`. It's easiest to copy an existing one and modify it. +3. Build any directory structure you like under `root/`. Any files you add will be automatically installed in their corresponding places under `/` when the plugin is installed or reloaded after reboot. +4. If your new package needs to perform any actions on start or stop, add a shell script in `root/boot/config/plugins/gow/scripts/start/new-pkg.sh` or `root/boot/config/plugins/gow/scripts/stop/new-pkg.sh`. `start` corresponds to when the plugin is installed or reloaded after reboot, while `stop` is when the plugin is uninstalled. + +## How to build a package + +Packages are built using the [`utils/fmakepkg.sh`](utils/fmakepkg.sh) script. For the purposes of these steps, we'll assume the name of the package you're building is `your-pkg`. + +1. Make a directory at the top level called `package-dist` to hold packages while you're working on them. +2. `cd` to `packages/your-pkg/root`. +3. Run `../../../utils/fmakepkg.sh ../../../package-dist/your-pkg.txz`. +4. `cd` to `../../../package-dist`. +5. Generate `your-pkg.txz.md5` and `your-pkg.txz.sha256`. +6. Uninstall and reinstall the plugin as above to pick up the new package. + + diff --git a/README.md b/README.md index 6c0bb06..1289179 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ A plugin for running Games on Whales on Unraid ## Important Note This plugin is still a work in progress. While several people have found it -useful, it is still at least theoretically possible it could be issues with it; +useful, it is still at least theoretically possible there could be issues with it; possibly even issues that we don't know how to help you fix. Having said that, it doesn't do anything permanent to your system, so uninstalling the plugin should be a good last-resort solution. @@ -29,3 +29,7 @@ and press `INSTALL` success! plugin: gow.plg installed ``` + +## Developer Notes + +See [DEVELOPING.md](DEVELOPING.md) diff --git a/gow.plg b/gow.plg index 8d8cf77..9341254 100644 --- a/gow.plg +++ b/gow.plg @@ -3,10 +3,14 @@ - + + + + + @@ -20,11 +24,14 @@ launch="&launch;" pluginURL="&pluginURL;" min="6.9.2" - max="6.10.0-rc2" + max="6.10.0" support="https://discord.gg/kRGUDHNHt2" > +### 2022.05.18 +- Add support for unRAID 6.10.0 + ### 2021.12.29 - Add support for pre-release versions of unRAID - Automatically download 32-bit drivers if an NVIDIA card is detected (used for Steam) @@ -61,6 +68,10 @@ export GOW_VERSION="&version;" export GOW_LAUNCH="&launch;" export GOW_GITURL="&gitURL;" export GOW_GITPKGURL="&gitPkgURL;" +export GOW_GITMODRELEASEURL="&gitModReleaseURL;" +export GOW_GITRELEASEURL="&gitReleaseURL;" +export GOW_GITRELEASEBASEURL="&gitReleaseBaseURL;" +export GOW_GOWGITURL="&gowGitUrl;" export GOW_PLUGINURL="&pluginURL;" export GOW_PLUGIN="&plugin;" export GOW_EMHTTP="&emhttp;" @@ -70,22 +81,44 @@ export GOW_PACKAGES="kernel/uinput common/settings-ui nvidia/32-bit-drivers" &gitPkgURL;/scripts/install.sh - 485cce35f36abe521b056457276967f4 + 0fdebb7e626327fb026c819d18057d8af44e26b80ae56e20f68bf93dfee5affb + 2e399109aa6086706502cdbea5648250 + + + + + &gitPkgURL;/scripts/preinstall.sh + e7a129f30184a97ab52dfe6552a0758a7552ae3088f75c34f7eee8df1aee96b9 + 6d35001f8dc6284b39dfee6c753875dd &gitPkgURL;/scripts/uninstall.sh - fbcf2cf99bd6907b41f155639b96b649 + 693c3f9dfa8d71aae4053883566b5ecc061d40afa592e16dcdc6af637ad4cb47 + c59b2a488fbe5946b88415216c12e6d1 + + + + + &gitPkgURL;/scripts/utils.sh + 02eb913cb5e26e3de172a5b0e7ea05325d7c2b603b801cde899dd9a3d72910fe + d385111e4d1ef7b1930942811178b29f - echo "╔════════════════════════════╗" - echo "║ Installing Games on Whales ║" - echo "╚════════════════════════════╝" cd &script_dir; + if ! bash ./preinstall.sh; then + echo "preconditions not met; not installing" + rm -rf &plugin; + exit 1 + fi + if ! bash ./install.sh; then + echo "╔════════════════════════════╗" + echo "║ Installing Games on Whales ║" + echo "╚════════════════════════════╝" echo "error while installing, cleaning up" rm -rf &plugin; exit 1 diff --git a/scripts/install.sh b/scripts/install.sh index bfe03ca..86ee9a2 100644 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -1,11 +1,7 @@ #!/bin/bash source vars.sh - -KV="$(uname -r)" -KERNEL_VER=${KV%%-*} - -PACKAGE_DIR="$GOW_PLUGIN/packages" +source utils.sh KERNEL_PKG_DIR="$PACKAGE_DIR/$KERNEL_VER" COMMON_PKG_DIR="$PACKAGE_DIR/$GOW_VERSION" @@ -17,88 +13,46 @@ for dir in $KERNEL_PKG_DIR $COMMON_PKG_DIR; do done function wait_for_network() { - HOST=8.8.8.8 + local host=8.8.8.8 for i in {1..30}; do - ping -c1 $HOST &>/dev/null && return 0 + ping -c1 $host &>/dev/null && return 0 done return 1 } -function pkg_name() { - PACKAGE_NAME=${1/kernel\//$KERNEL_VER\/} - PACKAGE_NAME=${PACKAGE_NAME/common\//$GOW_VERSION\/} - PACKAGE_NAME=${PACKAGE_NAME/nvidia\//$GOW_VERSION\/} - - echo "$PACKAGE_NAME" -} - -function pkg_file() { - PACKAGE_NAME=$(pkg_name "$1") - - echo "$PACKAGE_DIR/$PACKAGE_NAME.txz" -} - -function pkg_url() { - name=$1 - PACKAGE_NAME=$(pkg_name "$name") - - if [[ $name == kernel/* ]]; then - echo "$GOW_GITPKGURL/kernel-bin/$PACKAGE_NAME.txz" - else - echo "https://github.com/games-on-whales/unraid-plugin/releases/download/$PACKAGE_NAME.txz" - fi -} - -function download_pkg() { - PACKAGE_FILE=$(pkg_file "$1") - PACKAGE_URL=$(pkg_url "$1") - - echo "Downloading $PACKAGE_URL" - - if wget -q -nc --show-progress --progress=bar:force:noscroll -O "$PACKAGE_FILE" "$PACKAGE_URL"; then - if [ "$(md5sum "$PACKAGE_FILE" | cut -d ' ' -f1)" != "$(wget -qO- "$PACKAGE_URL.md5" | cut -d ' ' -f1)" ]; then - echo "ERROR: Checksum mismatch for $PACKAGE_URL" - return 1 - fi - else - echo "ERROR: Unable to download $PACKAGE_URL" - return 1 - fi -} - function ensure_pkg() { - PACKAGE_NAME=$1 - PACKAGE_FILE=$(pkg_file "$PACKAGE_NAME") + local package_name=$1 + local package_file=$(pkg_file "$package_name") # if it doesn't exist, download it - if [ ! -f "$PACKAGE_FILE" ] || [ ! -s "$PACKAGE_FILE" ]; then - rm -f "$PACKAGE_FILE" - if ! download_pkg "$PACKAGE_NAME"; then + if [ ! -f "$package_file" ] || [ ! -s "$package_file" ]; then + rm -f "$package_file" + if ! download_pkg "$package_name"; then return 1 fi fi } function install_pkg() { - PACKAGE_FILE=$(pkg_file "$1") + local package_file=$(pkg_file "$1") - echo "Installing: $PACKAGE_FILE" - /sbin/installpkg "$PACKAGE_FILE" + echo "Installing: $package_file" + /sbin/installpkg "$package_file" } function start_pkg() { # strip everything before the first slash. start/stop scripts are versioned # with the plugin, so they don't need the version in their filename. - NAME=${1#*/} + local name=${1#*/} - echo "attempting to start $NAME" + echo "attempting to start $name" - START_SCRIPT="$GOW_PLUGIN/scripts/start/$NAME.sh" + local start_script="$GOW_PLUGIN/scripts/start/$name.sh" - if [ -f "$START_SCRIPT" ]; then - echo "executing $START_SCRIPT" - bash "$START_SCRIPT" + if [ -f "$start_script" ]; then + echo "executing $start_script" + bash "$start_script" fi } diff --git a/scripts/preinstall.sh b/scripts/preinstall.sh new file mode 100644 index 0000000..cf304d2 --- /dev/null +++ b/scripts/preinstall.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +source vars.sh + +# What kind of GPUs do we have? +has_nvidia=false +has_non_nvidia=false + +if command -v lshw >/dev/null 2>&1; then + while read line; do + if [[ ${line,,} =~ nvidia ]]; then + has_nvidia=true + else + has_non_nvidia=true + fi + done < <(lshw -C display 2>/dev/null | grep vendor) +fi + +if [[ "$has_nvidia" = "true" && ! -f /boot/config/plugins/nvidia-driver.plg ]]; then + if [ "$has_non_nvidia" = "true" ]; then + # This user has both NVIDIA and non-NVIDIA cards, so don't prevent + # installation, but provide a warning. + echo "╔══════════╗" + echo "║ WARNING! ║" + echo "╚══════════╝" + echo "Using Games on Whales with an NVIDIA GPU requires the Nvidia-Driver plugin, but you don't have it installed. If you want to use your NVIDIA GPU, please install Nvidia-Driver from Community Applications." + else + # This user only has NVIDIA GPUs, so it's an error to install GoW without the Nvidia-Driver plugin. + echo "╔════════╗" + echo "║ ERROR! ║" + echo "╚════════╝" + echo "Games on Whales requires the Nvidia-Driver plugin. Please install it from Community Applications and try again." + exit 1 + fi +fi diff --git a/scripts/uninstall.sh b/scripts/uninstall.sh index c57a0df..08d676e 100644 --- a/scripts/uninstall.sh +++ b/scripts/uninstall.sh @@ -1,47 +1,33 @@ #1/bin/bash source vars.sh - -KV="$(uname -r)" -KERNEL_VER=${KV%%-*} - -PACKAGE_DIR="$GOW_PLUGIN/packages" - -function pkg_name() { - PACKAGE_NAME=${1/kernel\//$KERNEL_VER\/} - PACKAGE_NAME=${PACKAGE_NAME/common\//$GOW_VERSION\/} - PACKAGE_NAME=${PACKAGE_NAME/nvidia\//$GOW_VERSION\/} - - echo "$PACKAGE_NAME" -} - -function pkg_file() { - PACKAGE_NAME=$(pkg_name "$1") - - echo "$PACKAGE_DIR/$PACKAGE_NAME.txz" -} +source utils.sh function stop_pkg() { # strip everything before the first slash. start/stop scripts are versioned # with the plugin, so they don't need the version in their filename. - NAME=${1#*/} + local name=${1#*/} - STOP_SCRIPT="$GOW_PLUGIN/scripts/stop/$NAME.sh" + local stop_script="$GOW_PLUGIN/scripts/stop/$name.sh" - if [ -f "$STOP_SCRIPT" ]; then - bash "$STOP_SCRIPT" + if [ -f "$stop_script" ]; then + bash "$stop_script" fi } -for pkg in $GOW_PACKAGES; do - PKG_NAME=$(pkg_name "$pkg") - PKG_FILE=$(pkg_file "$pkg") +function main() { + for pkg in $GOW_PACKAGES; do + local package_name=$(pkg_name "$pkg") + local package_file=$(pkg_file "$pkg") - stop_pkg "$pkg" + stop_pkg "$pkg" - if [ -f "$PKG_FILE" ]; then - /sbin/removepkg "$PKG_FILE" 2>/dev/null - fi -done + if [ -f "$package_file" ]; then + /sbin/removepkg "$package_file" 2>/dev/null + fi + done +} + +main exit 0 diff --git a/scripts/utils.sh b/scripts/utils.sh new file mode 100644 index 0000000..c936170 --- /dev/null +++ b/scripts/utils.sh @@ -0,0 +1,80 @@ +export KERNEL_VER="$(uname -r)" +export PACKAGE_DIR="$GOW_PLUGIN/packages" + +function pkg_name() { + local package_name=$1 + if [[ $package_name == kernel/* ]]; then + # strip the namespace + package_name=${package_name/kernel\//} + # add the kernel version + package_name="$package_name-$KERNEL_VER" + else + # remove namespace names for everything else. since bash regexes don't + # support lookbehind, it's easiest to just list the (currently 2) known + # namespaces. + package_name=${package_name/common\//} + package_name=${package_name/nvidia\//} + fi + + echo "$package_name" +} + +# TODO: need to get the version in here somewhere for non-kernel packages +function pkg_file() { + local package_name=$(pkg_name "$1") + + echo "$PACKAGE_DIR/$package_name.txz" +} + +function pkg_url() { + local name=$1 + local package_name=$(pkg_name "$name") + + if [[ $name == kernel/* ]]; then + echo "$GOW_GITMODRELEASEURL/$package_name.txz" + else + echo "$GOW_GITRELEASEURL/$package_name.txz" + fi +} + +function download_file() { + local url=$1 + local file=$2 + local allow_no_hash=${3:-false} + + if wget -q -nc --show-progress --progress=bar:force:noscroll -O "$file" "$url"; then + # try to get the sha256 sum + local sha_sum=$(wget -qO- "$url.sha256" | cut -d ' ' -f1) + if [ ! -z "$sha_sum" ]; then + echo "INFO: using sha256 sum" + if [ "$(sha256sum "$file" | cut -d ' ' -f1)" != "$sha_sum" ]; then + echo "ERROR: Checksum (sha256) mismatch for $url" + return 1 + fi + else + # try to get the md5 sum + local md5_sum=$(wget -qO- "$url.md5" | cut -d ' ' -f1) + if [ ! -z "$md5_sum" ]; then + echo "INFO: using md5 sum" + if [ "$(md5sum "$file" | cut -d ' ' -f1)" != "$md5_sum" ]; then + echo "ERROR: Checksum (md5) mismatch for $url" + return 1 + fi + elif [[ "$allow_no_hash" = "false" ]]; then + # couldn't verify the hash and we're not allowing install without a matching hash; fail the install + echo "ERROR: unable to verify hash for $url" + return 1 + fi + fi + else + echo "ERROR: Unable to download $url ($?)" + return 1 + fi +} + +function download_pkg() { + local package_file=$(pkg_file "$1") + local package_url=$(pkg_url "$1") + + download_file "$package_url" "$package_file" +}