diff --git a/.gitignore b/.gitignore index eadc8da3..62d21a6b 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,5 @@ debian/rclone-browser* /release /bs0.cmd /src/*.autosave +*.appimage +Dockerfile.appimage diff --git a/ACKNOWLEDGMENTS.md b/ACKNOWLEDGMENTS.md new file mode 100644 index 00000000..3af9f2b4 --- /dev/null +++ b/ACKNOWLEDGMENTS.md @@ -0,0 +1,32 @@ +# Acknowledgments + +This project is a front end for [rclone](https://rclone.org/), which has had a profound effect on educational and research communities by allowing financially constrained students and researchers to utilize cloud storage while working across multiple computational servers and institutions. We are grateful to the rclone developers and community for creating such a powerful and accessible tool that enables this work. + +This project also uses the following external tools and libraries during development and packaging. We acknowledge and thank their creators and maintainers: + +## Build and Packaging Tools + +- **[Inno Setup](https://github.com/jrsoftware/issrc)** - Windows installer creation tool by Jordan Russell and Martijn Laan +- **[node-appdmg](https://github.com/LinusU/node-appdmg)** - macOS DMG creation tool by Linus Unnebäck +- **[qcron](https://github.com/Mankalas/qcron)** - C++ cron-like library by Mankalas (used in earlier versions) +- **[linuxdeploy](https://github.com/linuxdeploy/linuxdeploy)** - Linux AppImage deployment tool +- **[linuxdeploy-plugin-qt](https://github.com/linuxdeploy/linuxdeploy-plugin-qt)** - Qt plugin for linuxdeploy +- **[linuxdeploy-plugin-appimage](https://github.com/linuxdeploy/linuxdeploy-plugin-appimage)** - AppImage creation plugin +- **[AppImageKit](https://github.com/AppImage/AppImageKit)** - AppImage format and tools + +## Development and Testing Tools + +- **[Docker](https://www.docker.com/)** - Containerization platform used for isolated build environments +- **[Vagrant](https://www.vagrantup.com/)** - Virtual machine management tool (optional, used for testing VM environments) + +## Runtime Dependencies + +- **[Qt5](https://www.qt.io/)** - Cross-platform application framework (Core, Gui, Widgets, Network modules) +- **[rclone](https://rclone.org/)** - Command-line program to manage files on cloud storage + +## Other Resources + +- Screenshots and images may reference or use resources from the original Rclone Browser project by Martins Mozeiko + +These tools are used as external dependencies and are not distributed as part of this software. Please refer to their respective licenses and documentation. + diff --git a/CHANGELOG.md b/CHANGELOG.md index 375904d5..eb75a236 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -125,15 +125,15 @@ - Mount and unmount folders on macOS and GNU/Linux - Optionally minimizes to tray, with notifications when upload/download finishes -[1.8.0]: https://github.com/kapitainsky/RcloneBrowser/releases/tag/1.8.0 -[1.7.0]: https://github.com/kapitainsky/RcloneBrowser/releases/tag/1.7.0 -[1.6.0]: https://github.com/kapitainsky/RcloneBrowser/releases/tag/1.6.0 -[1.5.3]: https://github.com/kapitainsky/RcloneBrowser/releases/tag/1.5.3 -[1.5.2]: https://github.com/kapitainsky/RcloneBrowser/releases/tag/1.5.2 -[1.5.1]: https://github.com/kapitainsky/RcloneBrowser/releases/tag/1.5.1 -[1.5]: https://github.com/kapitainsky/RcloneBrowser/releases/tag/1.5 -[1.4.1]: https://github.com/kapitainsky/RcloneBrowser/releases/tag/1.4.1 -[1.4]: https://github.com/kapitainsky/RcloneBrowser/releases/tag/1.4 +[1.8.0]: https://github.com/zaphodbeeblebrox3rd/RcloneBrowser/releases/tag/1.8.0 +[1.7.0]: https://github.com/zaphodbeeblebrox3rd/RcloneBrowser/releases/tag/1.7.0 +[1.6.0]: https://github.com/zaphodbeeblebrox3rd/RcloneBrowser/releases/tag/1.6.0 +[1.5.3]: https://github.com/zaphodbeeblebrox3rd/RcloneBrowser/releases/tag/1.5.3 +[1.5.2]: https://github.com/zaphodbeeblebrox3rd/RcloneBrowser/releases/tag/1.5.2 +[1.5.1]: https://github.com/zaphodbeeblebrox3rd/RcloneBrowser/releases/tag/1.5.1 +[1.5]: https://github.com/zaphodbeeblebrox3rd/RcloneBrowser/releases/tag/1.5 +[1.4.1]: https://github.com/zaphodbeeblebrox3rd/RcloneBrowser/releases/tag/1.4.1 +[1.4]: https://github.com/zaphodbeeblebrox3rd/RcloneBrowser/releases/tag/1.4 [1.2]: https://github.com/mmozeiko/RcloneBrowser/releases/tag/1.2 [1.1]: https://github.com/mmozeiko/RcloneBrowser/releases/tag/1.1 [1.0.0]: https://github.com/mmozeiko/RcloneBrowser/releases/tag/1.0.0 diff --git a/DEVELOPER_README.md b/DEVELOPER_README.md new file mode 100644 index 00000000..404445ef --- /dev/null +++ b/DEVELOPER_README.md @@ -0,0 +1,68 @@ +# Developer Guide + +## Building AppImage with Docker + +If you're building on Ubuntu 18.04+ but want to create an AppImage compatible with CentOS 7+ and Ubuntu 16.04+ (glibc 2.17+), you can use Docker to build in a CentOS 7 environment: + +1. Install Docker: `sudo apt install docker.io` (or use your distribution's package manager) +2. Build the AppImage using Docker: + ```bash + ./scripts/build_AppImage_docker.sh + ``` +3. The AppImage will be created in the `release/` directory with glibc 2.17 compatibility + +This method allows you to build on modern systems (Ubuntu 20.04+, etc.) while ensuring the resulting AppImage works on older systems (CentOS 7+, Ubuntu 16.04+). The Docker container provides an isolated CentOS 7 build environment with glibc 2.17. + +**Note:** The regular build script (`scripts/release_AppImage.sh`) will warn you if you're building on a system with glibc > 2.17 and suggest using Docker for better compatibility. + +### Supported Distributions + +The AppImage built using this Docker method is compatible with: +- CentOS 7+ (glibc 2.17+) +- RHEL 7+ (glibc 2.17+) +- Ubuntu 16.04+ (glibc 2.23+) +- Debian Stretch+ (glibc 2.24+) +- Most modern Linux distributions released after 2014 + +### Troubleshooting + +If you encounter issues building the Docker image: +- Ensure Docker is running: `sudo systemctl start docker` (or equivalent) +- Check Docker permissions: You may need to add your user to the `docker` group or use `sudo` +- Verify the Dockerfile is in the repository root: `Dockerfile.appimage` +- Check available disk space: Docker images and builds can require several GB + +If the AppImage build fails inside the container: +- Check that all source files are present in the repository +- Verify that the build script has execute permissions: `chmod +x scripts/release_AppImage.sh` +- Review the build output for specific error messages + +## Testing AppImage on CentOS 7 + +After building the AppImage, you can test it on CentOS 7 to verify it works correctly. The `tests/` directory contains a script to run the AppImage in a CentOS 7 container with GUI support. + +### Quick Start + +1. **Build the AppImage** (if you haven't already): + ```bash + ./scripts/build_AppImage_docker.sh + ``` + +2. **Run the AppImage in CentOS 7 container with VNC** (recommended): + ```bash + ./tests/run_test_container.sh --vnc + ``` + Then connect to the VNC server at `localhost:5901` (password: `password`) to see the GUI. + +3. **Or use X11 forwarding** (Linux hosts only): + ```bash + ./tests/run_test_container.sh --x11 + ``` + The AppImage GUI will appear in your X server window. + +The script spins up a CentOS 7 container, mounts your AppImage, and launches it automatically so you can verify it works correctly. + +### Detailed Documentation + +For complete instructions, troubleshooting, and optional VM-based testing with Vagrant, see [tests/README.md](tests/README.md). + diff --git a/LICENSE b/LICENSE index 17864a9b..76c670f3 100644 --- a/LICENSE +++ b/LICENSE @@ -2,10 +2,6 @@ MIT License Copyright (c) 2019-2020 kapitainsky (Rclone Browser) Copyright (c) 2017 Martins Mozeiko (Rclone Browser) -Copyright (c) 2015 Mankalas (qcron) -Copyright (c) 2013 Linus Unnebäck (node-appdmg) -Copyright (c) 1997-2020 Jordan Russell (Inno Setup - Windows Installer) -Portions Copyright (c) 2000-2020 Martijn (Inno Setup - Windows Installer) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 62db534f..8bedf633 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ - + -[![Travis CI Build Status][img1]][1] [![AppVeyor Build Status][img2]][2] [![Downloads][img3]][3] [![Release][img4]][4] [![Codacy Badge](https://api.codacy.com/project/badge/Grade/e22f828fc0c94dcf9ddb3d38701d177f)](https://www.codacy.com/manual/kapitainsky/RcloneBrowser?utm_source=github.com&utm_medium=referral&utm_content=kapitainsky/RcloneBrowser&utm_campaign=Badge_Grade) [![License][img5]][5] [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.me/kapitainsky) +[![Travis CI Build Status][img1]][1] [![AppVeyor Build Status][img2]][2] [![Downloads][img3]][3] [![Release][img4]][4] [![License][img5]][5] Rclone browser ============== @@ -10,20 +10,19 @@ Supports macOS, GNU/Linux, BSD family and Windows. Table of contents ------------------- -* [Features](https://github.com/kapitainsky/RcloneBrowser#features) -* [Sample screenshots](https://github.com/kapitainsky/RcloneBrowser#sample-screenshots) -* [How to get it](https://github.com/kapitainsky/RcloneBrowser#how-to-get-it) -* [Why AppImage only for Linux](https://github.com/kapitainsky/RcloneBrowser#why-appimage-only-for-linux) -* [Build instructions](https://github.com/kapitainsky/RcloneBrowser#build-instructions) - * [Linux](https://github.com/kapitainsky/RcloneBrowser#linux) - * [FreeBSD](https://github.com/kapitainsky/RcloneBrowser#freebsd) - * [OpenBSD](https://github.com/kapitainsky/RcloneBrowser#openbsd) - * [NetBSD](https://github.com/kapitainsky/RcloneBrowser#netbsd) - * [macOS](https://github.com/kapitainsky/RcloneBrowser#macos) - * [Windows](https://github.com/kapitainsky/RcloneBrowser#windows) -* [Portable vs standard mode](https://github.com/kapitainsky/RcloneBrowser#portable-vs-standard-mode) -* [History](https://github.com/kapitainsky/RcloneBrowser#history) -* [Code signing certificates donations](https://github.com/kapitainsky/RcloneBrowser#code-signing-certificates-donations) +* [Features](https://github.com/zaphodbeeblebrox3rd/RcloneBrowser#features) +* [Sample screenshots](https://github.com/zaphodbeeblebrox3rd/RcloneBrowser#sample-screenshots) +* [How to get it](https://github.com/zaphodbeeblebrox3rd/RcloneBrowser#how-to-get-it) +* [Why AppImage only for Linux](https://github.com/zaphodbeeblebrox3rd/RcloneBrowser#why-appimage-only-for-linux) +* [Build instructions](https://github.com/zaphodbeeblebrox3rd/RcloneBrowser#build-instructions) + * [Linux](https://github.com/zaphodbeeblebrox3rd/RcloneBrowser#linux) + * [FreeBSD](https://github.com/zaphodbeeblebrox3rd/RcloneBrowser#freebsd) + * [OpenBSD](https://github.com/zaphodbeeblebrox3rd/RcloneBrowser#openbsd) + * [NetBSD](https://github.com/zaphodbeeblebrox3rd/RcloneBrowser#netbsd) + * [macOS](https://github.com/zaphodbeeblebrox3rd/RcloneBrowser#macos) + * [Windows](https://github.com/zaphodbeeblebrox3rd/RcloneBrowser#windows) +* [Portable vs standard mode](https://github.com/zaphodbeeblebrox3rd/RcloneBrowser#portable-vs-standard-mode) +* [History](https://github.com/zaphodbeeblebrox3rd/RcloneBrowser#history) Features -------- @@ -51,27 +50,27 @@ Sample screenshots ------------------- **macOS**

- - + +

**Linux**

- +

 

- +

  **Windows**

- +

 

- +

  @@ -87,11 +86,11 @@ Mac version is compiled to run on all versions of macOS starting with 10.9. Situation with Linux is a bit fuzzier... Linux binary ([AppImage](https://appimage.org/)) for armhf architecture runs on any Raspberry Pi hardware using Raspbian based on Stretch or Buster. -Linux binaries (AppImage) for x86_64 and i386 architectures should run on systems using distributions released in the last few years. x86_64 one is built on CentOS 7 (released in 2014) and i386 on Ubuntu 16.04 LTS (released in 2016). +Linux binaries (AppImage) for x86_64 and i386 architectures should run on systems using distributions released in the last few years. x86_64 one is built on CentOS 7 (glibc 2.17) and i386 on Ubuntu 16.04 LTS (released in 2016, glibc 2.23). Building on CentOS 7 ensures the AppImage is compatible with systems running glibc 2.17 and newer (CentOS 7+, RHEL 7+, Ubuntu 16.04+, Debian Stretch+, etc.). The whole idea with AppImage is to build it on the oldest still supported LTS distro – and it should work on all newer OS releases. AppImage contains an aplication and all the files the app needs to run. In other words, each AppImage has no dependencies other than what is included in the base operating system. -In practical terms it means that for example for Ubuntu Rclone Browser AppImage works on all versions starting with 16.04 LTS and for Debian starting with Stretch. With other distributions YMMV but I test major ones like Suse or Fedora. This is Linux. 10000 different distributions… with changes and customizations often only their authors are aware of. I would be happy to hear what distribution it does not work for. +In practical terms it means that for example for Ubuntu Rclone Browser AppImage works on all versions starting with 16.04 LTS (glibc 2.23+) and for Debian starting with Stretch (glibc 2.24+). The AppImage also works on CentOS 7+ and RHEL 7+ (glibc 2.17+). With other distributions YMMV but I test major ones like Suse or Fedora. This is Linux. 10000 different distributions… with changes and customizations often only their authors are aware of. I would be happy to hear what distribution it does not work for. To make life easier when using AppImages on Linux, you can use [AppImageLauncher](https://github.com/TheAssassin/AppImageLauncher) which monitors your system for downloaded AppImages and provides several useful benefits including: @@ -101,8 +100,6 @@ To make life easier when using AppImages on Linux, you can use [AppImageLauncher * **Easy removal of AppImages from system** - Removing integrated AppImages is pretty simple, too. Similar to updating AppImages, you will find an entry in the context menu in the application launcher that triggers a removal tool. You will be asked to confirm the removal. If you choose to do so, the desktop integration is undone, and the file is removed from your system. -For all released binaries file with hashes signed with my [PGP key](https://github.com/kapitainsky/RcloneBrowser/wiki/PGP-key) is provided. It allows to verify that provided binaries were created by myself (authenticity) and are unchanged (integrity). If you would like to have properly signed releases with code signing certificates please see note at the end of this section. - More and more operating systems include Rclone Browser in their offical distribution channels. You can check availibility [here](https://repology.org/project/rclone-browser/packages). ArchLinux users can install latest release from AUR repository: [rclone-browser][7]. @@ -113,7 +110,20 @@ FreeBSD has its version available from [freshports](https://www.freshports.org/n And if you would like to run it directly on your NAS (e.g. Synology or QNAP) there is docker version provided by @romancin - https://github.com/romancin/rclonebrowser-docker -*Note: For Windows and macOS it would be much nicer (to avoid pop ups about unknown software origin) to properly sign released packages with code signing certificates however it does not come free even for open source software. I looked at it and it seems that to get keys for both systems for the next three years would cost about $500 (3x$99 for [Apple developer account](https://developer.apple.com/support/purchase-activation/) and $200 for cheapest Comodo [code signing certificate](https://comodosslstore.com/uk/code-signing). I am not prepared to budget it as I do this only as a hobby and I am entirely happy with this software as it is. If Rclone Browser users think that properly signed software would be beneficial for them they can [chip in](https://www.paypal.me/kapitainsky) some cash for it. If I raise required amount I will get keys. If not I will give money to some charity.* +### Compatibility Table for AppImage with x86_64 + +| Distribution | Unsupported Versions | Supported Versions | +|--------------|---------------------|-------------------| +| **Debian/Ubuntu** | Ubuntu 14.04 and earlier, Debian 8 (Jessie) and earlier | Ubuntu 16.04+, Debian 9 (Stretch)+ | +| **Suse/OpenSuse** | OpenSUSE 13.2 and earlier | OpenSUSE Leap 42.1+, Tumbleweed | +| **RHEL/CentOS** | RHEL 6 and earlier, CentOS 6 and earlier | RHEL 7+, CentOS 7+ | +| **Fedora** | Fedora 21 and earlier | Fedora 22+ | +| **Arch/Manjaro** | N/A (rolling release) | All current versions | +| **FreeBSD** | FreeBSD 10 and earlier | FreeBSD 11+ | +| **OpenBSD** | OpenBSD 5.8 and earlier | OpenBSD 6.0+ | +| **NetBSD** | NetBSD 7 and earlier | NetBSD 8+ | +| **macOS** | macOS 10.8 and earlier | macOS 10.9+ | +| **Windows** | Windows 7 and earlier (without Visual Studio 2015+) | Windows 8+ with Visual Studio 2015+ or Windows 10+ | Why AppImage only for Linux ---------------------------- @@ -146,23 +156,33 @@ If for whatever reason you are not happy or your system is not covered with prov Build instructions ------------------ +**System Requirements:** This project requires C++14 support (GCC 5.1+ or equivalent) and Qt5. The source code can be built on Ubuntu 18.04 LTS through 25.10 and equivalent distributions. The following table shows supported and unsupported major versions for each distribution: + +**Note for AppImage Builds:** While the source code builds on Ubuntu 18.04-25.10, AppImages should be built on **CentOS 7** (glibc 2.17) to ensure compatibility with systems running glibc 2.17 and newer (CentOS 7+, RHEL 7+, Ubuntu 16.04+, etc.). Building AppImages on newer systems will limit compatibility to systems with matching or newer glibc versions. + +**Building AppImages on Newer Systems:** If you're building on Ubuntu 18.04+ but want to maintain compatibility with CentOS 7+, RHEL 7+, and Ubuntu 16.04+, you can use Docker to build in a CentOS 7 environment. See the [Developer Guide](DEVELOPER_README.md#building-appimage-with-docker) for instructions. + + ### Linux +> Compiling, rather than using the AppImage will yield you a build with modern OpenSSL implementations. The AppImage is built with OpenSSL 1.1. It might or might not be a real-life security concern in this context in the way it is used. 1. Install dependencies for your particular distribution: * **Debian/Ubuntu and derivatives**: `sudo apt update && sudo apt -y install git g++ cmake make qtdeclarative5-dev` * **Suse/OpenSuse**: `sudo zypper ref && sudo zypper --non-interactive install git cmake make gcc-c++ libQt5Core-devel libQt5Widgets-devel libQt5Network-devel` - * **RHEL/CentOS**: `sudo yum -y install git gcc-c++ cmake make qt5-qtdeclarative` + * **RHEL**: `sudo yum -y install git gcc-c++ cmake make qt5-qtdeclarative` * **Fedora**: `sudo dnf -y install git g++ cmake make qt5-qtdeclarative-devel` * **Arch/Manjaro**: `sudo pacman -Sy --noconfirm --needed git gcc cmake make qt5-declarative` -2. Clone source code from this repo `git clone https://github.com/kapitainsky/RcloneBrowser.git` +2. Clone source code from this repo `git clone https://github.com/zaphodbeeblebrox3rd/RcloneBrowser.git` 3. Go to source folder `cd RcloneBrowser` 4. Create new build folder - `mkdir build && cd build` 5. Run `cmake ..` from build folder to create makefile 6. Run `make` from build folder to create binary 7. Install `sudo make install` +**For Docker-based AppImage builds:** See the [Developer Guide](DEVELOPER_README.md#building-appimage-with-docker) for instructions on building AppImages using Docker for maximum compatibility. + ### FreeBSD 1. Install dependencies `sudo pkg install git cmake qt5-buildtools qt5-declarative qt5-qmake` -2. Clone source code from this repo `git clone https://github.com/kapitainsky/RcloneBrowser.git` +2. Clone source code from this repo `git clone https://github.com/zaphodbeeblebrox3rd/RcloneBrowser.git` 3. Go to source folder `cd RcloneBrowser` 4. Create new build folder - `mkdir build && cd build` 5. Run `cmake ..` from build folder to create makefile @@ -173,7 +193,7 @@ Build instructions ### OpenBSD 1. Install dependencies `sudo pkg_add git cmake qt5` -2. Clone source code from this repo `git clone https://github.com/kapitainsky/RcloneBrowser.git` +2. Clone source code from this repo `git clone https://github.com/zaphodbeeblebrox3rd/RcloneBrowser.git` 3. Go to source folder `cd RcloneBrowser` 4. Create new build folder - `mkdir build && cd build` 5. Run `cmake .. -DCMAKE_PREFIX_PATH:PATH=/usr/local/lib/qt5/cmake` from build folder to create makefile @@ -184,7 +204,7 @@ Build instructions ### NetBSD 1. Install dependencies `sudo pkgin install git cmake qt5-qtdeclarative` -2. Clone source code from this repo `git clone https://github.com/kapitainsky/RcloneBrowser.git` +2. Clone source code from this repo `git clone https://github.com/zaphodbeeblebrox3rd/RcloneBrowser.git` 3. Go to source folder `cd RcloneBrowser` 4. Create new build folder - `mkdir build && cd build` 5. Run `cmake .. -DCMAKE_PREFIX_PATH:PATH=/usr/pkg/qt5` from build folder to create makefile @@ -197,7 +217,7 @@ Build instructions 1. If you don't have [Homebrew](https://brew.sh/) yet install it `/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"` 2. You might be asked to install xcode command line tools - do it. This is actuall macOS SDK, headers, and build tools. You don't need full xcode IDE. 3. Install dependencies `brew install git cmake rclone qt5` -4. Clone source code from this repo `git clone https://github.com/kapitainsky/RcloneBrowser.git` +4. Clone source code from this repo `git clone https://github.com/zaphodbeeblebrox3rd/RcloneBrowser.git` 5. Go to source folder `cd RcloneBrowser` 6. Create new build folder - `mkdir build && cd build` 7. Run `cmake .. -DCMAKE_PREFIX_PATH:PATH=/usr/local/opt/qt` from build folder to create makefile @@ -251,26 +271,32 @@ I used DinCahill's [fork](https://github.com/DinCahill/RcloneBrowser) as a base I fixed whatever I found not working and added various tweaks enhancing functionality. I recompiled and repackaged everything using latest Qt (5.13.1) and latest platforms' compilers. This on its own fixed some issues and added new features like support for dark mode in macOS. Then followed with more fixes and more features. Rclone Browser was great again:) and is getting better. -Code signing certificates donations ---------------------------- +Acknowledgments +--------------- + +This project uses various external tools and libraries during development and packaging. See [ACKNOWLEDGMENTS.md](ACKNOWLEDGMENTS.md) for a complete list and recognition of their creators and maintainers. + +Special Thanks +-------------- + +Special recognition goes to **kapitainsky** for his major contributions to this project over the years. His significant work in maintaining, fixing, and enhancing Rclone Browser has been invaluable to the community. -If you would like to donate towards code signing keys please feel free to [do it](https://www.paypal.me/kapitainsky). If I don't raise required $500 I will give all money to some charity. Please see my note regarding it at the end of [How to get it](https://github.com/kapitainsky/RcloneBrowser#how-to-get-it) section. I will keep all updated with amount raised. +If you'd like to support kapitainsky's efforts to obtain code-signing certificates for Windows and macOS releases (which would eliminate security warnings and improve user experience), you can contribute via [PayPal](https://www.paypal.me/kapitainsky). -Raised so far: 6.4 USD (1.3% of the required target) -[1]: https://travis-ci.org/kapitainsky/RcloneBrowser -[2]: https://ci.appveyor.com/project/kapitainsky/RcloneBrowser -[3]: https://github.com/kapitainsky/RcloneBrowser/releases -[4]: https://github.com/kapitainsky/RcloneBrowser/releases/latest -[5]: https://github.com/kapitainsky/RcloneBrowser/blob/master/LICENSE +[1]: https://travis-ci.org/zaphodbeeblebrox3rd/RcloneBrowser +[2]: https://ci.appveyor.com/project/zaphodbeeblebrox3rd/RcloneBrowser +[3]: https://github.com/zaphodbeeblebrox3rd/RcloneBrowser/releases +[4]: https://github.com/zaphodbeeblebrox3rd/RcloneBrowser/releases/latest +[5]: https://github.com/zaphodbeeblebrox3rd/RcloneBrowser/blob/master/LICENSE [6]: https://www.videolan.org [7]: https://aur.archlinux.org/packages/rclone-browser [8]: https://docs.microsoft.com/en-us/visualstudio/releases/2019/release-notes [9]: http://www.cmake.org/ [10]: https://www.qt.io/download-open-source/ -[img1]: https://api.travis-ci.org/kapitainsky/RcloneBrowser.svg?branch=master +[img1]: https://api.travis-ci.org/zaphodbeeblebrox3rd/RcloneBrowser.svg?branch=master [img2]: https://ci.appveyor.com/api/projects/status/cclx7jc48t4u4x9u?svg=true -[img3]: https://img.shields.io/github/downloads/kapitainsky/RcloneBrowser/total.svg?maxAge=3600 -[img4]: https://img.shields.io/github/release/kapitainsky/RcloneBrowser.svg?maxAge=3600 -[img5]: https://img.shields.io/github/license/kapitainsky/RcloneBrowser.svg?maxAge=3600 +[img3]: https://img.shields.io/github/downloads/zaphodbeeblebrox3rd/RcloneBrowser/total.svg?maxAge=3600 +[img4]: https://img.shields.io/github/release/zaphodbeeblebrox3rd/RcloneBrowser.svg?maxAge=3600 +[img5]: https://img.shields.io/github/license/zaphodbeeblebrox3rd/RcloneBrowser.svg?maxAge=3600 [billziss-gh_cgofuse_i18]: https://github.com/billziss-gh/cgofuse/issues/18 diff --git a/assets/rclone-browser.appdata.xml b/assets/rclone-browser.appdata.xml index 37ca1273..31cc9b32 100644 --- a/assets/rclone-browser.appdata.xml +++ b/assets/rclone-browser.appdata.xml @@ -1,7 +1,7 @@ - org.kapitainsky.rclone_browser + org.rclone-browser.rclone_browser MIT MIT Rclone Browser @@ -30,16 +30,16 @@ - https://github.com/kapitainsky/RcloneBrowser/wiki/images/IMGdefault.png + https://github.com/zaphodbeeblebrox3rd/RcloneBrowser/wiki/images/IMGdefault.png - https://github.com/kapitainsky/RcloneBrowser/wiki/images/IMGtransfer.png + https://github.com/zaphodbeeblebrox3rd/RcloneBrowser/wiki/images/IMGtransfer.png - https://github.com/kapitainsky/RcloneBrowser/ - https://github.com/kapitainsky/RcloneBrowser/issues/ - https://github.com/kapitainsky/RcloneBrowser/wiki - https://github.com/kapitainsky/RcloneBrowser/issues/ + https://github.com/zaphodbeeblebrox3rd/RcloneBrowser/ + https://github.com/zaphodbeeblebrox3rd/RcloneBrowser/issues/ + https://github.com/zaphodbeeblebrox3rd/RcloneBrowser/wiki + https://github.com/zaphodbeeblebrox3rd/RcloneBrowser/issues/ diff --git a/scripts/rclone-browser-win-installer.iss b/scripts/rclone-browser-win-installer.iss index bdf9e979..c7a5fd1d 100755 --- a/scripts/rclone-browser-win-installer.iss +++ b/scripts/rclone-browser-win-installer.iss @@ -1,7 +1,7 @@ #define MyAppName "Rclone Browser" -#define MyAppPublisher "kapitainsky" -#define MyAppURL "https://github.com/kapitainsky/RcloneBrowser" +#define MyAppPublisher "zaphodbeeblebrox3rd" +#define MyAppURL "https://github.com/zaphodbeeblebrox3rd/RcloneBrowser" #define MyAppExeName "RcloneBrowser.exe" [Setup] diff --git a/scripts/release_AppImage.sh b/scripts/release_AppImage.sh index dd930a64..305c950e 100755 --- a/scripts/release_AppImage.sh +++ b/scripts/release_AppImage.sh @@ -2,25 +2,26 @@ set -e -# x86_64 build on CentOS 7.7 - # gcc 7 installed - # sudo yum install -y centos-release-scl - # sudo yum install -y devtoolset-7-gcc* - # run below command before build - # scl enable devtoolset-7 bash - - # newer cmake is required than one included in CentOS 7 +# x86_64 build + # For AppImage compatibility with glibc 2.17+ (CentOS 7+ and Ubuntu 16.04+), build on CentOS 7 + # Building on newer systems (Ubuntu 18.04+, glibc 2.27+) will limit compatibility + # newer cmake may be required depending on distribution # download from http://www.cmake.org/download # sudo mkdir /opt/cmake # sudo sh cmake-$version.$build-Linux-x86_64.sh --prefix=/opt/cmake if [ $(arch) = "x86_64" ]; then - CMAKE="/opt/cmake/bin/cmake" + # Use custom cmake if available, otherwise use system cmake + if [ -f "/opt/cmake/bin/cmake" ]; then + CMAKE="/opt/cmake/bin/cmake" + else + CMAKE="cmake" + fi fi -# i686 build on Ubuntu 16.04 LTS +# i686 build on Ubuntu 16.04 LTS (glibc 2.23, GCC 5.4 - supports C++14) -# armv7l build on raspbian stretch +# armv7l build on raspbian stretch (glibc 2.24, GCC 6.3 - supports C++14) # Qt path and flags set in env e.g.: # export PATH="/opt/Qt/5.14.0/bin/:$PATH" @@ -39,15 +40,57 @@ if [ "$1" = "SIGN" ]; then export SIGN="1" fi -# check gcc version on Centos -if [ $(arch) = "x86_64" ]; then - currentver="$(gcc -dumpversion)" - if [ "${currentver:0:1}" -lt "7" ]; then - echo "gcc version 7 or newer required" - echo "on Cetos 7 run" - echo "scl enable devtoolset-7 bash" - exit - fi +# check gcc version (C++14 requires GCC 5.1+) +# Use the GCC from PATH (which should be devtoolset-7's GCC 7.3 in CentOS 7 Docker) +GCC_CMD="gcc" +if [ -f "/opt/rh/devtoolset-7/root/usr/bin/gcc" ]; then + GCC_CMD="/opt/rh/devtoolset-7/root/usr/bin/gcc" +fi +currentver="$($GCC_CMD -dumpversion | cut -d. -f1)" +minorver="$($GCC_CMD -dumpversion | cut -d. -f2)" +if [ "$currentver" -lt "5" ] || ([ "$currentver" -eq "5" ] && [ "$minorver" -lt "1" ]); then + echo "Error: GCC 5.1 or newer required for C++14 support" + echo "Current GCC version: $($GCC_CMD -dumpversion)" + echo "GCC path: $GCC_CMD" + exit 1 +fi +echo "Using GCC $($GCC_CMD -dumpversion) from: $GCC_CMD" + +# check glibc version for AppImage compatibility +# AppImages built on systems with newer glibc won't run on older systems +# For maximum compatibility, build on CentOS 7 (glibc 2.17) +# Skip this check if running in Docker (Docker build script handles compatibility) +if [ -z "$CI" ] && [ ! -f /.dockerenv ] && [ $(arch) = "x86_64" ] || [ $(arch) = "i686" ]; then + if command -v ldd >/dev/null 2>&1; then + # Extract glibc version from ldd output (format varies: "ldd (Ubuntu GLIBC 2.35) 2.35" or "ldd (GNU libc) 2.27") + GLIBC_VERSION=$(ldd --version 2>&1 | head -n1 | grep -oE '[0-9]+\.[0-9]+' | head -n1) + if [ -n "$GLIBC_VERSION" ]; then + GLIBC_MAJOR=$(echo "$GLIBC_VERSION" | cut -d. -f1) + GLIBC_MINOR=$(echo "$GLIBC_VERSION" | cut -d. -f2) + + # Warn if glibc is newer than 2.17 (CentOS 7) + # Check if major > 2, or (major == 2 and minor > 17) + if [ "$GLIBC_MAJOR" -gt "2" ] || ([ "$GLIBC_MAJOR" -eq "2" ] && [ -n "$GLIBC_MINOR" ] && [ "$GLIBC_MINOR" -gt "17" ]); then + echo "===================================================================" + echo "Warning: Building on system with glibc $GLIBC_VERSION" + echo " This AppImage may not run on systems with glibc < $GLIBC_VERSION" + echo "" + echo "For maximum compatibility (glibc 2.17+, CentOS 7+ and Ubuntu 16.04+), you can:" + echo " 1. Build on CentOS 7 directly" + echo " 2. Use Docker: ./scripts/build_AppImage_docker.sh" + echo "" + echo "Press Ctrl+C to cancel, or wait 5 seconds to continue with current build..." + echo "===================================================================" + sleep 5 + fi + fi + fi +elif [ -f /.dockerenv ]; then + # Running in Docker - verify we're on CentOS 7 (glibc 2.17) + if command -v ldd >/dev/null 2>&1; then + GLIBC_VERSION=$(ldd --version 2>&1 | head -n1 | grep -oE '[0-9]+\.[0-9]+' | head -n1) + echo "Building in Docker container with glibc $GLIBC_VERSION (target: glibc 2.17 for CentOS 7 compatibility)" + fi fi # building AppImage in temporary directory to keep system clean @@ -97,6 +140,18 @@ fi # build and install to temporary AppDir folder cd "$BUILD" +# On CentOS 7 with devtoolset, ensure we link against system libstdc++ (glibc 2.17) +# not devtoolset's libstdc++ (glibc 2.18). +# Set library path and linker flags to prioritize system libs. +if [ -d "/opt/rh/devtoolset-7" ] && [ -f "/usr/lib64/libstdc++.so.6" ]; then + export LD_LIBRARY_PATH="/usr/lib64:/usr/lib:${LD_LIBRARY_PATH}" + # Explicitly tell linker to use system libstdc++ instead of devtoolset's + export LDFLAGS="-L/usr/lib64 -Wl,-rpath,/usr/lib64 ${LDFLAGS}" + export CPPFLAGS="-I/usr/include ${CPPFLAGS}" + echo "Using system libstdc++ for glibc 2.17 compatibility (avoiding devtoolset version)" + echo "LDFLAGS set to: $LDFLAGS" +fi + if [ $(arch) = "armv7l" ]; then # more threads need swap on 1GB RAM RPi cmake .. -DCMAKE_INSTALL_PREFIX=/usr @@ -129,14 +184,167 @@ cp "$ROOT"/LICENSE "$TEMP_BASE"/"$TARGET"/AppDir/License.txt # https://github.com/linuxdeploy/linuxdeploy # https://github.com/linuxdeploy/linuxdeploy-plugin-qt -linuxdeploy --appdir AppDir --desktop-file=AppDir/usr/share/applications/rclone-browser.desktop --plugin qt -#linuxdeploy-plugin-qt --appdir AppDir +# Set Qt environment variables to help linuxdeploy-qt find Qt modules +# Detect Qt installation path (varies by distro) +if command -v qmake >/dev/null 2>&1; then + export QTDIR=$(qmake -query QT_INSTALL_PREFIX 2>/dev/null || echo "/usr/lib64/qt5") + export PATH="$QTDIR/bin:$PATH" + # Find Qt plugin path (CentOS uses /usr/lib64/qt5/plugins, Ubuntu uses /usr/lib/x86_64-linux-gnu/qt5/plugins) + if [ -d "/usr/lib64/qt5/plugins" ]; then + export QT_PLUGIN_PATH="/usr/lib64/qt5/plugins" + elif [ -d "/usr/lib/x86_64-linux-gnu/qt5/plugins" ]; then + export QT_PLUGIN_PATH="/usr/lib/x86_64-linux-gnu/qt5/plugins" + else + export QT_PLUGIN_PATH="${QT_PLUGIN_PATH:-/usr/lib64/qt5/plugins}" + fi + echo "Qt installation: QTDIR=$QTDIR, QT_PLUGIN_PATH=$QT_PLUGIN_PATH" +fi + +# Deploy dependencies first, then Qt plugin +# The app uses Qt5::Widgets and Qt5::Network (see src/CMakeLists.txt line 137) +linuxdeploy --appdir AppDir \ + --executable AppDir/usr/bin/rclone-browser \ + --desktop-file=AppDir/usr/share/applications/rclone-browser.desktop + +# Deploy Qt libraries - manually specify the libraries the app needs +# The app links against Qt5::Widgets and Qt5::Network, which also require Qt5::Core and Qt5::Gui +echo "Deploying Qt libraries manually..." +# Find Qt library directory (varies by distro: /usr/lib64 for CentOS/RHEL, /usr/lib/x86_64-linux-gnu for Ubuntu/Debian) +if [ -d "/usr/lib64/qt5" ] && [ -f "/usr/lib64/libQt5Widgets.so.5" ]; then + QT_LIB_DIR="/usr/lib64" +elif [ -d "/usr/lib/x86_64-linux-gnu/qt5" ] && [ -f "/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5" ]; then + QT_LIB_DIR="/usr/lib/x86_64-linux-gnu" +else + # Try to find Qt libraries + QT_LIB_DIR=$(find /usr/lib* -name "libQt5Widgets.so.5" 2>/dev/null | head -1 | xargs dirname 2>/dev/null || echo "/usr/lib64") +fi + +echo "Using Qt library directory: $QT_LIB_DIR" +for lib in libQt5Widgets.so.5 libQt5Network.so.5 libQt5Core.so.5 libQt5Gui.so.5; do + if [ -f "$QT_LIB_DIR/$lib" ]; then + echo "Deploying $lib from $QT_LIB_DIR..." + # Deploy library (strip failures are non-fatal, libraries are still copied) + linuxdeploy --appdir AppDir --library "$QT_LIB_DIR/$lib" 2>&1 | grep -v "ERROR: Strip call failed" || true + else + echo "Warning: $lib not found in $QT_LIB_DIR" + fi +done + +# Deploy Qt plugins using the qt plugin (this will handle platform plugins, etc.) +# The plugin might fail but that's okay if libraries are already deployed +linuxdeploy-plugin-qt --appdir AppDir 2>&1 | grep -v "ERROR: Could not find Qt modules" || true + +# Always manually deploy Qt platform plugins to ensure they're present +# This is critical for GUI applications - without platform plugins, Qt apps won't start +echo "Deploying Qt platform plugins..." +PLATFORM_PLUGIN_DIR="" +if [ -d "/usr/lib64/qt5/plugins/platforms" ]; then + PLATFORM_PLUGIN_DIR="/usr/lib64/qt5/plugins/platforms" +elif [ -d "/usr/lib/x86_64-linux-gnu/qt5/plugins/platforms" ]; then + PLATFORM_PLUGIN_DIR="/usr/lib/x86_64-linux-gnu/qt5/plugins/platforms" +fi + +if [ -n "$PLATFORM_PLUGIN_DIR" ] && [ -d "$PLATFORM_PLUGIN_DIR" ]; then + mkdir -p ./AppDir/usr/plugins/platforms + # First, deploy libqxcb.so using linuxdeploy to pull in all its dependencies + if [ -f "$PLATFORM_PLUGIN_DIR/libqxcb.so" ]; then + echo "Deploying libqxcb.so and its dependencies..." + linuxdeploy --appdir AppDir --library "$PLATFORM_PLUGIN_DIR/libqxcb.so" 2>&1 | grep -v "ERROR: Strip call failed" || true + # Move it to the correct location (linuxdeploy puts it in usr/lib, we need it in usr/plugins/platforms) + if [ -f "./AppDir/usr/lib/libqxcb.so" ]; then + mkdir -p ./AppDir/usr/plugins/platforms + mv ./AppDir/usr/lib/libqxcb.so ./AppDir/usr/plugins/platforms/ 2>/dev/null || cp ./AppDir/usr/lib/libqxcb.so ./AppDir/usr/plugins/platforms/ 2>/dev/null || true + fi + fi + # Copy all other platform plugins + cp "$PLATFORM_PLUGIN_DIR"/libq*.so ./AppDir/usr/plugins/platforms/ 2>/dev/null || true + if [ -f "./AppDir/usr/plugins/platforms/libqxcb.so" ]; then + echo "Successfully deployed Qt platform plugins from $PLATFORM_PLUGIN_DIR (including libqxcb.so for X11)" + echo "Qt platform plugins deployed to: ./AppDir/usr/plugins/platforms/" + ls -la ./AppDir/usr/plugins/platforms/ | head -10 || echo "Warning: Could not list platform plugins" + else + echo "Error: libqxcb.so deployment failed!" + echo "Attempted to copy from: $PLATFORM_PLUGIN_DIR" + ls -la "$PLATFORM_PLUGIN_DIR" || true + exit 1 + fi +else + echo "Error: Qt platform plugins directory not found" + exit 1 +fi + +# Ensure Qt can find the plugins by updating the hook script +# CRITICAL: The AppRun script sets $this_dir but NOT $APPDIR +# The hook needs to export APPDIR so QT_PLUGIN_PATH works correctly +mkdir -p ./AppDir/apprun-hooks + +echo "Creating/updating Qt plugin path hook..." +# Always recreate the hook to ensure it's correct +cat > ./AppDir/apprun-hooks/linuxdeploy-plugin-qt-hook.sh << 'HOOKEOF' +#!/bin/bash +# Qt plugin hook for AppImage +# This must define APPDIR since AppRun only sets $this_dir + +# Set APPDIR from the script location (AppRun sources this from $this_dir) +export APPDIR="${APPDIR:-"$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")/.."}" + +# Set Qt plugin path so Qt can find platform plugins +export QT_PLUGIN_PATH="${APPDIR}/usr/plugins:${QT_PLUGIN_PATH}" + +# Also set LD_LIBRARY_PATH to find Qt libraries +export LD_LIBRARY_PATH="${APPDIR}/usr/lib:${LD_LIBRARY_PATH}" + +# Try to make Qt apps more "native looking" on Gtk-based desktops +case "${XDG_CURRENT_DESKTOP}" in + *GNOME*|*gnome*|*XFCE*) + export QT_QPA_PLATFORMTHEME=gtk2 + ;; +esac +HOOKEOF +chmod +x ./AppDir/apprun-hooks/linuxdeploy-plugin-qt-hook.sh +echo "Created Qt plugin path hook with APPDIR definition" + +# Bundle libstdc++ for compatibility across different distributions +# IMPORTANT: Use the system libstdc++ (compatible with glibc 2.17), not devtoolset's +# On CentOS 7, devtoolset-7's libstdc++ requires glibc 2.18, but system libstdc++ only needs 2.17 +# Find system libstdc++ location (prioritize system paths, avoid devtoolset paths) +if [ -f "/usr/lib64/libstdc++.so.6" ] && ! readlink -f /usr/lib64/libstdc++.so.6 | grep -q devtoolset; then + # CentOS 7 system libstdc++ (glibc 2.17 compatible) + STDCPP_LIB="/usr/lib64/libstdc++.so.6" +elif [ -f "/usr/lib/x86_64-linux-gnu/libstdc++.so.6" ] && ! readlink -f /usr/lib/x86_64-linux-gnu/libstdc++.so.6 | grep -q devtoolset; then + # Ubuntu/Debian system libstdc++ + STDCPP_LIB="/usr/lib/x86_64-linux-gnu/libstdc++.so.6" +elif [ -f "/usr/lib/libstdc++.so.6" ] && ! readlink -f /usr/lib/libstdc++.so.6 | grep -q devtoolset; then + # Generic system libstdc++ + STDCPP_LIB="/usr/lib/libstdc++.so.6" +fi + +if [ -n "$STDCPP_LIB" ] && [ -f "$STDCPP_LIB" ]; then + echo "Bundling system libstdc++ for compatibility (glibc 2.17+)..." + cp "$STDCPP_LIB" ./AppDir/usr/lib/ 2>/dev/null || true + # Also try to find and bundle system libgcc_s (avoid devtoolset) + if [ -f "/usr/lib64/libgcc_s.so.1" ] && ! readlink -f /usr/lib64/libgcc_s.so.1 2>/dev/null | grep -q devtoolset; then + cp /usr/lib64/libgcc_s.so.1 ./AppDir/usr/lib/ 2>/dev/null || true + elif [ -f "/usr/lib/x86_64-linux-gnu/libgcc_s.so.1" ] && ! readlink -f /usr/lib/x86_64-linux-gnu/libgcc_s.so.1 2>/dev/null | grep -q devtoolset; then + cp /usr/lib/x86_64-linux-gnu/libgcc_s.so.1 ./AppDir/usr/lib/ 2>/dev/null || true + fi +else + echo "Warning: Could not find system libstdc++ (avoiding devtoolset version)" + echo "AppImage may have compatibility issues on older systems" +fi if [ $(arch) != "armv7l" ] then # we add openssl 1.1.1 libs needed for distros still using openssl 1.0 - cp /opt/openssl-1.1.1/lib/libssl.so.1.1 ./AppDir/usr/bin/ - cp /opt/openssl-1.1.1/lib/libcrypto.so.1.1 ./AppDir/usr/bin/ + # Qt 5.x uses OpenSSL 1.1.x, and bundling 1.1.1 ensures compatibility with older systems + if [ -f "/opt/openssl-1.1.1/lib/libssl.so.1.1" ] && [ -f "/opt/openssl-1.1.1/lib/libcrypto.so.1.1" ]; then + cp /opt/openssl-1.1.1/lib/libssl.so.1.1 ./AppDir/usr/bin/ + cp /opt/openssl-1.1.1/lib/libcrypto.so.1.1 ./AppDir/usr/bin/ + echo "Bundled OpenSSL 1.1.1 libraries for compatibility with distros using OpenSSL 1.0" + else + echo "Warning: OpenSSL 1.1.1 libraries not found at /opt/openssl-1.1.1/ - AppImage will use system OpenSSL" + echo "This may cause issues on older distros that still use OpenSSL 1.0 (e.g., Ubuntu 16.04, Debian Stretch)" + fi fi # https://github.com/linuxdeploy/linuxdeploy-plugin-appimage @@ -144,20 +352,29 @@ linuxdeploy-plugin-appimage --appdir=AppDir # raspberry pi build if [ $(arch) = "armv7l" ]; then - rename 's/armhf/raspberrypi-armhf/' Rclone_Browser* - rename 's/Rclone_Browser/rclone-browser/' Rclone_Browser* + for file in Rclone_Browser*; do + [ -f "$file" ] || continue + newname=$(echo "$file" | sed 's/armhf/raspberrypi-armhf/; s/Rclone_Browser/rclone-browser/') + [ "$file" != "$newname" ] && mv "$file" "$newname" + done fi # x86 build if [ $(arch) = "i686" ]; then - rename 's/i386/linux-i386/' Rclone_Browser* - rename 's/Rclone_Browser/rclone-browser/' Rclone_Browser* + for file in Rclone_Browser*; do + [ -f "$file" ] || continue + newname=$(echo "$file" | sed 's/i386/linux-i386/; s/Rclone_Browser/rclone-browser/') + [ "$file" != "$newname" ] && mv "$file" "$newname" + done fi # x86_64 build if [ $(arch) = "x86_64" ]; then - rename x86_64 linux-x86_64 Rclone_Browser* - rename Rclone_Browser rclone-browser Rclone_Browser* + for file in Rclone_Browser*; do + [ -f "$file" ] || continue + newname=$(echo "$file" | sed 's/x86_64/linux-x86_64/; s/Rclone_Browser/rclone-browser/') + [ "$file" != "$newname" ] && mv "$file" "$newname" + done fi cp ./*AppImage "$ROOT"/release/ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 321ea722..8c33a42b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,7 +10,9 @@ endif() if(WIN32) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /WX /wd4100 /wd4189") else() - add_definitions("-pedantic -Wall -Wextra -Werror -std=c++11") + set(CMAKE_CXX_STANDARD 14) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + add_definitions("-pedantic -Wall -Wextra -Werror") endif() if (APPLE) diff --git a/src/main_window.cpp b/src/main_window.cpp index a792075f..61a2d344 100644 --- a/src/main_window.cpp +++ b/src/main_window.cpp @@ -210,9 +210,7 @@ MainWindow::MainWindow() { R"(

GUI for rclone, v)" RCLONE_BROWSER_VERSION "

" R"(

Copyright © 2019

)" - R"(

Current development and maintenance
kapitainsky

)" - - R"(

New features and fixes
contributors

)" + R"(

New features and fixes
contributors

)" R"(

Original version
Martins Mozeiko

)")); }); @@ -590,8 +588,8 @@ void MainWindow::rcloneGetVersion() { current_date); // get latest version available - QString url = "https://api.github.com/repos/kapitainsky/" - "rclonebrowser/releases/latest"; + QString url = "https://api.github.com/repos/zaphodbeeblebrox3rd/" + "RcloneBrowser/releases/latest"; QNetworkAccessManager manager; QNetworkReply *response = manager.get(QNetworkRequest(QUrl(url))); QEventLoop event; @@ -625,7 +623,7 @@ void MainWindow::rcloneGetVersion() { R"(New version: v)" + rclone_browser_latest_version_no + "

" - R"(

Visit releases page to download

)")); + R"(

Visit releases page to download

)")); }; }; }; @@ -810,6 +808,7 @@ void MainWindow::rcloneListRemotes() { } #else // for Linux/BSD PM_ListViewIconSize stays the same + Q_UNUSED(darkModeIconScale); size = lightModeiconScale * style->pixelMetric(QStyle::PM_ListViewIconSize); #endif #else @@ -1168,7 +1167,7 @@ void MainWindow::addStream(const QString &remote, const QString &stream) { ui.jobs->insertWidget(1, line); ui.tabs->setTabText(1, QString("Jobs (%1)").arg(++mJobCount)); - player->start(stream, QProcess::ReadOnly); + player->start(stream, QStringList(), QProcess::ReadOnly); UseRclonePassword(rclone); rclone->start(GetRclone(), QStringList() << "cat" << GetRcloneConf() << remote, diff --git a/tests/Dockerfile.test b/tests/Dockerfile.test new file mode 100644 index 00000000..4dc11908 --- /dev/null +++ b/tests/Dockerfile.test @@ -0,0 +1,79 @@ +# Dockerfile for testing AppImage on CentOS 7 with GUI support +# This allows testing the AppImage in a CentOS 7 environment with desktop GUI + +FROM centos:7 + +# CentOS 7 reached end-of-life, so we need to use vault.centos.org +# Update yum configuration to use vault repository +RUN sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*.repo && \ + sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*.repo + +# Install EPEL repository +RUN yum install -y epel-release && yum clean all + +# Install desktop environment (Xfce - lightweight and suitable for testing) +# Install VNC server for remote GUI access +# Install FUSE (required for AppImage execution) +# Install X11 utilities for X11 forwarding +# Install wget, curl, and unzip for downloading and extracting rclone +RUN yum install -y \ + xfce4 \ + xfce4-terminal \ + tigervnc-server \ + fuse \ + xorg-x11-xauth \ + xorg-x11-utils \ + xorg-x11-server-Xvfb \ + which \ + wget \ + curl \ + unzip \ + && yum clean all + +# Install rclone (download binary directly since CentOS 7 repos don't have it) +# Using a recent stable version that works on CentOS 7 (glibc 2.17) +RUN RCLONE_VERSION="1.66.0" && \ + wget -q "https://github.com/rclone/rclone/releases/download/v${RCLONE_VERSION}/rclone-v${RCLONE_VERSION}-linux-amd64.zip" -O /tmp/rclone.zip && \ + unzip -q /tmp/rclone.zip -d /tmp && \ + cp /tmp/rclone-v${RCLONE_VERSION}-linux-amd64/rclone /usr/local/bin/ && \ + chmod +x /usr/local/bin/rclone && \ + rm -rf /tmp/rclone.zip /tmp/rclone-v${RCLONE_VERSION}-linux-amd64 && \ + rclone version + +# Set up VNC server +# Create VNC user directory and set password (default: password) +# You can change the password by mounting a custom .vnc/passwd file +RUN mkdir -p /root/.vnc && \ + echo "password" | vncpasswd -f > /root/.vnc/passwd && \ + chmod 600 /root/.vnc/passwd + +# Create VNC startup script +RUN echo '#!/bin/bash' > /root/.vnc/xstartup && \ + echo 'unset SESSION_MANAGER' >> /root/.vnc/xstartup && \ + echo 'unset DBUS_SESSION_BUS_ADDRESS' >> /root/.vnc/xstartup && \ + echo '[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources' >> /root/.vnc/xstartup && \ + echo 'xsetroot -solid grey' >> /root/.vnc/xstartup && \ + echo 'vncconfig -iconic &' >> /root/.vnc/xstartup && \ + echo 'export XKL_XMODMAP_DISABLE=1' >> /root/.vnc/xstartup && \ + echo 'export XDG_CURRENT_DESKTOP="XFCE"' >> /root/.vnc/xstartup && \ + echo 'export XDG_MENU_PREFIX="xfce-"' >> /root/.vnc/xstartup && \ + echo 'export XDG_SESSION_DESKTOP="xfce"' >> /root/.vnc/xstartup && \ + echo 'startxfce4 &' >> /root/.vnc/xstartup && \ + chmod +x /root/.vnc/xstartup + +# Set up environment for Xfce +ENV DISPLAY=:1 +ENV VNC_RESOLUTION=1024x768 + +# Create directory for AppImage +RUN mkdir -p /test + +# Set working directory +WORKDIR /test + +# Expose VNC port +EXPOSE 5901 + +# Default command (can be overridden) +CMD ["/bin/bash"] + diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 00000000..43be778f --- /dev/null +++ b/tests/README.md @@ -0,0 +1,134 @@ +# Testing AppImage on CentOS 7 + +This directory contains a script to run the AppImage in a CentOS 7 container with GUI support, allowing you to verify it works correctly on CentOS 7. + +## Prerequisites + +- Docker installed and running +- For X11 forwarding mode: X server running on Linux host +- For VNC mode: VNC viewer client (for GUI access) + +## Quick Start + +1. **Build the AppImage first:** + ```bash + ./scripts/build_AppImage_docker.sh + ``` + +2. **Run the AppImage in CentOS 7 container with VNC (recommended):** + ```bash + ./tests/run_test_container.sh --vnc + ``` + +3. **Connect to the GUI:** + ```bash + vncviewer localhost:5901 + ``` + Password: `password` + +4. **Or use X11 forwarding (Linux hosts only):** + ```bash + ./tests/run_test_container.sh --x11 + ``` + The AppImage GUI will appear in your X server window. + +## Usage Modes + +### VNC Mode (Default) + +VNC mode works on all platforms. It starts a VNC server inside the container that you can connect to from your host machine. + +**Usage:** +```bash +./tests/run_test_container.sh --vnc +``` + +**Connecting to the GUI:** +1. Install a VNC viewer if you don't have one: + - **Linux:** `sudo apt install tigervnc-viewer` or `sudo apt install remmina` + - **macOS:** Download from [RealVNC](https://www.realvnc.com/download/viewer/) or use built-in Screen Sharing + - **Windows:** Download [TigerVNC](https://tigervnc.org/) or [RealVNC Viewer](https://www.realvnc.com/download/viewer/) + +2. Connect to `localhost:5901` + - Password: `password` + +3. Or use command line: + ```bash + vncviewer localhost:5901 + ``` + +**Container Management:** +- View logs: `docker logs -f rclone-browser-test` +- Get a shell: `docker exec -it rclone-browser-test /bin/bash` +- Stop container: `docker stop rclone-browser-test` + +### X11 Forwarding Mode + +X11 forwarding allows the AppImage GUI to appear directly in your X server window. This only works on Linux hosts with an X server running. + +**Usage:** +```bash +./tests/run_test_container.sh --x11 +``` + +**Requirements:** +- X server running on host (most Linux desktop environments have this) +- X11 socket accessible at `/tmp/.X11-unix/X0` +- The script will automatically run `xhost +local:docker` to allow Docker access + +**Note:** If you get permission errors, you may need to run: +```bash +xhost +local:docker +``` + +## What It Does + +The script: +1. Finds your freshly built AppImage in the `release/` directory +2. Builds a CentOS 7 Docker image with desktop environment (Xfce) and VNC server +3. Starts a container with the AppImage mounted +4. Launches the AppImage automatically +5. Provides you with connection instructions to see the GUI + +The AppImage runs in a CentOS 7 environment (glibc 2.17), so you can verify it works correctly on CentOS 7+ and Ubuntu 16.04+ systems. + +## Troubleshooting + +### "No AppImage found" error +- Make sure you've built the AppImage first: `./scripts/build_AppImage_docker.sh` +- Check that the AppImage exists in `release/` directory + +### VNC connection refused +- Make sure the container is still running: `docker ps` +- Check if port 5901 is already in use: `netstat -an | grep 5901` +- Try a different port by modifying the script + +### X11 forwarding not working +- Verify X server is running: `echo $DISPLAY` +- Check X11 socket exists: `ls -l /tmp/.X11-unix/X0` +- Try VNC mode instead, which is more reliable + +### Container permissions issues +- You may need to use `sudo` with Docker commands +- Or add your user to the `docker` group: `sudo usermod -aG docker $USER` (requires logout/login) + +## Files + +- `Dockerfile.test` - Docker image definition for CentOS 7 test environment +- `run_test_container.sh` - Script to build and run the container with GUI support +- `Vagrantfile` - Optional Vagrant setup for VM-based testing (see below) + +## Optional: VM Testing with Vagrant + +For more comprehensive testing, you can use Vagrant to spin up a full CentOS 7 VM: + +1. Install Vagrant: https://www.vagrantup.com/downloads +2. Start the VM: + ```bash + cd tests + vagrant up + ``` +3. Connect via VNC or SSH +4. Copy AppImage to VM and test + +See `Vagrantfile` for details. diff --git a/tests/Vagrantfile b/tests/Vagrantfile new file mode 100644 index 00000000..f6701003 --- /dev/null +++ b/tests/Vagrantfile @@ -0,0 +1,143 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +# Vagrantfile for testing RcloneBrowser AppImage on CentOS 7 +# This creates a CentOS 7 VM with desktop environment for GUI testing + +Vagrant.configure("2") do |config| + # Use CentOS 7 box + config.vm.box = "centos/7" + + # VM configuration + config.vm.provider "virtualbox" do |vb| + # VM resources + vb.memory = "2048" + vb.cpus = 2 + vb.name = "rclone-browser-test-centos7" + + # Enable GUI (for VirtualBox) + vb.gui = true + end + + # Network configuration + # Forward VNC port for remote access + config.vm.network "forwarded_port", guest: 5901, host: 5901, auto_correct: true + + # Shared folder for AppImage + config.vm.synced_folder "../release", "/vagrant/release", type: "rsync", + rsync__exclude: [".git/", "build/", "*.o", "*.a"] + + # Provisioning script + config.vm.provision "shell", inline: <<-SHELL + # Update system + yum update -y + + # Install EPEL repository + yum install -y epel-release + + # Install desktop environment (Xfce - lightweight) + yum groupinstall -y "Xfce" + + # Install VNC server + yum install -y tigervnc-server + + # Install FUSE (required for AppImage) + yum install -y fuse + + # Install other useful tools + yum install -y wget curl vim firefox + + # Set up VNC server for root + mkdir -p /root/.vnc + echo "password" | vncpasswd -f > /root/.vnc/passwd + chmod 600 /root/.vnc/passwd + + # Create VNC startup script + cat > /root/.vnc/xstartup << 'EOF' +#!/bin/bash +unset SESSION_MANAGER +unset DBUS_SESSION_BUS_ADDRESS +exec /etc/X11/xinit/xinitrc +[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup +[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources +xsetroot -solid grey +vncconfig -iconic & +startxfce4 & +EOF + chmod +x /root/.vnc/xstartup + + # Create systemd service for VNC (optional) + cat > /etc/systemd/system/vncserver@:1.service << 'EOF' +[Unit] +Description=Remote desktop service (VNC) +After=syslog.target network.target + +[Service] +Type=forking +User=root +ExecStartPre=/bin/sh -c '/usr/bin/vncserver -kill :1 > /dev/null 2>&1 || :' +ExecStart=/usr/bin/vncserver :1 -geometry 1024x768 -depth 24 +ExecStop=/usr/bin/vncserver -kill :1 + +[Install] +WantedBy=multi-user.target +EOF + + # Enable VNC service (optional - can start manually) + # systemctl daemon-reload + # systemctl enable vncserver@:1.service + + # Create test directory + mkdir -p /test + + # Copy AppImage if it exists + if [ -f /vagrant/release/*.AppImage ]; then + cp /vagrant/release/*.AppImage /test/ + chmod +x /test/*.AppImage + echo "AppImage copied to /test/" + else + echo "Warning: No AppImage found in release/ directory" + echo "Build the AppImage first, then run: vagrant rsync" + fi + + echo "" + echo "=== CentOS 7 Test VM Ready ===" + echo "" + echo "To start VNC server manually:" + echo " vncserver :1" + echo "" + echo "To connect from host:" + echo " vncviewer localhost:5901" + echo " Password: password" + echo "" + echo "AppImage location: /test/" + echo "" + SHELL + + # Post-up message + config.vm.post_up_message = <<-MESSAGE +=== CentOS 7 Test VM is Ready === + +The VM is now running. You can: + +1. Connect via SSH: + vagrant ssh + +2. Start VNC server (inside VM): + vagrant ssh -c "vncserver :1" + +3. Connect via VNC from host: + vncviewer localhost:5901 + Password: password + +4. Test the AppImage: + vagrant ssh -c "cd /test && ./rclone-browser-*.AppImage" + +5. Copy updated AppImage to VM: + vagrant rsync + +To stop the VM: vagrant halt +To destroy the VM: vagrant destroy +MESSAGE +end + diff --git a/tests/run_test_container.sh b/tests/run_test_container.sh new file mode 100755 index 00000000..03a63d5f --- /dev/null +++ b/tests/run_test_container.sh @@ -0,0 +1,302 @@ +#!/bin/bash + +# Script to run the AppImage in a CentOS 7 container with GUI support +# This spins up a container with the freshly built AppImage and presents it to the developer + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" +DOCKERFILE="$SCRIPT_DIR/Dockerfile.test" +IMAGE_NAME="rclone-browser-test-centos7" +CONTAINER_NAME="rclone-browser-test" + +# Default mode - prefer X11 to avoid VNC dialog issues +# Check if X11 is available (check for any X socket, not just X0) +if [ -n "$DISPLAY" ] && ls /tmp/.X11-unix/X* >/dev/null 2>&1; then + MODE="x11" +else + # If X11 not available, warn user about VNC dialog issues + MODE="vnc" +fi + +# Parse arguments +while [[ $# -gt 0 ]]; do + case $1 in + --x11) + MODE="x11" + shift + ;; + --vnc) + MODE="vnc" + shift + ;; + --help|-h) + echo "Usage: $0 [--x11|--vnc]" + echo "" + echo "Spins up a CentOS 7 container with the AppImage and presents the GUI." + echo "" + echo "Options:" + echo " --x11 Use X11 forwarding (Linux hosts only, recommended - no dialogs!)" + echo " --vnc Use VNC server (works on all platforms, but may have dialog issues)" + echo " --help Show this help message" + echo "" + echo "Note: X11 mode is recommended on Linux as it avoids VNC viewer dialog issues." + exit 0 + ;; + *) + echo "Unknown option: $1" + echo "Use --help for usage information" + exit 1 + ;; + esac +done + +# Check if Docker is available +if ! command -v docker >/dev/null 2>&1; then + echo "Error: Docker is not installed or not in PATH" + echo "Please install Docker to use this script" + exit 1 +fi + +# Check if we can run Docker (might need sudo) +DOCKER_CMD="docker" +if ! docker info >/dev/null 2>&1; then + if sudo docker info >/dev/null 2>&1; then + DOCKER_CMD="sudo docker" + echo "Note: Using sudo for Docker commands" + else + echo "Error: Cannot access Docker. Please ensure Docker is running and you have permissions" + exit 1 + fi +fi + +# Check if AppImage exists +APPIMAGE=$(find "$ROOT_DIR/release" -name "*.AppImage" -type f 2>/dev/null | head -n 1) +if [ -z "$APPIMAGE" ]; then + echo "Error: No AppImage found in $ROOT_DIR/release/" + echo "Please build the AppImage first using: ./scripts/build_AppImage_docker.sh" + exit 1 +fi + +echo "Found AppImage: $(basename "$APPIMAGE")" + +# Build Docker image +echo "Building test container image..." +$DOCKER_CMD build -f "$DOCKERFILE" -t "$IMAGE_NAME" "$SCRIPT_DIR" >/dev/null 2>&1 || { + echo "Building test container image (this may take a few minutes)..." + $DOCKER_CMD build -f "$DOCKERFILE" -t "$IMAGE_NAME" "$SCRIPT_DIR" +} + +# Stop and remove existing container if it exists +if $DOCKER_CMD ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then + echo "Removing existing container..." + $DOCKER_CMD rm -f "$CONTAINER_NAME" >/dev/null 2>&1 || true +fi + +# Prepare Docker run command +DOCKER_RUN_ARGS=( + --rm + --name "$CONTAINER_NAME" + --cap-add SYS_ADMIN + --device /dev/fuse + -v "$APPIMAGE:/test/$(basename "$APPIMAGE"):ro" +) + +# Mount rclone config from host if it exists +HOST_RCLONE_CONFIG="${HOME}/.config/rclone" +if [ -d "$HOST_RCLONE_CONFIG" ] || [ -f "$HOST_RCLONE_CONFIG/rclone.conf" ]; then + # Mount the entire rclone config directory so the config file and any cached tokens are available + DOCKER_RUN_ARGS+=(-v "$HOST_RCLONE_CONFIG:/root/.config/rclone:ro") + echo "Mounting rclone config from host: $HOST_RCLONE_CONFIG" +else + echo "Note: No rclone config found at $HOST_RCLONE_CONFIG (you can configure rclone in the GUI)" +fi + +# AppImage name for use in container +APPIMAGE_NAME=$(basename "$APPIMAGE") + +if [ "$MODE" = "x11" ]; then + # X11 forwarding mode + if [ -z "$DISPLAY" ] || ! ls /tmp/.X11-unix/X* >/dev/null 2>&1; then + echo "Error: X11 not available" + echo "X11 forwarding requires an X server to be running and DISPLAY to be set" + echo "Try using --vnc mode instead, or start an X server" + exit 1 + fi + + # Extract display number from DISPLAY (e.g., :1 -> X1, :0 -> X0) + DISPLAY_NUM=$(echo "$DISPLAY" | sed 's/.*:\([0-9]*\).*/\1/') + X_SOCKET="/tmp/.X11-unix/X${DISPLAY_NUM}" + + if [ ! -S "$X_SOCKET" ]; then + echo "Warning: X11 socket $X_SOCKET not found, but will try anyway" + fi + + # Allow X11 connections from Docker + xhost +local:docker 2>/dev/null || echo "Warning: Could not run 'xhost +local:docker'. You may need to run this manually." + + DOCKER_RUN_ARGS+=( + -e DISPLAY="$DISPLAY" + -v /tmp/.X11-unix:/tmp/.X11-unix:rw + ) + + echo "" + echo "=== Starting container with X11 forwarding ===" + echo "The AppImage GUI should appear in your X server window" + echo "" + + # Run container with X11 forwarding + $DOCKER_CMD run -it "${DOCKER_RUN_ARGS[@]}" \ + "$IMAGE_NAME" \ + /bin/bash -c " + export DISPLAY=$DISPLAY + cd /test + # Copy AppImage to writable location and make it executable + cp '$APPIMAGE_NAME' appimage_copy + chmod +x appimage_copy + echo 'Starting AppImage...' + ./appimage_copy & + echo '' + echo 'AppImage started in background.' + echo 'You can also run it manually: ./appimage_copy' + echo 'Press Ctrl+C to exit the container' + /bin/bash + " + + # Restore X11 access control + xhost -local:docker 2>/dev/null || true + +elif [ "$MODE" = "vnc" ]; then + # VNC mode + VNC_PORT=5901 + + # Check if X11 is available and recommend it + if [ -n "$DISPLAY" ] && ls /tmp/.X11-unix/X* >/dev/null 2>&1; then + echo "" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo " ⚠️ RECOMMENDATION: Use X11 forwarding instead!" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo " X11 forwarding avoids VNC viewer dialog issues." + echo " To use X11 mode, stop this and run:" + echo " $0 --x11" + echo "" + echo " Continuing with VNC mode (you may encounter dialog issues)..." + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "" + sleep 2 + fi + + DOCKER_RUN_ARGS+=( + -p "$VNC_PORT:5901" + -e DISPLAY=:1 + ) + + echo "" + echo "=== Starting container with VNC server ===" + echo "" + + # Run container with VNC + $DOCKER_CMD run -d "${DOCKER_RUN_ARGS[@]}" \ + "$IMAGE_NAME" \ + /bin/bash -c " + # Start VNC server + vncserver :1 -geometry 1024x768 -depth 24 + sleep 5 + + # Wait for Xfce to fully start + export DISPLAY=:1 + for i in {1..30}; do + if xdpyinfo >/dev/null 2>&1; then + break + fi + sleep 1 + done + + # Copy AppImage to writable location and make it executable + cd /test + cp '$(basename "$APPIMAGE")' appimage_copy + chmod +x appimage_copy + + # Start AppImage in the VNC session + sleep 2 + ./appimage_copy >/tmp/appimage.log 2>&1 & + + echo 'AppImage started in VNC session' + echo '' + echo '=== VNC Server Running ===' + echo 'Connect with: vncviewer localhost:$VNC_PORT' + echo 'Password: password' + echo '' + echo 'Container is running in background.' + echo 'To stop: docker stop $CONTAINER_NAME' + echo 'To view logs: docker logs -f $CONTAINER_NAME' + echo 'To get a shell: docker exec -it $CONTAINER_NAME /bin/bash' + + # Keep container running + tail -f /dev/null + " >/dev/null + + echo "Container started!" + echo "" + + # Wait a moment for VNC server to be ready + sleep 3 + + # Show connection info and try to auto-launch Remmina + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo " VNC Connection Ready" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo " Address: localhost:$VNC_PORT" + echo " Password: password" + echo "" + + # Try to auto-launch Remmina if available + if command -v remmina >/dev/null 2>&1; then + echo " Auto-launching Remmina..." + remmina -c vnc://:password@localhost:$VNC_PORT >/dev/null 2>&1 & + sleep 2 + echo " Remmina launched (if it didn't open, try manually)" + echo "" + fi + + echo " Connect using one of these methods:" + echo "" + + # Detect available viewers and show appropriate command + if command -v vncviewer >/dev/null 2>&1; then + echo " Option 1:" + echo " vncviewer localhost:$VNC_PORT" + echo "" + fi + + if command -v tigervnc-viewer >/dev/null 2>&1; then + echo " Option 2:" + echo " tigervnc-viewer localhost:$VNC_PORT" + echo "" + fi + + if [ -d "/Applications" ]; then + echo " Option 3 (macOS):" + echo " open vnc://localhost:$VNC_PORT" + echo "" + fi + + echo " Or use any VNC viewer and connect to: localhost:$VNC_PORT" + echo "" + echo " After connecting, you should see the Xfce desktop with the AppImage running." + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "" + + echo "Container management:" + echo " Stop: $DOCKER_CMD stop $CONTAINER_NAME" + echo " Logs: $DOCKER_CMD logs -f $CONTAINER_NAME" + echo " Shell: $DOCKER_CMD exec -it $CONTAINER_NAME /bin/bash" + echo "" + echo "Press Ctrl+C to stop the container when done." + + # Keep script running so container stays alive + # Wait for container to stop or user interrupt + trap "echo ''; echo 'Stopping container...'; $DOCKER_CMD stop $CONTAINER_NAME >/dev/null 2>&1; exit 0" INT TERM + $DOCKER_CMD wait $CONTAINER_NAME >/dev/null 2>&1 || wait +fi