From a65746c5272d90dc479cf3cd013c906cf6fe904a Mon Sep 17 00:00:00 2001 From: Marcus Lagergren <1062473+lagergren@users.noreply.github.com> Date: Sun, 10 Dec 2023 15:49:16 +0100 Subject: [PATCH 01/13] Ported the Platform repository to use the XTC Plugin, internal version 0.4.44, as published on the GitHub Org XVM Maven Package Repository. --- .gitignore | 47 ++++++-- Dockerfile | 2 +- README.md | 213 ++++++++++++++++++++++++++--------- bin/stop-server.sh | 3 + build.gradle.kts | 173 ++++++++++++++++++++++++---- common/build.gradle.kts | 25 +--- gradle.properties | 25 ++++ gradle/libs.versions.toml | 27 +++++ host/build.gradle.kts | 33 ++---- kernel/build.gradle.kts | 35 ++---- kernel/src/main/x/kernel.x | 12 +- platformDB/build.gradle.kts | 35 ++---- platformUI/build.gradle.kts | 177 +++++++++++++++++++++-------- platformUI/gradle.properties | 1 + platformUI/gui/.gitignore | 2 +- platformUI/gui/.npmrc | 2 +- platformUI/gui/package.json | 3 +- platformUI/gui/src/App.vue | 2 +- settings.gradle.kts | 135 +++++++++++++++++++++- settings.gradle.local.kts | 67 +++++++++++ 20 files changed, 777 insertions(+), 242 deletions(-) create mode 100755 bin/stop-server.sh create mode 100644 gradle.properties create mode 100644 gradle/libs.versions.toml create mode 100644 platformUI/gradle.properties create mode 100644 settings.gradle.local.kts diff --git a/.gitignore b/.gitignore index e1c5f79..fcdeab2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ -# Logs and databases # -###################### +# +# Logs and databases +# *.log *.out *.tmp @@ -7,8 +8,9 @@ *.sql *.sqlite +# # OS generated files # -###################### +# .DS_Store .DS_Store? ._* @@ -17,20 +19,41 @@ ehthumbs.db Thumbs.db -# build directory # -################### +# +# Build directories +# build/ + +# +# Module aggregation directory: +# +# While we can still collect everyting into a common lib folder, as a final build step, +# if we want, the 'standard' Maven style way would be to just build and run the project. +# Every component declaratively states its dependencies to build and/or run, and any +# task using these dependencies gets them lazily resolved, and exactly what it needs, +# nothing more. We will likely implement a distribution config for XTC applications +# like this, of course, so that the old "lib" folder is some kind of versioned +# publishable artifact) +# lib/ -# xdk directory # -################### +# +# XDK directory +# xdk/ -# user-specific project files # -############################### +# +# User-specific project files +# prj/ .idea/ -# Gradle-specific project files # -################################# -.gradle \ No newline at end of file +# +# Gradle caches +# +.gradle + +# +# Local environment fike for docker/docker compose that may contain secrets +# +.env.local diff --git a/Dockerfile b/Dockerfile index ca75cbc..49aa712 100644 --- a/Dockerfile +++ b/Dockerfile @@ -49,4 +49,4 @@ RUN mkdir -p ~/xqiz.it/platform \ && cd ~/xtc_platform && ~/xvm/gradlew build WORKDIR /root/xtc_platform -CMD ["xec", "-L", "lib/", "lib/kernel.xtc", "qwerty"] \ No newline at end of file +CMD ["xec", "-L", "lib/", "lib/kernel.xtc", "qwerty"] diff --git a/README.md b/README.md index 13ab2d3..3a10afa 100644 --- a/README.md +++ b/README.md @@ -1,101 +1,208 @@ -# Platform as a Service # +# Platform as a Service This is the public repository for the open source Ecstasy PaaS project, sponsored by [xqiz.it](http://xqiz.it). -## Status: - -This project is being actively developed, but is not yet considered a production-ready release. - ## Layout The project is organized as a number of sub-projects, with the important ones to know about being: -* The *common* library (`./common`), contains common interfaces shared across platform modules. - -* The *kernel* library (`./kernel`), contains the boot-strapping functionality. It's responsible for starting system services and introducing them to each other. - -* The *host* library (`./host`), contains the manager for hosted applications. +* The *common* library ([platform/common](./common)), contains common interfaces shared across platform modules. + +* The *kernel* library ([platform/kernel](./kernel)), contains the boot-strapping functionality. It's responsible for + starting system services and introducing them to each other. + +* The *host* library ([platform/host](./host)), contains the manager for hosted applications. -* The *platformDB* library (`./platformDB`), contains the platform database. +* The *platformDB* library ([platform/platformDB](./platformDB)), contains the platform database. + +* The *platformUI* library ([platform/platformUI](./platformUI)), contains the end-points for the platform + web-application. -* The *platformUI* library (`./platformUI`), contains the end-points for the platform web-application. - ## Installation 1. Please follow steps 1-3 of the [XDK Installation](https://github.com/xtclang/xvm#installation). -2. Clone [the platform repository](https://github.com/xtclang/platform) to your local machine. For purposes of this document, we will assume that the project directory is `~/Development/platform/`, but you may use whatever location makes sense for your environment. +2. Clone [the platform repository](https://github.com/xtclang/platform) to your local machine. ## Steps to test the PAAS functionality: -Note that steps 2 and 3 are temporary, and step 3 needs to be re-executed every time after an OS reboot. +### Provide properties named `gitHubUser` and `gitHubPassword` + +The platform expects to be able to read artifacts from the GitHub Maven Package Repository, +and requires credentials to do so. Later we will have this repo retrieve its artifacts from +gradlePluginPortal and mavenCentral. To understand how to set up these credentials, follow +the instructions in the [xtc-template-app](https://github.com/xtclang/xtc-app-template/blob/master/README.md) +and if you want to get more detail on this, take a look at the comment in the +[xtc-template-app settings](https://github.com/xtclang/xtc-app-template/blob/master/settings.gradle.kts) + +Hence, ensure that you have properties named "gitHubUser" and "gitHubToken" set up in your +environments, and that the token has read:package privileges for the GitHub Maven Repo. + +If you can build and run the [xtc-template-app](https://github.com/xtclang/xtc-app-template/tree/master), and +have that correctly configured, you can skip this step. -1. Create "xqiz.it" subdirectory under the user home directory for the platform persistent data. The subdirectory "platform" will be used to keep the platform operational information and subdirectory "users" for hosted applications. +### Create a local (or containerized) platform environment -2. Create a file "~/xqiz.it/platform/port-forwarding.conf" with the following content: +Note that steps 1 and 2 are temporary, and step 2 needs to be re-executed every time after an OS reboot. Steps 3-8 need +to be done just once. Or Dockerize and never have to think about this again. The platform should also be distributed +as a container/Dockerfile/docker in the near future, so that you won't have to do any of these manual steps. - rdr pass on lo0 inet proto tcp from any to self port 80 -> 127.0.0.1 port 8080 - rdr pass on lo0 inet proto tcp from any to self port 443 -> 127.0.0.1 port 8090 +1. Create `xqiz.it` subdirectory under the user home directory for the platform persistent data. The subdirectory " + platform" will be used to keep the platform operational information and subdirectory "users" for hosted applications. + +2. Create a file `~/xqiz.it/port-forwarding.conf` with the following content: + +``` + rdr pass on lo0 inet proto tcp from any to self port 80 -> 127.0.0.1 port 8080 + rdr pass on lo0 inet proto tcp from any to self port 443 -> 127.0.0.1 port 8090 +``` 3. Run the following command to redirect http and https traffic to unprivileged ports: - - sudo pfctl -evf ~/xqiz.it/platform/port-forwarding.conf + +``` + sudo pfctl -evf ~/xqiz.it/platform/port-forwarding.conf +``` 4. Make sure you can ping the local platform address: - - ping xtc-platform.localhost.xqiz.it - - The domain name `xtc-platform.localhost.xqiz.it` should resolve to `127.0.0.1`. This allows the same xqiz.it cloud-hosted platform to be self-hosted on the `localhost` loop-back address, enabling local and disconnected development. - If that address fails to resolve you may need to change the rules on you DNS server. For example, for Verizon routers you would need add an exception entry for "127.0.0.1" to your DNS Server settings: "Exceptions to DNS Rebind Protection" (Advanced - Network Settings - DNS Server) +``` + ping xtc-platform.localhost.xqiz.it +``` + + The domain name `xtc-platform.localhost.xqiz.it` should resolve to `127.0.0.1`. This allows the same xqiz.it + cloud-hosted platform to be self-hosted on the `localhost` loop-back address, enabling local and disconnected + development. + + If that address fails to resolve you may need to change the rules on you DNS server. For example, for Verizon routers + you would need add an exception entry for `127.0.0.1` to your DNS Server settings: "Exceptions to DNS Rebind + Protection" (Advanced - Network Settings - DNS Server) + +5. Create a self-signed certificate for the platform web server. For example: + +``` + keytool -genkeypair -alias platform -keyalg RSA -keysize 2048 -validity 365 -dname "OU=Platform, O=[your name], C=US" -keystore ~/xqiz.it/platform/certs.p12 -storetype PKCS12 -storepass [password] +``` + +6. Add a symmetric key to encode the cookies: + +``` + keytool -genseckey -alias cookies -keyalg AES -keysize 256 -keystore ~/xqiz.it/platform/certs.p12 -storetype PKCS12 -storepass [password] +``` + +7. If you want to run with an XDK installation and not just let the plugin sort it out, make sure you + have [xdk-latest](https://github.com/xtclang/xvm#readme) installed. + +8. Make sure you have a Java runtime installed for bootstrapping. It should really be enough with any + old Java, just so that you can run the Gradle wrapper. The Java toolchains support should download the + latest compatible JDK environment for you, to build and run the XTC Platform. + +9. Make sure that when you issue Gradle commands, you do it either through the Gradle wrapper script, or from + inside your IDE, that you are sure knows about your wrapper script. Any IDE in which you import this project + should pick that up and grab the appropriate runtimes and dependencies. + +``` + xec -L lib/ lib/kernel.xtc [password] +``` + +10. *It is recommended that you *do not* keep a Gradle executable on your system path to build the project, but + instead use the Gradle wrapper script (or its IDE integration) for every task you want to execute.* + +11. Build and run the server. + + You can provide the password for your keystore as a Gradle property, by adding a line on the form + `keystorePassword=` to the `$GRADLE_USER_HOME/gradle.properties`. This is + the customary way to add secrets outside source control. You can also place it in the environment + variable `ORG_GRADLE_PROJECT_password`, or send it as a Gradle property on the launcher line, like this: + + * Note: The password you choose during the very first run will be used to encrypt the platform key storage. + You will need the same password for all subsequent runs. If you do not provide a password, executing + the launcher through one of the two methods described in this paragraph, will prompt for the password + on `stdin`, which, while it works, is not compatible with scenarios like automatic CI/CD testing. + +Either build and run the server "the traditional way" (requires a local XDK installation) with: + +``` + ./gradlew build + xec --verbose -L ./build/platform/ kernel.xqiz.it +``` + +or with the experimental: + +``` + ./gradlew run -PkeystorePassword=` +``` -5. Make sure you have the latest [gradle](https://gradle.org/), [node](https://nodejs.org/en), [yarn](https://yarnpkg.com/) and [xdk-latest](https://github.com/xtclang/xvm#readme) installed. If you are using `brew`, you can simply say: - - brew install gradle node yarn +Note: the ./gradlew run task described in this paragraph is not meant as a production way of running +the platform. However, it can be quite handy to use for debugging purses, with "fork=false" in its +xtcRun configuraiton. That way you can just execute the run task from IntelliJ in Debug mode, and +just step into your executing platform server. -6. Change your directory to the `./platformUI/gui` directory inside the local git repo installed above. +TODO: ORG_GRADLE_PROJECT_keystorePassword= xec -L ./build/platform/ kernel - cd ~/Development/platform/platformUI/gui +12. Open the [locally hosted platform web page](https://xtc-platform.localhost.xqiz.it): -7. Make sure all necessary *node* modules are installed within that directory using the following command: + Note: Using the locally-created (self-signed) certificate from step 5 above, you will receive warnings from the + browser about the unverifiability of the website and its certificate. - npm install +13. Follow the instructions from the [Examples](https://github.com/xtclang/examples) repository to build and "upload" a web application. -8. If you plan to use `quasar` dev environment, please install it globally by the following command: +14. Log into the "Ecstasy Cloud" platform using the pre-defined test user "admin" and the password "password". - npm install -g @quasar/cli - -9. Build the platform services using the gradle command (from within the "platform" directory): +15. Go to the "Modules" panel and install any of the example module (e.g. "welcome.examples.org"). - cd ~/Development/platform/ - gradle clean build +16. Go to the "Application" panel, register a deployment (e.g. "welcome") and "start" it -10. Start the platform using the command (from within the "platform" directory): +17. Click on the URL to launch your application web page. - xec -L lib/ lib/kernel.xtc [password] +18. To stop the server cleanly, from a separate shell or process, run this command: - Note: The password you choose during the very first run will be used to encrypt the platform key storage. You will need the same password for all subsequent runs. +``` + curl -k -b cookies.txt -L -i -w '\n' -X POST https://xtc-platform.localhost.xqiz.it/host/shutdown +``` -11. Open the [locally hosted platform web page](https://xtc-platform.localhost.xqiz.it): +If you do not stop the server cleanly, the next start-up will be much slower, since the databases on the server will +need to be recovered. - https://xtc-platform.localhost.xqiz.it +### Third Part Installation Dependencies - Note: Using the locally-created (self-signed) certificate from step 5 above, you will receive warnings from the browser about the unverifiability of the website and its certificate. +Previously, to build and run, we required that NodeJS, NPM and Yarn were installed, and available in the +environment and PATH on the system where you execute the platform build and/or run. This is problematic +since you may have several different applications that you work on that require different versions of +the software. It's problematic to have to switch between different versions of an external software +installation, and there are even meta-frameworks like NVM to do that, but it adds complexity, and +it's hard to always detect that you are running the right version. -12. Follow the instructions from the [Examples](https://github.com/xtclang/examples) repository to build and "upload" a web application. +It is even more problematic if you have to install or configure the dependent software with root/admin +privileges, since this alters the global state of your development machine, perhaps breaking something +else you need to work on as well. -13. Log into the "Ecstasy Cloud" platform using the pre-defined test user "admin" and the password "password". +Luckily, this is 2024, and it's industry best practice to keep exactly versioned dependencies referenced +and resolvable inside the scope of a project. For those dependencies that still have to live as installed +system executables, we containerize. -14. Go to the "Modules" panel and install any of the example module (e.g. "welcome.examples.org"). +For the Platform, you don't need to install any additional software as long as you have a bootstrap +Java runtime for the Gradle wrapper. The Platform project will make sure that it downloads and uses +the correct and tested versions of its external dependencies. This includes NodeJS and all the other +things required to build the frontend. The build will always resolve and execute a specific version +of an artifact, without any need for configuration. The build will always override any system +installation of its dependencies with its own, of a known and tested version and configuration. -15. Go to the "Application" panel, register a deployment (e.g. "welcome") and "start" it +#### Quasar -16. Click on the URL to launch your application web page. +While the default behavior is to only install external software dependency at the XTC platform project repo +level, and in the system Gradle caches, e.g. under $GRADLE_USER_HOME/..., Quasar may still be installed by +the build as a "global" scope Node application. This should not be necessary for basic use cases, but since +previous XTC Platform repository supported this option, and we strive to preserve exact semantics of a +build or system, even when performing large changes, it is supported by the build, through the property: -17. To stop the server cleanly, from a separate shell run this command: +``` + org.lang.platform.quasarGlobal=[true|false] +``` - curl -k -b cookies.txt -L -i -w '\n' -X POST https://xtc-platform.localhost.xqiz.it/host/shutdown +If the property is not defined, it will default to "false". - If you do not stop the server cleanly, the next start-up will be much slower, since the databases on the server will need to be recovered. +As with all other Gradle properties, the installation mode for Quasar can be declared on the Gradle wrapper +command line, or in a gradle.properties file in the root of the repository, or under your GRADLE_USER_HOME +directory. ## License diff --git a/bin/stop-server.sh b/bin/stop-server.sh new file mode 100755 index 0000000..a44afb0 --- /dev/null +++ b/bin/stop-server.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +curl -k -b cookies.txt -L -i -w '\n' -X POST https://xtc-platform.localhost.xqiz.it/host/shutdown diff --git a/build.gradle.kts b/build.gradle.kts index 017bc6e..d4cbfdf 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,37 +1,162 @@ -/* +/** * Main build file for the "platform" project. */ +import org.xtclang.plugin.tasks.XtcCompileTask +import org.xtclang.plugin.tasks.XtcRunTask -group = "platform.xqiz.it" -version = "0.1.0" +/** + * Enable the XTC plugin, so that we can parse this build file. In the interest to avoid + * hardcoded artifact descriptors, and copy-and-paste for versions, we refer to the + * plugin aliases declared in "gradle/libs.versions.toml" + */ +plugins { + alias(libs.plugins.xtc) + alias(libs.plugins.tasktree) // for debugging purposes. +} + +/** + * Dependencies to other projects, configurations and artifacts. + * + * These are the dependencies to other projects, and to the XDK proper (versioned). We follow + * the Gradle Version Catalog standard for this project, and normally, when changing the version + * of any requested artifact or plugin, there should only be the need to change + * "gradle/libs.versions.toml" + */ +dependencies { + xdkDistribution(libs.xdk) + xtcModule(project(":kernel")) // main module to run. + xtcModule(project(":common")) // runtime library path + xtcModule(project(":host")) // runtime library path + xtcModule(project(":platformDB")) // runtime library path + xtcModule(project(":platformUI")) // runtime library path + xtcModule(project(":platformCLI")) // runtime library path +} + +// TODO: Automatically run a pre-pass to verify that the XTC init script is in place (until we are +// on Maven Central (and have a new XDK release from "master"that supports the XTC Plugin). -val libDir = "${projectDir}/lib" +/** + * Lazy password resolution provider. + * + * The password must support both: + * + * 1) Entering it on stdin when the platform kernel is getting started. + * 2) Retrieve it from the environment as described below, or through + * similar methods. SUPPORTING THIS USE CASE IS ABSOLUTELY NECESSARY + * FOR AUTOMATIC CI/CD INTEGRATION (e.g. with GitLab/GitHub/TeamCity + * or other industrial strength integration testing frameworks.) + * + * Read the password. Typically, the password is either placed as a Gradle property + * with the key "keystorePassword" in an external gradle.properties or init + * file outside the project repository. The most common choice is + * $GRADLE_USER_HOME/.gradle.properties, which generally contains secrets. + * + * You can also send values as project properties for the root project by using the + * "-P" switch on the Gradle command line, like so: + * "./gradlew run -PkeystorePassword=Uhlers0th" + * + * If you do not provide a password, i.e., defining that property from the command line + * or a "*.properties" file, the XTC Platform will ask the user to input the password + * from stdin. The default behavior if this happens from Gradle, is to show stdin from + * the Gradle run process to the user and allow inputs there. (Or from the actual + * execution command line, of course, if you do it manually). + */ -tasks.register("clean") { - group = "Build" - description = "Delete previous build results" - delete(libDir) +internal val passwordProvider: Provider = provider { + logger.lifecycle("Resolving password for XTC platform...") + findProperty("keystorePassword")?.toString() ?: "" } -val build = tasks.register("build") { - group = "Build" - description = "Build all" +/** + * Gather all compiled XTC modules from subprojects into a single location: $rootProject/build/platform. + */ +val commonXtcOutputDir = layout.buildDirectory.dir("platform") - dependsOn(project(":kernel") .tasks["build"]) - dependsOn(project(":host") .tasks["build"]) - dependsOn(project(":platformDB") .tasks["build"]) - dependsOn(project(":platformUI") .tasks["build"]) - dependsOn(project(":platformCLI").tasks["build"]) +allprojects { + tasks.withType().configureEach { + doLast { + copy { + from(outputs.files.asFileTree) + into(commonXtcOutputDir) + } + } + } } -tasks.register("run") { - group = "Run" - description = "Run the platform" +/** + * This is the run configuration, which configures all xtcRun taks for the main source set. (runXtc, runAllXtc) + * The DSL for modules to run is a list of "module { }" elements or a list of moduleName("...") statements. + * To look at the DSL for all parts of the XTC build, you can use your IDE and browse the implementing + * classes. For example, there should be a hint in IntelliJ with the type for the xtcRun element and + * the modules element (DefaultXtcRuntimeExtension and XtcRuntimeExtension.XtcRunModule, respectively). + * It is a good way to understand how the build DSL works, so you can add your own powerful XTC build + * syntax constructs and nice syntactic sugar/shorthand for things you feel should be simpler to write. + */ +xtcRun { + verbose = true + //fork = false + stdin = System.`in` // Prevent Gradle from eating stdin; make it interactive with the Gradle process that executes the kernel. + module { + moduleName = "kernel" + findProperty("keystorePassword")?.also { + moduleArg(it.toString()) + } + } +} - dependsOn(build) +/** + * Run the XTC Platform. Note that this is a Gradle job, and as such gets is dependencies from the module path + * in the Gradle plugin for all source in the project. It will use a module path precisely including + * the correct dependencies. + * + * PLEASE Read the rest of this comment if you are interested how we can best model the architectural + * support for the XTC Platform, and why. + * + * This is very neat, but of course we don't want to start a Gradle task to run the platform, as the task + * never completes, given the standard operation. Thus, the more kludgy solution if you want to run the + * project is the "classic" use-a-commandline-method. + * + * To derive a working command line, you can execute "./gradlew run --info" and look for "JavaExec" in the log. + * Or you can do "XTC_PLUGIN_VERBOSE_PROPERTY=true ./gradlew run" for less info. + * + * Ongoing XTC Plugin improvements (TODO): + * + * 1) The ability to retrieve a complete self-contained command line from the XTCPlugin launcher tasks instead + * of having to scrape logs. + * + * 2) The ability explicitly ask the plugin for that command line, or at least programmatically represent + * it as part of an output configuration for the task. + * + * 2) Implement an XtcChildProcessLauncher that inherits the XtcLauncher interface. This would use the Java + * process builder to spawn the platform in the background instead of with JavaExec. That would give us + * 2.1) A state where Gradle finishes and exists after the run task (and any cleanups after that), but + * leaves the platform running in the background. + * 2.2) Still custom input and output stream configuration, so the log is not lost, and we get + * interactive mode with the created child process by just "foregrounding" it, when we need to. + * + * Typically, these improvements make sense, as they follow the law of least astonishment for Docker Compose. + * The user would typically do "./gradlew build" (or install/distribution or any other bundling tasks + * that is required in the environment), followed by a "./gradlew up". This starts the platform in the background + * and the Gradle process goes away. To take the server down, we can execute "./gradlew down". + * + * 3) Touch op the existing Dockerfile, add a docker-compose.yaml, and provide the build and run + * semantics with docker-compose. Here we both have the avantage that we don't need to set up + * various things on our local machine, remember to run some "sudo" command very reboot, and so on. + * For the equivalent of ~/xqiz.it, it's trivial to add that very directory as a Docker volume + * in the compose script, or even better create a docker volume, that can be reused, closed, moved, + * suspended, aggregated with the Example apps in one virtual environment, and so on. This will + * be fundamental both for devleoping "examples" and other XTC platform applications, as well as + * the platform itself. + */ +tasks.withType().configureEach { + verbose = true +} - doLast { - println("Please run the platform directly using the following command:") - println(" xec -L lib/ kernel.xtc [password]") +val run by tasks.registering { + group = "application" + description = "Build (if necessary) and run the platform (equivalent to 'xec [-L ]+ kernel.xtc )" + dependsOn(tasks.runXtc) + doFirst { + logger.lifecycle("Starting the XTC platform (kernel).") } -} \ No newline at end of file +} diff --git a/common/build.gradle.kts b/common/build.gradle.kts index d9aa2d8..35a04a6 100644 --- a/common/build.gradle.kts +++ b/common/build.gradle.kts @@ -2,23 +2,10 @@ * Build the "common" module. */ -val libDir = "${rootProject.projectDir}/lib" +plugins { + alias(libs.plugins.xtc) +} -tasks.register("build") { - group = "Build" - description = "Build this module" - - val src = fileTree("${projectDir}/src").files.stream(). - mapToLong{f -> f.lastModified()}.max().orElse(0) - val dst = file("$libDir/common.xtc").lastModified() - - if (src > dst) { - val srcModule = "${projectDir}/src/main/x/common.x" - - project.exec { - commandLine("xcc", "--verbose", - "-o", libDir, - srcModule) - } - } -} \ No newline at end of file +dependencies { + xdkDistribution(libs.xdk) +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..6441254 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,25 @@ +# Common properties for the build. + +group=platform.xqiz.it +version=1.0.0 + +org.gradle.parallel=true +org.gradle.caching=true + +# NOTE: See the comment about this property in the sibling file "build.gradle.kts". In a production system, +# this password would of course be stored outside the project, and never ever checked into source control. +# This declaration is just for demo purposes and to support headless test environments like GitHub Runners. +# However, it does contribute to dev process efficiency as well, by verifying that password input +#keystorePassword=password + +gitHubUrl=https://maven.pkg.github.com/xtclang/xvm + +# This is a secret, but for testing, this shows you can define it either here, outside the repository, +# or by using properties or system environment variables, following the correct convention. + +# These are secrets and should be defined outside the repository +#gitHubUser= +#gitHubToken= + +mavenLocalOnly=true +#gitHubOnly=true diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 0000000..1196df9 --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,27 @@ +# +# This is the only file in the project where we keep version information and artifact +# names for our plugins and dependencies. +# + +[versions] +xdk = "0.4.43" + +gradle-node = "7.0.1" +node = "20.10.0" +npm = "10.4.0" +yarn = "1.22.21" +tasktree = "2.1.1" + +[plugins] +xtc = { id = "org.xtclang.xtc-plugin", version.ref = "xdk" } +node = { id = "com.github.node-gradle.node", version.ref = "gradle-node" } + +# taskTree is a helper that we can use to view task dependencies +# for example: ./gradlew run taskTree, or ./gradle run taskTree --with-inputs --with-outputs +tasktree = { id = "com.dorongold.task-tree", version.ref = "tasktree" } + +[libraries] +xdk = { group = "org.xtclang", name = "xdk", version.ref = "xdk" } + +[bundles] +# No bundles so far diff --git a/host/build.gradle.kts b/host/build.gradle.kts index b2b1452..5e599fe 100644 --- a/host/build.gradle.kts +++ b/host/build.gradle.kts @@ -2,28 +2,15 @@ * Build the host module. */ -val libDir = "${rootProject.projectDir}/lib" +plugins { + alias(libs.plugins.xtc) +} -tasks.register("build") { - group = "Build" - description = "Build this module" +xtcCompile { + verbose = true +} - dependsOn(project(":common").tasks["build"]) - - doLast { - val src = fileTree("${projectDir}/src").files.stream(). - mapToLong{f -> f.lastModified()}.max().orElse(0) - val dst = file("$libDir/host.xtc").lastModified() - - if (src > dst) { - val srcModule = "${projectDir}/src/main/x/host.x" - - project.exec { - commandLine("xcc", "--verbose", - "-o", libDir, - "-L", libDir, - srcModule) - } - } - } -} \ No newline at end of file +dependencies { + xdkDistribution(libs.xdk) + xtcModule(project(":common")) +} diff --git a/kernel/build.gradle.kts b/kernel/build.gradle.kts index 0c761d9..a909c07 100644 --- a/kernel/build.gradle.kts +++ b/kernel/build.gradle.kts @@ -2,29 +2,12 @@ * Build the "kernel" module. */ -val libDir = "${rootProject.projectDir}/lib" - -tasks.register("build") { - group = "Build" - description = "Build this module" - - dependsOn(project(":common") .tasks["build"]) - dependsOn(project(":platformDB") .tasks["build"]) - - doLast { - val src = fileTree("${projectDir}/src").files.stream(). - mapToLong{f -> f.lastModified()}.max().orElse(0) - val dst = file("$libDir/kernel.xtc").lastModified() - - if (src > dst) { - val srcModule = "${projectDir}/src/main/x/kernel.x" - - project.exec { - commandLine("xcc", "--verbose", - "-o", libDir, - "-L", libDir, - srcModule) - } - } - } -} \ No newline at end of file +plugins { + alias(libs.plugins.xtc) +} + +dependencies { + xdkDistribution(libs.xdk) + xtcModule(project(":common")) + xtcModule(project(":platformDB")) +} diff --git a/kernel/src/main/x/kernel.x b/kernel/src/main/x/kernel.x index 87a3564..4b4db61 100644 --- a/kernel/src/main/x/kernel.x +++ b/kernel/src/main/x/kernel.x @@ -59,9 +59,13 @@ module kernel.xqiz.it { @Inject ModuleRepository repository; // get the password - String password = args.size == 0 - ? console.readLine("Enter password:", suppressEcho=True) - : args[0]; + String password = ""; + if (password.size == 0) { + console.print("Enter password:"); + password = console.readLine(suppressEcho=True); + } else { + password = args[0]; + } // ensure necessary directories Directory platformDir = homeDir.dirFor("xqiz.it/platform").ensure(); @@ -192,4 +196,4 @@ module kernel.xqiz.it { errors.reportAll(msg -> console.print(msg)); } } -} \ No newline at end of file +} diff --git a/platformDB/build.gradle.kts b/platformDB/build.gradle.kts index 19a2c28..649763e 100644 --- a/platformDB/build.gradle.kts +++ b/platformDB/build.gradle.kts @@ -1,29 +1,12 @@ -/* - * Build the platformDB module. +/** + * The platform database subproject. */ -val libDir = "${rootProject.projectDir}/lib" +plugins { + alias(libs.plugins.xtc) +} -tasks.register("build") { - group = "Build" - description = "Build this module" - - dependsOn(project(":common").tasks["build"]) - - doLast { - val src = fileTree("${projectDir}/src").files.stream(). - mapToLong{f -> f.lastModified()}.max().orElse(0) - val dst = file("$libDir/platformDB.xtc").lastModified() - - if (src > dst) { - val srcModule = "${projectDir}/src/main/x/platformDB.x" - - project.exec { - commandLine("xcc", "--verbose", - "-o", libDir, - "-L", libDir, - srcModule) - } - } - } -} \ No newline at end of file +dependencies { + xdkDistribution(libs.xdk) + xtcModule(project(":common")) +} diff --git a/platformUI/build.gradle.kts b/platformUI/build.gradle.kts index defb80d..9ad06af 100644 --- a/platformUI/build.gradle.kts +++ b/platformUI/build.gradle.kts @@ -1,68 +1,157 @@ -/* - * Build the "platformUI" module. +/** + * The platform UI subproject. This relies on npm and yarn for building the web + * UI. We plug the node builder and the quasar runner into the Gradle lifecycle, + * so that we don't need to rebuild the non-XTC parts of the webapp unless something + * has explicitly changed. + * + * We also use the version catalog to resolve the name and version of the popular + * third party Node plugin for Gradle. + * + * This project used to be buildable both with Npm and Yarn, but due to time + * constraints, reimplementing the Npm functionality is in the backlog. The user + * should not need to care anymore, however, because the build system takes care + * of setting up the web app frameworks, and make sure they interact correctly + * with the rest of the Gradle build lifecycle. */ -val common = project(":common") +import com.github.gradle.node.yarn.task.YarnTask -val libDir = "${rootProject.projectDir}/lib" +node { + // Retrieve tested versions of Node, Npm and Yarn from the version catalog (see gradle/libs.versions.toml) + version = libs.versions.node.get() + npmVersion = libs.versions.npm.get() + yarnVersion = libs.versions.yarn.get() -val guiDir = "$projectDir/gui" -val webContent = "$guiDir/dist" - -tasks.register("clean") { - group = "Build" - description = "Delete previous build results" + // Download any Node, Npm and Yarn versions that aren't available locally, and use them from within the build. + download = true + // See settings.gradle.kts; workaround to make the Node plugin work, while still allowing repository declarations outside of settings.gradle.kts. + distBaseUrl = null +} - delete(webContent) +plugins { + alias(libs.plugins.node) + alias(libs.plugins.xtc) } -tasks.register("build") { - group = "Build" - description = "Build this module" +dependencies { + xdkDistribution(libs.xdk) + xtcModule(project(":common")) +} - dependsOn(common.tasks["build"]) +// TODO: Future webapp improvement; implement a parallel NPM / package-lock based approach. Yarn does not like having a package lock in the same build. +internal val gui = project.file("gui") +internal val buildDirs = arrayOf("gui/node_modules", "gui/dist", "gui/.quasar") - // there must be a way to tell quasar not to rebuild if nothing changed, but I cannot - // figure it out and have to use a manual timestamp check - dependsOn(checkGui) +/** + * By adding the gui/dist folder as a resource directory, the build will also treat + * it like an input to the build result. This means that any changes of its contents + * or timestamps will require that we rebuild it and its dependencies. This also means + * that as long as it stays unchanged, a finished build task for this project remains + * a no-op. + */ +sourceSets.main { + xtc { + resources { + srcDir(files("gui/dist/")) + } + } +} +val clean by tasks.existing { doLast { - val srcModule = "${projectDir}/src/main/x/platformUI.x" - - project.exec { - commandLine("xcc", "--verbose", - "-o", libDir, - "-L", libDir, - "-r", webContent, - srcModule) + for (buildDir in buildDirs) { + logger.info("Want to clean build dir: $buildDir") + delete(layout.files(buildDir)) } } } -val checkGui = tasks.register("checkGui") { - group = "Build" - description = "Build the web app content" +/** + * Task that will make sure yarn updates all node_modules. + */ +val yarnAddDependencies by tasks.registering(YarnTask::class) { + workingDir = gui + dependsOn(tasks.yarnSetup) - val src1 = fileTree("$projectDir/gui/src").files.stream(). - mapToLong{f -> f.lastModified()}.max().orElse(0) - val src2 = fileTree("$projectDir/gui/public").files.stream(). - mapToLong{f -> f.lastModified()}.max().orElse(0) - val dest = fileTree(webContent).files.stream(). - mapToLong{f -> f.lastModified()}.max().orElse(0) + // Tag this task as a producer of the "node_modules" directory, implicitly ensuring that any changes + // to the resolved node_modules will make its dependents rebuild properly. + outputs.dir("gui/node_modules") - if (src1 > dest || src2 > dest) { - dependsOn(buildGui) + // Add a dependency to quasar. If one exists in the yarn/lock file, it may be used instead, so + // if the state of global/local installation changed, that may still rebuild, though, if it's + // not installed in both places. + val quasarGlobal = providers.gradleProperty("org.xtclang.platform.quasarGlobal") + args = buildList { + add("add") + if (quasarGlobal.isPresent && quasarGlobal.get().toBoolean()) { + add("global") } - else { - println("$webContent is up to date") + add("quasar") + add("@quasar/cli") + } + + doFirst { + logger.lifecycle("Task '$name' installing Quasar (${if (quasarGlobal.isPresent && quasarGlobal.get().toBoolean()) "globally" else "locally, only for ${rootProject.name})"}.") + printTaskInputsAndOutputs(LogLevel.INFO) } } -val buildGui = tasks.register("buildGui") { +/** + * Task that defines the inputs and outputs for the Quasar webapp, and builds it. This means that the task + * should detect, e.g. if someone changes index.html or a single Vue file, and then rerun the task. Otherwise + * the task will be treated as "up to date". + */ +val yarnQuasarBuild by tasks.registering(YarnTask::class) { + workingDir = gui + dependsOn(yarnAddDependencies) + + inputs.files("gui/public") + inputs.files("gui/index.html", "gui/src") + outputs.dir("gui/.quasar") + outputs.dir("gui/dist/spa") // Declare output file collection, even though empty, or we can never cache the yarnQuasarBuild task. + args = listOf("quasar", "build") doLast { - project.exec { - workingDir(guiDir) - commandLine("yarn", "--ignore-engines", "quasar", "build") + printTaskInputsAndOutputs(LogLevel.INFO) + } +} + +/** + * Compile the XTC PlatformUI Module. + */ +val compileXtc by tasks.existing { + dependsOn(verifySourceSets) + dependsOn(yarnQuasarBuild) +} + +val processResources by tasks.existing { + dependsOn(yarnQuasarBuild) +} + +val verifySourceSets by tasks.registering { + dependsOn(processResources) + mustRunAfter(yarnQuasarBuild) + sourceSets.forEach { + logger.info("*** Source Set: $it") + it.resources.files.forEach { + logger.info("** Resource: $it") } } -} \ No newline at end of file +} + +private fun Task.printTaskInputsAndOutputs(level: LogLevel = LogLevel.LIFECYCLE) { + val inputFiles = inputs.files.asFileTree + logger.log(level, "Inputs: $name: ${inputFiles.toList()}") + val outputFiles = outputs.files.asFileTree + logger.log(level, "Outputs: $name: ${outputFiles.toList()}") + val ni = inputFiles.count() + val no = outputFiles.count() + logger.log(level, "${project.name} Task '$name' finished.") + logger.log(level, "${project.name} Inputs (count: $no):") + inputs.files.asFileTree.forEachIndexed { + i, it -> logger.log(level, "${project.name} '$name' input $i (of $ni): $it") + } + logger.log(level, "${project.name} Outputs (count: $no):") + outputs.files.asFileTree.forEachIndexed { + i, it -> logger.log(level, "${project.name} '$name' output $i (of $no): $it") + } +} diff --git a/platformUI/gradle.properties b/platformUI/gradle.properties new file mode 100644 index 0000000..926d4dc --- /dev/null +++ b/platformUI/gradle.properties @@ -0,0 +1 @@ +org.xtclang.platform.quasar.global=false diff --git a/platformUI/gui/.gitignore b/platformUI/gui/.gitignore index 7da5a9a..f1d913c 100644 --- a/platformUI/gui/.gitignore +++ b/platformUI/gui/.gitignore @@ -30,4 +30,4 @@ yarn-error.log* *.sln # local .env files -.env.local* \ No newline at end of file +.env.local* diff --git a/platformUI/gui/.npmrc b/platformUI/gui/.npmrc index 1f56332..32bd84d 100644 --- a/platformUI/gui/.npmrc +++ b/platformUI/gui/.npmrc @@ -1,3 +1,3 @@ # pnpm-related options shamefully-hoist=true -strict-peer-dependencies=false \ No newline at end of file +strict-peer-dependencies=false diff --git a/platformUI/gui/package.json b/platformUI/gui/package.json index 679cf24..c717749 100644 --- a/platformUI/gui/package.json +++ b/platformUI/gui/package.json @@ -13,11 +13,12 @@ "build": "quasar build" }, "dependencies": { + "@quasar/cli": "^2.3.0", "@quasar/extras": "^1.16.4", "axios": "^1.2.1", "node": "^20.12.2", "pinia": "^2.0.11", - "quasar": "^2.6.0", + "quasar": "^2.14.5", "vue": "^3.0.0", "vue-router": "^4.0.0", "yarn": "^1.22.21" diff --git a/platformUI/gui/src/App.vue b/platformUI/gui/src/App.vue index 5a2ae0d..38442ee 100644 --- a/platformUI/gui/src/App.vue +++ b/platformUI/gui/src/App.vue @@ -8,4 +8,4 @@ import { defineComponent } from 'vue' export default defineComponent({ name: 'App' }) - \ No newline at end of file + diff --git a/settings.gradle.kts b/settings.gradle.kts index 3ddba87..8348d22 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,8 +1,131 @@ +/** + * settings.gradle.kts is used for bootstrapping a build. + * + * This is based on the xtc-application-template repository, so understand how it works + * and how to supply credentials. If you have put working GitHub credentials in your + * $GRADLE_USER_HOME/gradle.properties already, this should just work. + * + * You will need properties named "gitHubUrl" , "gitHubUser" an "gitHubToken" + * available to the system, in order for it to work. Please see the README.md + * on how to set this up, and why you have to do this. + */ + +pluginManagement { + repositories { + val gitHubOnly: String? by settings + val mavenLocalOnly: String? by settings + + val gitHubUser: String? by settings + val gitHubToken: String? by settings + val gitHubUrl: String by settings + + if (mavenLocalOnly == "true" && gitHubOnly == mavenLocalOnly) { + throw GradleException("Error: mavenLocalOnly AND gitHubOnly are both set to true.") + } + + if (mavenLocalOnly != "true") { + maven { + url = uri(gitHubUrl) + credentials { + username = gitHubUser + password = gitHubToken + } + } + } + + if (gitHubOnly != "true") { + // Define mavenLocal as an artifact repository (disabled by default) + mavenLocal() + } + + // Define Gradle Plugin Portal as a plugin repository + gradlePluginPortal() + } + + plugins { + id("org.xtclang.xtc-plugin") + id("com.github.node-gradle.node") + } +} + +@Suppress("UnstableApiUsage") +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + // Define XTC org GitHub Maven as a plugin repository + val gitHubOnly: String? by settings + val mavenLocalOnly: String? by settings + + val gitHubUser: String? by settings + val gitHubToken: String? by settings + val gitHubUrl: String by settings + + if (mavenLocalOnly == "true" && gitHubOnly == mavenLocalOnly) { + throw GradleException("Error: mavenLocalOnly AND gitHubOnly are both set to true.") + } + + if (mavenLocalOnly != "true") { + maven { + url = uri(gitHubUrl) + credentials { + username = gitHubUser + password = gitHubToken + } + } + } + + if (gitHubOnly != "true") { + // Define mavenLocal as an artifact repository (disabled by default) + mavenLocal() + } + + /** + * Patch the Node configuration, so that the Node plugin doesn't try to add hardcoded + * repositories to the Platform project during build. We are following the best-practice + * of forbidding any repository declaration anywhere else but project settings. The Node + * plugin does not. However, it's way more important to be able to specify an exact Node + * version, and integrate that with the build, than having to fall back on a system wide + * version of NodeJS that may or may not be installed on your machine, and may or may + * not work well the Platform build. The Platform build religiously declares all its + * required dependencies its repository, and SHOULD NEVER rely on any other system state + * of its host machine. This also very easily paves the way for integration testing, CI/CD, + * containerization and avoids contaminating your machine with multiple NodeJS versions. + * In 2024, we do not install and rely on system wide software on a dev machine, unless + * we are completely out of alternatives. + * + * For the NodeJS Gradle plugin, this is a known bug, and the workaround is the one + * recommended by the plugin developers: + * @see https://github.com/node-gradle/gradle-node-plugin/blob/main/docs/faq.md#is-this-plugin-compatible-with-centralized-repositories-declaration + */ + ivy { + name = "NodeJS" + setUrl("https://nodejs.org/dist/") + patternLayout { + artifact("v[revision]/[artifact](-v[revision]-[classifier]).[ext]") + ivy("v[revision]/ivy.xml") + } + metadataSources { + artifact() + } + content { + includeModule("org.nodejs", "node") + } + } + } +} + +// Set the name of the main project. rootProject.name = "platform" -include(":common") -include(":kernel") -include(":host") -include(":platformDB") -include(":platformUI") -include(":platformCLI") \ No newline at end of file +listOfNotNull( + "kernel", + "common", + "host", + "platformDB", + "platformUI", + "platformCLI" +).forEach { + include(":$it") + logger.info("[platform] Added subproject '$it' to build.") +} + diff --git a/settings.gradle.local.kts b/settings.gradle.local.kts new file mode 100644 index 0000000..8cbadd0 --- /dev/null +++ b/settings.gradle.local.kts @@ -0,0 +1,67 @@ +rootProject.name = "platform" + +pluginManagement { + repositories { + mavenLocal() + gradlePluginPortal() // This is used to resolve Node and other non-XTC related dependencies we need to build and run. + } + plugins { + id("org.xtclang.xtc-plugin") + id("com.github.node-gradle.node") + } +} + +@Suppress("UnstableApiUsage") +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + mavenLocal() + // TODO: May want to move this out into a specific node.workaround.settings.gradle.kts, + // or something, and apply that so that it just inlines here. Can't remember why + // that did not work on my first attempt. + + /** + * Patch the Node configuration, so that the Node plugin doesn't try to add hardcoded + * repositories to the Platform project during build. We are following the best-practice + * of forbidding any repository declaration anywhere else but project settings. The Node + * plugin does not. However, it's way more important to be able to specify an exact Node + * version, and integrate that with the build, than having to fall back on a system wide + * version of NodeJS that may or may not be installed on your machine, and may or may + * not work well the Platform build. The Platform build religiously declares all its + * required dependencies its repository, and SHOULD NEVER rely on any other system state + * of its host machine. This also very easily paves the way for integration testing, CI/CD, + * containerization and avoids contaminating your machine with multiple NodeJS versions. + * In 2024, we do not install and rely on system wide software on a dev machine, unless + * we are completely out of alternatives. + * + * For the NodeJS Gradle plugin, this is a known bug, and the workaround is the one + * recommended by the plugin developers: + * @see https://github.com/node-gradle/gradle-node-plugin/blob/main/docs/faq.md#is-this-plugin-compatible-with-centralized-repositories-declaration + */ + ivy { + name = "NodeJS" + setUrl("https://nodejs.org/dist/") + patternLayout { + artifact("v[revision]/[artifact](-v[revision]-[classifier]).[ext]") + ivy("v[revision]/ivy.xml") + } + metadataSources { + artifact() + } + content { + includeModule("org.nodejs", "node") + } + } + } +} + +listOfNotNull( + "kernel", + "common", + "host", + "platformDB", + "platformUI" +).forEach { + include(":$it") + logger.lifecycle("Added subproject '$it' to build.") +} From 5bc0b2340006a248f93cd9f9056697b65f404cba Mon Sep 17 00:00:00 2001 From: Marcus Lagergren <1062473+lagergren@users.noreply.github.com> Date: Wed, 28 Feb 2024 18:25:51 +0100 Subject: [PATCH 02/13] Updated plugin and repaired processXtcResources for the gui app. --- gradle/libs.versions.toml | 2 +- platformUI/build.gradle.kts | 31 +++++++++++++++++++++---------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1196df9..fce3337 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -4,7 +4,7 @@ # [versions] -xdk = "0.4.43" +xdk = "0.4.431" gradle-node = "7.0.1" node = "20.10.0" diff --git a/platformUI/build.gradle.kts b/platformUI/build.gradle.kts index 9ad06af..fd1aebf 100644 --- a/platformUI/build.gradle.kts +++ b/platformUI/build.gradle.kts @@ -100,6 +100,8 @@ val yarnAddDependencies by tasks.registering(YarnTask::class) { * Task that defines the inputs and outputs for the Quasar webapp, and builds it. This means that the task * should detect, e.g. if someone changes index.html or a single Vue file, and then rerun the task. Otherwise * the task will be treated as "up to date". + * + * The quasar build creates the gui/dist/spa folder and files. */ val yarnQuasarBuild by tasks.registering(YarnTask::class) { workingDir = gui @@ -115,26 +117,35 @@ val yarnQuasarBuild by tasks.registering(YarnTask::class) { } } + /** * Compile the XTC PlatformUI Module. */ val compileXtc by tasks.existing { - dependsOn(verifySourceSets) + //dependsOn(verifySourceSets) dependsOn(yarnQuasarBuild) } val processResources by tasks.existing { - dependsOn(yarnQuasarBuild) + enabled = false + // TODO get rid of processResources from the XTC build cycle. } -val verifySourceSets by tasks.registering { - dependsOn(processResources) - mustRunAfter(yarnQuasarBuild) - sourceSets.forEach { - logger.info("*** Source Set: $it") - it.resources.files.forEach { - logger.info("** Resource: $it") - } +// This implicitly copies the yarnQuasarBuild outputs to platformUI/build/xtc/main/resources, which +// is where the compileXtc tasks expects to find its resource path. Since the yarnQuasarBuild task +// does not output its files in src/main/resources, which it should for Java or XTC, for the normal +// process resources task to pick it up, we have add the paths where they end up as a resource directory +// too. We do that in the source set configuration. Process resources then does any available transforms, +// which here is the default identity transform, i.e. copy, to the build resources directory for the +// source set main. That is what we want, because that is what compileXtc will use as its -r flag. In +// XTC resources have to be processed before the build, since the build compiles them in. Any resource +// processing hence haver to take place before the compileXtc task, and its sourceset resource outputs +// (under build/sourceset/resources) by convention, will be fed into the XTC Compiler. +val processXtcResources by tasks.existing { + dependsOn(yarnQuasarBuild) + inputs.files(yarnQuasarBuild.map { it.outputs.files }) + doLast { + printTaskInputsAndOutputs() } } From 2dc8d2669ec2a616e4fa65fd64a0aac54f272007 Mon Sep 17 00:00:00 2001 From: Marcus Lagergren <1062473+lagergren@users.noreply.github.com> Date: Tue, 5 Mar 2024 15:32:13 +0100 Subject: [PATCH 03/13] Updated version of XDK artifact and plugin Artifact to point out master 2024-03-05 (manual publication) --- README.md | 2 ++ gradle/libs.versions.toml | 2 +- platformUI/gui/package.json | 3 +-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3a10afa..5f11180 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +FROM gradle-8.6 + # Platform as a Service This is the public repository for the open source Ecstasy PaaS project, sponsored by [xqiz.it](http://xqiz.it). diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index fce3337..1196df9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -4,7 +4,7 @@ # [versions] -xdk = "0.4.431" +xdk = "0.4.43" gradle-node = "7.0.1" node = "20.10.0" diff --git a/platformUI/gui/package.json b/platformUI/gui/package.json index c717749..679cf24 100644 --- a/platformUI/gui/package.json +++ b/platformUI/gui/package.json @@ -13,12 +13,11 @@ "build": "quasar build" }, "dependencies": { - "@quasar/cli": "^2.3.0", "@quasar/extras": "^1.16.4", "axios": "^1.2.1", "node": "^20.12.2", "pinia": "^2.0.11", - "quasar": "^2.14.5", + "quasar": "^2.6.0", "vue": "^3.0.0", "vue-router": "^4.0.0", "yarn": "^1.22.21" From 9b784020de21aa0c7bade9858c57fe7e3b467517 Mon Sep 17 00:00:00 2001 From: Marcus Lagergren <1062473+lagergren@users.noreply.github.com> Date: Sat, 9 Mar 2024 13:48:42 +0100 Subject: [PATCH 04/13] Adding some docker work. Looks like we don't need all port forwarding stuff. --- Dockerfile | 52 ------------------- README.md | 2 + docker-compose.yaml | 45 +++++++++++++++++ docker/.env | 4 ++ docker/.env.local | 4 ++ docker/Dockerfile.platform | 81 ++++++++++++++++++++++++++++++ docker/config/port-forwarding.conf | 5 ++ docker/entrypoint-xtc-platform.sh | 34 +++++++++++++ 8 files changed, 175 insertions(+), 52 deletions(-) delete mode 100644 Dockerfile create mode 100644 docker-compose.yaml create mode 100644 docker/.env create mode 100644 docker/.env.local create mode 100644 docker/Dockerfile.platform create mode 100644 docker/config/port-forwarding.conf create mode 100755 docker/entrypoint-xtc-platform.sh diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 49aa712..0000000 --- a/Dockerfile +++ /dev/null @@ -1,52 +0,0 @@ -FROM homebrew/brew:4.1.4 - -# install essential tools and libraries -USER root -RUN apt-get update \ - && apt-get upgrade -y \ - && apt-get install -y build-essential git - -# install xvm -RUN brew tap xtclang/xvm \ - && brew install xdk-latest - -# build the latest xvm from source and update the default -RUN git clone https://github.com/xtclang/xvm.git ~/xvm \ - && cd ~/xvm \ - && ./gradlew dist-local - -# install JS tools -ARG NODE_VERSION=18.17.1 -ARG NODE_PACKAGE=node-v$NODE_VERSION-linux-x64 -ARG NODE_HOME=/opt/$NODE_PACKAGE - -ENV NODE_PATH $NODE_HOME/lib/node_modules -ENV PATH $NODE_HOME/bin:$PATH - -RUN curl https://nodejs.org/dist/v$NODE_VERSION/$NODE_PACKAGE.tar.gz | tar -xzC /opt/ \ - && npm install --global yarn - -# build the platform -RUN mkdir -p ~/xqiz.it/platform \ - && keytool -genkeypair \ - -alias platform \ - -keyalg RSA \ - -keysize 2048 \ - -validity 365 \ - -dname "OU=Platform, O=[some.org], C=US" \ - -keystore ~/xqiz.it/platform/certs.p12 \ - -storetype PKCS12 -storepass qwerty \ - && keytool -genseckey \ - -alias cookies \ - -keyalg AES \ - -keysize 256 \ - -keystore ~/xqiz.it/platform/certs.p12 \ - -storetype PKCS12 \ - -storepass qwerty \ - && git clone https://github.com/azzazzel/xtc_platform.git ~/xtc_platform \ - && cd ~/xtc_platform && git checkout quasar_gui \ - && cd ~/xtc_platform/platformUI/gui && npm install \ - && cd ~/xtc_platform && ~/xvm/gradlew build - -WORKDIR /root/xtc_platform -CMD ["xec", "-L", "lib/", "lib/kernel.xtc", "qwerty"] diff --git a/README.md b/README.md index 5f11180..4c3ce4f 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,8 @@ as a container/Dockerfile/docker in the near future, so that you won't have to d you would need add an exception entry for `127.0.0.1` to your DNS Server settings: "Exceptions to DNS Rebind Protection" (Advanced - Network Settings - DNS Server) + TODO: Why not just add an /etc/host entry, or run a dns server in a co-deployed container? + 5. Create a self-signed certificate for the platform web server. For example: ``` diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..e623eef --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,45 @@ +# +# Platform independent Docker compose configuration that syncs out a git branch +# (master is default) and/or a tag, and produced distribution installers for it. +# This is equivalent to ./gradlew installDist, where all platform archives, +# including Windows exe files, are built in the container. +# +# The build volume persists, and is rebuilt whenever it is detected that we +# want to build a branch at a change that doesn't correspond to the last build +# state. The cache volume also persiscat ~ts, so significant info is reused. +# + +version: '3.8' + +# +# Set up secrets from the default locations, so that we can do things like +# publications, artifact signing or other Gradle operations, where sensitive +# information is stored outside the repository. +# +#secrets: +# gradle_properties: +# file: ~/.gradle/gradle.properties + +#volumes: +# cache: +# source: + +services: + platform: + image: ghcr.io/xtclang/xdk-platform:latest + build: + context: docker + dockerfile: Dockerfile.platform + args: + DOCKER_BUILDKIT: 1 + PLATFORM_PASSWORD: ${PLATFORM_PASSWORD:-password} + env_file: + - docker/.env + - docker/.env.local + extra_hosts: + - "xtc-platform.localhost.xqiz.it:127.0.0.1" + - "xtc-platform.xqiz.it:127.0.0.10" + ports: + - "8080:8080" + - "8090:8090" + entrypoint: ['entrypoint-xtc-platform.sh'] diff --git a/docker/.env b/docker/.env new file mode 100644 index 0000000..fd1bd5c --- /dev/null +++ b/docker/.env @@ -0,0 +1,4 @@ +COMPOSE_PROJECT_NAME=platform + +GITHUB_BRANCH=${GITHUB_BRANCH:-master} +XTC_VERSION=0.4.3 diff --git a/docker/.env.local b/docker/.env.local new file mode 100644 index 0000000..a899be7 --- /dev/null +++ b/docker/.env.local @@ -0,0 +1,4 @@ + +# TODO: This should be exclude from source control. + +PLATFORM_PASSWORD=${PLATFORM_PASSWORD:-password} diff --git a/docker/Dockerfile.platform b/docker/Dockerfile.platform new file mode 100644 index 0000000..6305e7b --- /dev/null +++ b/docker/Dockerfile.platform @@ -0,0 +1,81 @@ +#FROM openjdk:21 +FROM ubuntu:24.04 + +ARG DOCKER_BUILDKIT=$DOCKER_BUILDKIT +ENV DOCKER_BUILD_KIT=$DOCKER_BUILDKIT + +#ARG TARGETARCH +#ARG BUILDARCH +#ENV TARGETARCH=$TARGETARCH +#ENV BUILDARCH=$BUILDARCH + +# Linux +ENV LANG C.UTF-8 +ENV LC_ALL C.UTF-8 +ENV DEBIAN_FRONTEND=noninteractive + +ARG XTC_USER=xtc +ARG XTC_USER_HOME=/home/$XTC_USER + +ENV XTC_USER=$XTC_USER +ENV XTC_USER_HOME=$XTC_USER_HOME +ENV XQIZIT_HOME=$XTC_USER_HOME/xqiz.it +ENV PLATFORM_HOME=$XQIZIT_HOME/platform + +ARG NPM_SAFE_VERSION='npm@10.4.0' + +USER root + +RUN apt-get update && apt-get install --no-install-recommends -y \ + iputils-ping jq sudo wget curl openjdk-21-jdk + +RUN curl --silent --location https://deb.nodesource.com/setup_21.x | sudo bash - +RUN apt-get -y --no-install-recommends install \ + nodejs # && npm -g install npm@${NPM_SAFE_VERSION} # && npm -g install yarn + +COPY entrypoint-xtc-platform.sh /usr/local/bin +#RUN echo >>/etc/hosts "127.0.0.1 xtc-platform.localhost.xqiz.it" +#RUN echo >>/etc/hosts "127.0.0.10 xtc-platform.xqiz.it" + +RUN useradd -ms /bin/bash $XTC_USER \ + && passwd -d $XTC_USER \ + && passwd -d root \ + && usermod -aG sudo $XTC_USER \ + && echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers \ + && chown -R $XTC_USER:$XTC_USER $XTC_USER_HOME + +USER $XTC_USER + +# 1. Create xqiz.it subdirectory and config +RUN mkdir -p $PLATFORM_HOME && mkdir -p $XQIZIT_HOME/config + +# 2. Create port forwarding config. +COPY config/port-forwarding.conf $PLATFORM_HOME + +# 5. Create a self-signed certificate for the platform web server. For example: +ARG PLATFORM_PASSWORD +ENV PLATFORM_PASSWORD=$PLATFORM_PASSWORD + +RUN keytool \ + -genkeypair \ + -alias platform \ + -keyalg RSA \ + -keysize 2048 \ + -validity 365 \ + -dname "OU=Platform, O=${XTC_USER}, C=US" \ + -keystore ${PLATFORM_HOME}/certs.p12 \ + -storetype PKCS12 \ + -storepass $PLATFORM_PASSWORD + +# 6. Add a symmetric key to encode the cookies: +RUN keytool \ + -genseckey \ + -alias cookies \ + -keyalg AES \ + -keysize 256 \ + -keystore ${PLATFORM_HOME}/certs.p12 \ + -storetype PKCS12 \ + -storepass $PLATFORM_PASSWORD + +WORKDIR $XTC_USER_HOME +ENTRYPOINT ["/usr/local/bin/entrypoint-xtc-platform.sh"] diff --git a/docker/config/port-forwarding.conf b/docker/config/port-forwarding.conf new file mode 100644 index 0000000..39530ef --- /dev/null +++ b/docker/config/port-forwarding.conf @@ -0,0 +1,5 @@ +#!bin/sh + +rdr pass on lo0 inet proto tcp from any to self port 80 -> 127.0.0.1 port 8080 +rdr pass on lo0 inet proto tcp from any to self port 443 -> 127.0.0.1 port 8090 + \ No newline at end of file diff --git a/docker/entrypoint-xtc-platform.sh b/docker/entrypoint-xtc-platform.sh new file mode 100755 index 0000000..e5651ee --- /dev/null +++ b/docker/entrypoint-xtc-platform.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +echo "Entrypoint for Platform..." + +# XTC user should be sudoer +# Port forwaring should just be in the container??? +#echo "User $USER executing pfctl under sudo privileges..." +#sudo pfctl -evf ~$XQIZIT_HOME/platform/port-forwarding.conf +#echo "Done." + +# +# TODO: This is insane. We should just be setting up a localhost network. +# If we want xtc-platform.localhost.xqiz.it to pingback from the host, put it /etc/hosts +# +# The domain name `xtc-platform.localhost.xqiz.it` should resolve to `127.0.0.1`. This allows the same xqiz.it +# cloud-hosted platform to be self-hosted on the `localhost` loop-back address, enabling local and disconnected +# development. +# +# If that address fails to resolve you may need to change the rules on you DNS server. For example, for Verizon routers +# you would need add an exception entry for `127.0.0.1` to your DNS Server settings: "Exceptions to DNS Rebind +# Protection" (Advanced - Network Settings - DNS Server) + +ping -c 1 xtc-platform.localhost.xqiz.it +if [ $? != 0 ]; then + echo "Ping to localhost failed using xtc-platform.localhost.xqiz.it" + exit 1 +fi + +if [ -z "${@}" ]; then + echo "No extra entrypoint arguments. Container exiting from $0." +else + echo "Handing over entrypoint arguments to exec: ${@}" + exec "${@}" +fi From 17658c3f4cdb3a1331cfe57624cf9e6fc9239940 Mon Sep 17 00:00:00 2001 From: Marcus Lagergren <1062473+lagergren@users.noreply.github.com> Date: Mon, 11 Mar 2024 08:49:40 +0100 Subject: [PATCH 05/13] Docker scripts stubs. Should really do the publishing flow now instead, to shorten this and remove the need for an XVM build / brew install in the image. --- docker-compose.yaml | 4 ++- docker/Dockerfile.platform | 25 ++++++++----------- ...trypoint-xtc-platform.sh => entrypoint.sh} | 5 +++- docker/paltform-down.sh | 11 ++++++++ docker/platform-up.sh | 7 ++++++ 5 files changed, 36 insertions(+), 16 deletions(-) rename docker/{entrypoint-xtc-platform.sh => entrypoint.sh} (84%) create mode 100755 docker/paltform-down.sh create mode 100755 docker/platform-up.sh diff --git a/docker-compose.yaml b/docker-compose.yaml index e623eef..41689f6 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -33,6 +33,8 @@ services: args: DOCKER_BUILDKIT: 1 PLATFORM_PASSWORD: ${PLATFORM_PASSWORD:-password} + GITHUB_BRANCH_PLATFORM: ${GITHUB_BRANCH_PLATFORM:-platform-xtcplugin} + GITHUB_BRANCH_XVM: ${GITHUB_BRANCH_XVM:-master} env_file: - docker/.env - docker/.env.local @@ -42,4 +44,4 @@ services: ports: - "8080:8080" - "8090:8090" - entrypoint: ['entrypoint-xtc-platform.sh'] + entrypoint: ['entrypoint.sh'] diff --git a/docker/Dockerfile.platform b/docker/Dockerfile.platform index 6305e7b..811a254 100644 --- a/docker/Dockerfile.platform +++ b/docker/Dockerfile.platform @@ -4,38 +4,35 @@ FROM ubuntu:24.04 ARG DOCKER_BUILDKIT=$DOCKER_BUILDKIT ENV DOCKER_BUILD_KIT=$DOCKER_BUILDKIT -#ARG TARGETARCH -#ARG BUILDARCH -#ENV TARGETARCH=$TARGETARCH -#ENV BUILDARCH=$BUILDARCH - -# Linux ENV LANG C.UTF-8 ENV LC_ALL C.UTF-8 ENV DEBIAN_FRONTEND=noninteractive ARG XTC_USER=xtc ARG XTC_USER_HOME=/home/$XTC_USER +ARG NPM_SAFE_VERSION='npm@10.4.0' +ARG GITHUB_BRANCH_XVM +ARG GITHUB_BRANCH_PLATFORM ENV XTC_USER=$XTC_USER ENV XTC_USER_HOME=$XTC_USER_HOME ENV XQIZIT_HOME=$XTC_USER_HOME/xqiz.it ENV PLATFORM_HOME=$XQIZIT_HOME/platform - -ARG NPM_SAFE_VERSION='npm@10.4.0' +ENV GITHUB_BRANCH_XVM=$GITHUB_BRANCH_XVM +ENV GITHUB_BRANCH_PLATFORM=$GITHUB_BRANCH_PLATFORM USER root RUN apt-get update && apt-get install --no-install-recommends -y \ - iputils-ping jq sudo wget curl openjdk-21-jdk + iputils-ping jq sudo wget curl git openjdk-21-jdk RUN curl --silent --location https://deb.nodesource.com/setup_21.x | sudo bash - RUN apt-get -y --no-install-recommends install \ - nodejs # && npm -g install npm@${NPM_SAFE_VERSION} # && npm -g install yarn + nodejs + +# && npm -g install npm@${NPM_SAFE_VERSION} # && npm -g install yarn -COPY entrypoint-xtc-platform.sh /usr/local/bin -#RUN echo >>/etc/hosts "127.0.0.1 xtc-platform.localhost.xqiz.it" -#RUN echo >>/etc/hosts "127.0.0.10 xtc-platform.xqiz.it" +COPY entrypoint.sh /usr/local/bin RUN useradd -ms /bin/bash $XTC_USER \ && passwd -d $XTC_USER \ @@ -78,4 +75,4 @@ RUN keytool \ -storepass $PLATFORM_PASSWORD WORKDIR $XTC_USER_HOME -ENTRYPOINT ["/usr/local/bin/entrypoint-xtc-platform.sh"] +ENTRYPOINT ["entrypoint.sh"] diff --git a/docker/entrypoint-xtc-platform.sh b/docker/entrypoint.sh similarity index 84% rename from docker/entrypoint-xtc-platform.sh rename to docker/entrypoint.sh index e5651ee..0109431 100755 --- a/docker/entrypoint-xtc-platform.sh +++ b/docker/entrypoint.sh @@ -9,7 +9,6 @@ echo "Entrypoint for Platform..." #echo "Done." # -# TODO: This is insane. We should just be setting up a localhost network. # If we want xtc-platform.localhost.xqiz.it to pingback from the host, put it /etc/hosts # # The domain name `xtc-platform.localhost.xqiz.it` should resolve to `127.0.0.1`. This allows the same xqiz.it @@ -26,6 +25,10 @@ if [ $? != 0 ]; then exit 1 fi +# TODO Here is where we really want snapshot releases. +git clone --branch $GITHUB_BRANCH_PLATFORM --depth=1 https://github.com/xtclang/platform.git +git clone --branch $GITHUB_BRANCH_XVM --depth=1 https://github.com/xtclang/xvm.git + if [ -z "${@}" ]; then echo "No extra entrypoint arguments. Container exiting from $0." else diff --git a/docker/paltform-down.sh b/docker/paltform-down.sh new file mode 100755 index 0000000..45d2835 --- /dev/null +++ b/docker/paltform-down.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +_platform="htts://xtc-platform.localhost.xqiz.it" +if [ -z $1 ]; then + echo "No platform URL given, defaulting to 'https://xtc-platform.localhost.xqiz.it'" +else + _platform=$1 +fi + +echo "Taking down platform: '$_platform'..." +https://xtc-platform.localhost.xqiz.itecho "Done." diff --git a/docker/platform-up.sh b/docker/platform-up.sh new file mode 100755 index 0000000..f65a5f4 --- /dev/null +++ b/docker/platform-up.sh @@ -0,0 +1,7 @@ +#!bin/sh + + +#./gradlew build +#xec --verbose -L ./build/platform/ kernel.xqiz.it + +# ./gradlew run -PkeystorePassword=` From d0fb8fcf9638c3f4bdba536ac3f58bda943a3908 Mon Sep 17 00:00:00 2001 From: Marcus Lagergren <1062473+lagergren@users.noreply.github.com> Date: Mon, 11 Mar 2024 11:56:28 +0100 Subject: [PATCH 06/13] Updated docker --- docker-compose.yaml | 21 +++--- docker/Dockerfile.platform | 19 ++++-- docker/config/port-forwarding.conf | 3 +- docker/entrypoint.sh | 26 ++++++- docker/platform-build.sh | 49 ++++++++++++++ docker/{paltform-down.sh => platform-down.sh} | 0 docker/platform-up.sh | 2 +- settings.gradle.kts | 2 + settings.gradle.local.kts | 67 ------------------- 9 files changed, 104 insertions(+), 85 deletions(-) create mode 100644 docker/platform-build.sh rename docker/{paltform-down.sh => platform-down.sh} (100%) delete mode 100644 settings.gradle.local.kts diff --git a/docker-compose.yaml b/docker-compose.yaml index 41689f6..3a0d761 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -16,13 +16,14 @@ version: '3.8' # publications, artifact signing or other Gradle operations, where sensitive # information is stored outside the repository. # -#secrets: -# gradle_properties: -# file: ~/.gradle/gradle.properties +secrets: + gradle_properties: + file: ~/.gradle/gradle.properties -#volumes: -# cache: -# source: +# gradle_cache is placed under /.root +# we also add a platform volume to reuse ~/xqiz.it +volumes: + build: services: platform: @@ -35,6 +36,10 @@ services: PLATFORM_PASSWORD: ${PLATFORM_PASSWORD:-password} GITHUB_BRANCH_PLATFORM: ${GITHUB_BRANCH_PLATFORM:-platform-xtcplugin} GITHUB_BRANCH_XVM: ${GITHUB_BRANCH_XVM:-master} + secrets: + - gradle_properties + volumes: + - build:/cache env_file: - docker/.env - docker/.env.local @@ -42,6 +47,6 @@ services: - "xtc-platform.localhost.xqiz.it:127.0.0.1" - "xtc-platform.xqiz.it:127.0.0.10" ports: - - "8080:8080" - - "8090:8090" + - "8080:80" + #- "8090:90" entrypoint: ['entrypoint.sh'] diff --git a/docker/Dockerfile.platform b/docker/Dockerfile.platform index 811a254..108ec1e 100644 --- a/docker/Dockerfile.platform +++ b/docker/Dockerfile.platform @@ -20,6 +20,7 @@ ENV XQIZIT_HOME=$XTC_USER_HOME/xqiz.it ENV PLATFORM_HOME=$XQIZIT_HOME/platform ENV GITHUB_BRANCH_XVM=$GITHUB_BRANCH_XVM ENV GITHUB_BRANCH_PLATFORM=$GITHUB_BRANCH_PLATFORM +#ENV GRADLE_USER_HOME=$XTC_USER_HOME/build/.gradle USER root @@ -30,9 +31,13 @@ RUN curl --silent --location https://deb.nodesource.com/setup_21.x | sudo bash - RUN apt-get -y --no-install-recommends install \ nodejs +# TOOD: Figure out why this isn't working. # && npm -g install npm@${NPM_SAFE_VERSION} # && npm -g install yarn -COPY entrypoint.sh /usr/local/bin +# Install dev tools. We should separate these out later. +RUN apt-get install --no-install-recommends -y emacs-nox + +COPY *.sh /usr/local/bin RUN useradd -ms /bin/bash $XTC_USER \ && passwd -d $XTC_USER \ @@ -43,13 +48,13 @@ RUN useradd -ms /bin/bash $XTC_USER \ USER $XTC_USER -# 1. Create xqiz.it subdirectory and config +# From README.md: Create xqiz.it subdirectory and config RUN mkdir -p $PLATFORM_HOME && mkdir -p $XQIZIT_HOME/config -# 2. Create port forwarding config. +# From README.md: Create port forwarding config. COPY config/port-forwarding.conf $PLATFORM_HOME -# 5. Create a self-signed certificate for the platform web server. For example: +# From README.md create: a self-signed certificate for the platform web server. For example: ARG PLATFORM_PASSWORD ENV PLATFORM_PASSWORD=$PLATFORM_PASSWORD @@ -64,7 +69,7 @@ RUN keytool \ -storetype PKCS12 \ -storepass $PLATFORM_PASSWORD -# 6. Add a symmetric key to encode the cookies: +# From README.md: Add a symmetric key to encode the cookies: RUN keytool \ -genseckey \ -alias cookies \ @@ -75,4 +80,8 @@ RUN keytool \ -storepass $PLATFORM_PASSWORD WORKDIR $XTC_USER_HOME + +#ADD https://api.github.com/repos/xtclang/platform/git/refs/heads/${GITHUB_BRANCH_PLATFORM} $HOME/github-version.json +#RUN git clone --branch $GITHUB_BRANCH_PLATFORM --depth=1 https://github.com/xtclang/platform.git + ENTRYPOINT ["entrypoint.sh"] diff --git a/docker/config/port-forwarding.conf b/docker/config/port-forwarding.conf index 39530ef..2dd82d6 100644 --- a/docker/config/port-forwarding.conf +++ b/docker/config/port-forwarding.conf @@ -1,5 +1,4 @@ -#!bin/sh +; TODO this should not be necessary, it's merely a matter of container network setup / container hosts and ports. rdr pass on lo0 inet proto tcp from any to self port 80 -> 127.0.0.1 port 8080 rdr pass on lo0 inet proto tcp from any to self port 443 -> 127.0.0.1 port 8090 - \ No newline at end of file diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index 0109431..aa9de03 100755 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -2,6 +2,26 @@ echo "Entrypoint for Platform..." +# Under root build we have have src and .gradle +sudo chown -R $XTC_USER:$XTC_USER /cache + +if [ ! -e $HOME/build ]; then + echo "Linking cache volume as $HOME/build" + ln -s /cache $HOME/build +fi + +export GRADLE_USER_HOME=$HOME/build/.gradle +if [ ! -d $GRADLE_USER_HOME ]; then + echo "Creating Gradle user home: $GRADLE_USER_HOME" + mkdir -p $GRADLE_USER_HOME + ln -s /var/run/secrets/gradle_properties $GRADLE_USER_HOME/gradle.properties +fi + + +source /usr/local/bin/platform-build.sh + +check_updated_source + # XTC user should be sudoer # Port forwaring should just be in the container??? #echo "User $USER executing pfctl under sudo privileges..." @@ -26,8 +46,10 @@ if [ $? != 0 ]; then fi # TODO Here is where we really want snapshot releases. -git clone --branch $GITHUB_BRANCH_PLATFORM --depth=1 https://github.com/xtclang/platform.git -git clone --branch $GITHUB_BRANCH_XVM --depth=1 https://github.com/xtclang/xvm.git +# TODO Right now the git clone is part of the container build. We should not do that, or at least map it to a reusable volume. +# First we just want to check that docker works for it, though. +#git clone --branch $GITHUB_BRANCH_PLATFORM --depth=1 https://github.com/xtclang/platform.git +#git clone --branch $GITHUB_BRANCH_XVM --depth=1 https://github.com/xtclang/xvm.git if [ -z "${@}" ]; then echo "No extra entrypoint arguments. Container exiting from $0." diff --git a/docker/platform-build.sh b/docker/platform-build.sh new file mode 100644 index 0000000..4422273 --- /dev/null +++ b/docker/platform-build.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +echo "Ensuring the platform is built." + + +function clone_platform() { + pushd $HOME/build + echo "Cloning to platform" + git clone --branch $GITHUB_BRANCH_PLATFORM --depth=1 https://github.com/xtclang/platform.git platform + echo "Writing last commit" + pushd platform + git rev-parse --verify HEAD > last_commit + popd + popd +} + +function check_updated_source() { + if [ -e $HOME/build/platform ]; then + echo "Found existing source." + + pushd $HOME/build/platform + _last_commit="unknown" + if [ -e last_commit ]; then + _last_commit=$(cat last_commit) + fi + _last_remote_commit=$(git rev-parse --verify HEAD) + popd + + echo "last_commit : $_last_commit" + echo "last_remote_commit: $_last_remote_commit" + if [ "$_last_commit" != "$_last_remote_commit" ]; then + echo "Existing source out of date." + rm -fr $HOME/build/platform + clone_platform + else + echo "Existing platform is up date - good!" + fi + else + echo "Cloning new platform (no previous version found)." + clone_platform + fi +} + +# Verify that the platform is built +function build_platform() { + pushd $HOME/build/platform + ./gradlew build + popd +} diff --git a/docker/paltform-down.sh b/docker/platform-down.sh similarity index 100% rename from docker/paltform-down.sh rename to docker/platform-down.sh diff --git a/docker/platform-up.sh b/docker/platform-up.sh index f65a5f4..3d3247d 100755 --- a/docker/platform-up.sh +++ b/docker/platform-up.sh @@ -1,4 +1,4 @@ -#!bin/sh +#!/bin/sh #./gradlew build diff --git a/settings.gradle.kts b/settings.gradle.kts index 8348d22..3cdc02a 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -19,6 +19,7 @@ pluginManagement { val gitHubToken: String? by settings val gitHubUrl: String by settings + println("Plugin: resolving settings mavenLocalOnly=$mavenLocalOnly, gitHubOnly=$gitHubOnly") if (mavenLocalOnly == "true" && gitHubOnly == mavenLocalOnly) { throw GradleException("Error: mavenLocalOnly AND gitHubOnly are both set to true.") } @@ -60,6 +61,7 @@ dependencyResolutionManagement { val gitHubToken: String? by settings val gitHubUrl: String by settings + println("Repos: resolving settings mavenLocalOnly=$mavenLocalOnly, gitHubOnly=$gitHubOnly") if (mavenLocalOnly == "true" && gitHubOnly == mavenLocalOnly) { throw GradleException("Error: mavenLocalOnly AND gitHubOnly are both set to true.") } diff --git a/settings.gradle.local.kts b/settings.gradle.local.kts deleted file mode 100644 index 8cbadd0..0000000 --- a/settings.gradle.local.kts +++ /dev/null @@ -1,67 +0,0 @@ -rootProject.name = "platform" - -pluginManagement { - repositories { - mavenLocal() - gradlePluginPortal() // This is used to resolve Node and other non-XTC related dependencies we need to build and run. - } - plugins { - id("org.xtclang.xtc-plugin") - id("com.github.node-gradle.node") - } -} - -@Suppress("UnstableApiUsage") -dependencyResolutionManagement { - repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) - repositories { - mavenLocal() - // TODO: May want to move this out into a specific node.workaround.settings.gradle.kts, - // or something, and apply that so that it just inlines here. Can't remember why - // that did not work on my first attempt. - - /** - * Patch the Node configuration, so that the Node plugin doesn't try to add hardcoded - * repositories to the Platform project during build. We are following the best-practice - * of forbidding any repository declaration anywhere else but project settings. The Node - * plugin does not. However, it's way more important to be able to specify an exact Node - * version, and integrate that with the build, than having to fall back on a system wide - * version of NodeJS that may or may not be installed on your machine, and may or may - * not work well the Platform build. The Platform build religiously declares all its - * required dependencies its repository, and SHOULD NEVER rely on any other system state - * of its host machine. This also very easily paves the way for integration testing, CI/CD, - * containerization and avoids contaminating your machine with multiple NodeJS versions. - * In 2024, we do not install and rely on system wide software on a dev machine, unless - * we are completely out of alternatives. - * - * For the NodeJS Gradle plugin, this is a known bug, and the workaround is the one - * recommended by the plugin developers: - * @see https://github.com/node-gradle/gradle-node-plugin/blob/main/docs/faq.md#is-this-plugin-compatible-with-centralized-repositories-declaration - */ - ivy { - name = "NodeJS" - setUrl("https://nodejs.org/dist/") - patternLayout { - artifact("v[revision]/[artifact](-v[revision]-[classifier]).[ext]") - ivy("v[revision]/ivy.xml") - } - metadataSources { - artifact() - } - content { - includeModule("org.nodejs", "node") - } - } - } -} - -listOfNotNull( - "kernel", - "common", - "host", - "platformDB", - "platformUI" -).forEach { - include(":$it") - logger.lifecycle("Added subproject '$it' to build.") -} From cc424ebf6617d3bbe97ca742d1cf5bd681b8225e Mon Sep 17 00:00:00 2001 From: Marcus Lagergren <1062473+lagergren@users.noreply.github.com> Date: Mon, 11 Mar 2024 12:43:04 +0100 Subject: [PATCH 07/13] Changed repo resolution logic. --- gradle.properties | 4 ++-- settings.gradle.kts | 28 ++++++++++++++-------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/gradle.properties b/gradle.properties index 6441254..8627244 100644 --- a/gradle.properties +++ b/gradle.properties @@ -21,5 +21,5 @@ gitHubUrl=https://maven.pkg.github.com/xtclang/xvm #gitHubUser= #gitHubToken= -mavenLocalOnly=true -#gitHubOnly=true +mavenLocalRepo=false +xtclangGitHubRepo=true diff --git a/settings.gradle.kts b/settings.gradle.kts index 3cdc02a..1100854 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -12,19 +12,19 @@ pluginManagement { repositories { - val gitHubOnly: String? by settings - val mavenLocalOnly: String? by settings + val mavenLocalRepo: String? by settings + val xtclangGitHubRepo: String? by settings val gitHubUser: String? by settings val gitHubToken: String? by settings val gitHubUrl: String by settings - println("Plugin: resolving settings mavenLocalOnly=$mavenLocalOnly, gitHubOnly=$gitHubOnly") - if (mavenLocalOnly == "true" && gitHubOnly == mavenLocalOnly) { - throw GradleException("Error: mavenLocalOnly AND gitHubOnly are both set to true.") + println("Plugin: mavenLocal=$mavenLocalRepo, xtclangGitHubRepo=$xtclangGitHubRepo") + if (mavenLocalRepo != "true" && xtclangGitHubRepo != "true") { + throw GradleException("Error: either or both of mavenResolveFromMavenLocal and mavenResolveFromXtcGitHub must be set.") } - if (mavenLocalOnly != "true") { + if (xtclangGitHubRepo == "true") { maven { url = uri(gitHubUrl) credentials { @@ -34,7 +34,7 @@ pluginManagement { } } - if (gitHubOnly != "true") { + if (mavenLocalRepo == "true") { // Define mavenLocal as an artifact repository (disabled by default) mavenLocal() } @@ -54,19 +54,19 @@ dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { // Define XTC org GitHub Maven as a plugin repository - val gitHubOnly: String? by settings - val mavenLocalOnly: String? by settings + val mavenLocalRepo: String? by settings + val xtclangGitHubRepo: String? by settings val gitHubUser: String? by settings val gitHubToken: String? by settings val gitHubUrl: String by settings - println("Repos: resolving settings mavenLocalOnly=$mavenLocalOnly, gitHubOnly=$gitHubOnly") - if (mavenLocalOnly == "true" && gitHubOnly == mavenLocalOnly) { - throw GradleException("Error: mavenLocalOnly AND gitHubOnly are both set to true.") + println("Repos: mavenLocal=$mavenLocalRepo, xtclangGitHubRepo=$xtclangGitHubRepo") + if (mavenLocalRepo != "true" && xtclangGitHubRepo != "true") { + throw GradleException("Error: either or both of mavenResolveFromMavenLocal and mavenResolveFromXtcGitHub must be set.") } - if (mavenLocalOnly != "true") { + if (xtclangGitHubRepo == "true") { maven { url = uri(gitHubUrl) credentials { @@ -76,7 +76,7 @@ dependencyResolutionManagement { } } - if (gitHubOnly != "true") { + if (mavenLocalRepo == "true") { // Define mavenLocal as an artifact repository (disabled by default) mavenLocal() } From 2cd43663295b2b97d782e90620b8eb29d1435ed4 Mon Sep 17 00:00:00 2001 From: Marcus Lagergren <1062473+lagergren@users.noreply.github.com> Date: Mon, 11 Mar 2024 13:34:58 +0100 Subject: [PATCH 08/13] Dev container (and prod container given artifacts) seems to be working. --- docker-compose.yaml | 4 ++-- docker/Dockerfile.platform | 14 +++++------- docker/entrypoint.sh | 46 ++++++++++++-------------------------- docker/platform-build.sh | 39 +++++++++++++++++--------------- 4 files changed, 43 insertions(+), 60 deletions(-) diff --git a/docker-compose.yaml b/docker-compose.yaml index 3a0d761..675f155 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -23,7 +23,7 @@ secrets: # gradle_cache is placed under /.root # we also add a platform volume to reuse ~/xqiz.it volumes: - build: + persistent: services: platform: @@ -39,7 +39,7 @@ services: secrets: - gradle_properties volumes: - - build:/cache + - persistent:/persistent env_file: - docker/.env - docker/.env.local diff --git a/docker/Dockerfile.platform b/docker/Dockerfile.platform index 108ec1e..a164dae 100644 --- a/docker/Dockerfile.platform +++ b/docker/Dockerfile.platform @@ -16,23 +16,21 @@ ARG GITHUB_BRANCH_PLATFORM ENV XTC_USER=$XTC_USER ENV XTC_USER_HOME=$XTC_USER_HOME -ENV XQIZIT_HOME=$XTC_USER_HOME/xqiz.it +ENV XTC_VOLUME=$XTC_USER_HOME/xtc +ENV XQIZIT_HOME=$XTC_VOLUME/xqiz.it ENV PLATFORM_HOME=$XQIZIT_HOME/platform ENV GITHUB_BRANCH_XVM=$GITHUB_BRANCH_XVM ENV GITHUB_BRANCH_PLATFORM=$GITHUB_BRANCH_PLATFORM -#ENV GRADLE_USER_HOME=$XTC_USER_HOME/build/.gradle +#ENV GRADLE_USER_HOME=$XTC_VOLUME/.gradle USER root RUN apt-get update && apt-get install --no-install-recommends -y \ iputils-ping jq sudo wget curl git openjdk-21-jdk -RUN curl --silent --location https://deb.nodesource.com/setup_21.x | sudo bash - -RUN apt-get -y --no-install-recommends install \ - nodejs - -# TOOD: Figure out why this isn't working. -# && npm -g install npm@${NPM_SAFE_VERSION} # && npm -g install yarn +# Actually, we don't need a node installation. The Gradle plugin handles everything. +#RUN curl --silent --location https://deb.nodesource.com/setup_21.x | sudo bash - +#RUN apt-get -y --no-install-recommends install nodejs && npm -g install npm@${NPM_SAFE_VERSION} # && npm -g install yarn # Install dev tools. We should separate these out later. RUN apt-get install --no-install-recommends -y emacs-nox diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index aa9de03..8cac562 100755 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -1,56 +1,38 @@ #!/bin/bash +# This is more of a devcontainer than a production container, since we set up a build enviromnment and +# make it possible to update and build sources from it. This should be split into separate responsibiliteis +# as echo "Entrypoint for Platform..." # Under root build we have have src and .gradle -sudo chown -R $XTC_USER:$XTC_USER /cache -if [ ! -e $HOME/build ]; then - echo "Linking cache volume as $HOME/build" - ln -s /cache $HOME/build -fi +export PLATFORM_DIR=$HOME/build -export GRADLE_USER_HOME=$HOME/build/.gradle -if [ ! -d $GRADLE_USER_HOME ]; then +# Ensure persistent docker volume is set up, and link our secrets and build and Gradle cache dirs from it. +sudo chown -R $XTC_USER:$XTC_USER /persistent +ln -s /persistent $PLATFORM_DIR +export GRADLE_USER_HOME=$HOME/.gradle +if [ ! -d $PLATFORM_DIR/gradle ]; then echo "Creating Gradle user home: $GRADLE_USER_HOME" - mkdir -p $GRADLE_USER_HOME + mkdir -p $PLATFORM_DIR/gradle +fi +ln -s $PLATFORM_DIR/gradle $GRADLE_USER_HOME +if [ ! -e $GRADLE_USER_HOME/gradle.properties ]; then + echo "Linking gradle.properties" ln -s /var/run/secrets/gradle_properties $GRADLE_USER_HOME/gradle.properties fi - source /usr/local/bin/platform-build.sh check_updated_source -# XTC user should be sudoer -# Port forwaring should just be in the container??? -#echo "User $USER executing pfctl under sudo privileges..." -#sudo pfctl -evf ~$XQIZIT_HOME/platform/port-forwarding.conf -#echo "Done." - -# -# If we want xtc-platform.localhost.xqiz.it to pingback from the host, put it /etc/hosts -# -# The domain name `xtc-platform.localhost.xqiz.it` should resolve to `127.0.0.1`. This allows the same xqiz.it -# cloud-hosted platform to be self-hosted on the `localhost` loop-back address, enabling local and disconnected -# development. -# -# If that address fails to resolve you may need to change the rules on you DNS server. For example, for Verizon routers -# you would need add an exception entry for `127.0.0.1` to your DNS Server settings: "Exceptions to DNS Rebind -# Protection" (Advanced - Network Settings - DNS Server) - ping -c 1 xtc-platform.localhost.xqiz.it if [ $? != 0 ]; then echo "Ping to localhost failed using xtc-platform.localhost.xqiz.it" exit 1 fi -# TODO Here is where we really want snapshot releases. -# TODO Right now the git clone is part of the container build. We should not do that, or at least map it to a reusable volume. -# First we just want to check that docker works for it, though. -#git clone --branch $GITHUB_BRANCH_PLATFORM --depth=1 https://github.com/xtclang/platform.git -#git clone --branch $GITHUB_BRANCH_XVM --depth=1 https://github.com/xtclang/xvm.git - if [ -z "${@}" ]; then echo "No extra entrypoint arguments. Container exiting from $0." else diff --git a/docker/platform-build.sh b/docker/platform-build.sh index 4422273..061146f 100644 --- a/docker/platform-build.sh +++ b/docker/platform-build.sh @@ -2,35 +2,38 @@ echo "Ensuring the platform is built." +export SRC_DIR=$PLATFORM_DIR/src function clone_platform() { - pushd $HOME/build - echo "Cloning to platform" - git clone --branch $GITHUB_BRANCH_PLATFORM --depth=1 https://github.com/xtclang/platform.git platform - echo "Writing last commit" - pushd platform - git rev-parse --verify HEAD > last_commit - popd + pushd $PLATFORM_DIR + echo "Cloning to platform" + git clone --branch $GITHUB_BRANCH_PLATFORM --depth=1 https://github.com/xtclang/platform.git src + echo "Writing last commit" + pushd $SRC_DIR + git rev-parse --verify HEAD > last_commit + popd popd } function check_updated_source() { - if [ -e $HOME/build/platform ]; then + echo "Checking for $SRC_DIR" + ls -lart $PLATFORM_DIR + if [ -e $SRC_DIR ]; then echo "Found existing source." - pushd $HOME/build/platform - _last_commit="unknown" - if [ -e last_commit ]; then - _last_commit=$(cat last_commit) - fi - _last_remote_commit=$(git rev-parse --verify HEAD) + pushd $SRC_DIR + _last_commit="unknown" + if [ -e last_commit ]; then + _last_commit=$(cat last_commit) + fi + _last_remote_commit=$(git ls-remote https://github.com/xtclang/platform.git platform-xtcplugin | awk '{ print $1 }') popd echo "last_commit : $_last_commit" echo "last_remote_commit: $_last_remote_commit" if [ "$_last_commit" != "$_last_remote_commit" ]; then - echo "Existing source out of date." - rm -fr $HOME/build/platform + echo "Existing source out of date. REMOVING existing source dir: $SRC_DIR" + rm -fr $SRC_DIR clone_platform else echo "Existing platform is up date - good!" @@ -43,7 +46,7 @@ function check_updated_source() { # Verify that the platform is built function build_platform() { - pushd $HOME/build/platform - ./gradlew build + pushd $SRC_DIR + ./gradlew build popd } From 66d0124b2505f0a5c64fe8cacef15501ea7cd4d0 Mon Sep 17 00:00:00 2001 From: Marcus Lagergren <1062473+lagergren@users.noreply.github.com> Date: Mon, 11 Mar 2024 13:42:42 +0100 Subject: [PATCH 09/13] Added port forwarding of http/https --- docker-compose.yaml | 2 +- docker/Dockerfile.platform | 3 --- docker/entrypoint.sh | 18 ++++++++++++------ docker/platform-build.sh | 2 +- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/docker-compose.yaml b/docker-compose.yaml index 675f155..6e1f3cd 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -48,5 +48,5 @@ services: - "xtc-platform.xqiz.it:127.0.0.10" ports: - "8080:80" - #- "8090:90" + - "8090:443" entrypoint: ['entrypoint.sh'] diff --git a/docker/Dockerfile.platform b/docker/Dockerfile.platform index a164dae..76823c6 100644 --- a/docker/Dockerfile.platform +++ b/docker/Dockerfile.platform @@ -79,7 +79,4 @@ RUN keytool \ WORKDIR $XTC_USER_HOME -#ADD https://api.github.com/repos/xtclang/platform/git/refs/heads/${GITHUB_BRANCH_PLATFORM} $HOME/github-version.json -#RUN git clone --branch $GITHUB_BRANCH_PLATFORM --depth=1 https://github.com/xtclang/platform.git - ENTRYPOINT ["entrypoint.sh"] diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index 8cac562..520cc2f 100755 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -5,6 +5,15 @@ # as echo "Entrypoint for Platform..." +function check_name_resolution() { + ping -c 1 xtc-platform.localhost.xqiz.it + if [ $? != 0 ]; then + echo "Ping to localhost failed using xtc-platform.localhost.xqiz.it" + exit 1 + fi + echo "xtc-platform.localhost.xqiz.it resolves and responds to ping." +} + # Under root build we have have src and .gradle export PLATFORM_DIR=$HOME/build @@ -25,14 +34,11 @@ fi source /usr/local/bin/platform-build.sh +check_name_resolution check_updated_source +check_platform_build -ping -c 1 xtc-platform.localhost.xqiz.it -if [ $? != 0 ]; then - echo "Ping to localhost failed using xtc-platform.localhost.xqiz.it" - exit 1 -fi - +# Pass any remaining args or CMD on to the run command. if [ -z "${@}" ]; then echo "No extra entrypoint arguments. Container exiting from $0." else diff --git a/docker/platform-build.sh b/docker/platform-build.sh index 061146f..a2e9a57 100644 --- a/docker/platform-build.sh +++ b/docker/platform-build.sh @@ -45,7 +45,7 @@ function check_updated_source() { } # Verify that the platform is built -function build_platform() { +function check_platform_build() { pushd $SRC_DIR ./gradlew build popd From c39058e942ffc19729b583162db553a591d7bbdd Mon Sep 17 00:00:00 2001 From: Marcus Lagergren <1062473+lagergren@users.noreply.github.com> Date: Mon, 11 Mar 2024 15:22:50 +0100 Subject: [PATCH 10/13] Docker changes --- README.md | 19 ++++++------------- docker-compose.yaml | 13 +++++++------ docker/Dockerfile.platform | 4 +--- docker/entrypoint.sh | 3 +++ 4 files changed, 17 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 4c3ce4f..79bb62e 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ as a container/Dockerfile/docker in the near future, so that you won't have to d 1. Create `xqiz.it` subdirectory under the user home directory for the platform persistent data. The subdirectory " platform" will be used to keep the platform operational information and subdirectory "users" for hosted applications. -2. Create a file `~/xqiz.it/port-forwarding.conf` with the following content: +2. Create a file `~/xqiz.it/platform/port-forwarding.conf` with the following content: ``` rdr pass on lo0 inet proto tcp from any to self port 80 -> 127.0.0.1 port 8080 @@ -103,14 +103,10 @@ as a container/Dockerfile/docker in the near future, so that you won't have to d inside your IDE, that you are sure knows about your wrapper script. Any IDE in which you import this project should pick that up and grab the appropriate runtimes and dependencies. -``` - xec -L lib/ lib/kernel.xtc [password] -``` - -10. *It is recommended that you *do not* keep a Gradle executable on your system path to build the project, but + *It is recommended that you *do not* keep a Gradle executable on your system path to build the project, but instead use the Gradle wrapper script (or its IDE integration) for every task you want to execute.* -11. Build and run the server. +10.Build and run the server. You can provide the password for your keystore as a Gradle property, by adding a line on the form `keystorePassword=` to the `$GRADLE_USER_HOME/gradle.properties`. This is @@ -126,7 +122,7 @@ Either build and run the server "the traditional way" (requires a local XDK inst ``` ./gradlew build - xec --verbose -L ./build/platform/ kernel.xqiz.it + xec --verbose -L ./build/platform/ kernel.xqiz.it [password] ``` or with the experimental: @@ -136,11 +132,8 @@ or with the experimental: ``` Note: the ./gradlew run task described in this paragraph is not meant as a production way of running -the platform. However, it can be quite handy to use for debugging purses, with "fork=false" in its -xtcRun configuraiton. That way you can just execute the run task from IntelliJ in Debug mode, and -just step into your executing platform server. - -TODO: ORG_GRADLE_PROJECT_keystorePassword= xec -L ./build/platform/ kernel +the platform. However, it can be quite handy to use for debugging poses with the debug = true flag +set in the XTC run configuration. 12. Open the [locally hosted platform web page](https://xtc-platform.localhost.xqiz.it): diff --git a/docker-compose.yaml b/docker-compose.yaml index 6e1f3cd..2ac4a6d 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -26,6 +26,7 @@ volumes: persistent: services: + # TODO: Create a platform that is more "dev container" style, and platform: image: ghcr.io/xtclang/xdk-platform:latest build: @@ -35,7 +36,6 @@ services: DOCKER_BUILDKIT: 1 PLATFORM_PASSWORD: ${PLATFORM_PASSWORD:-password} GITHUB_BRANCH_PLATFORM: ${GITHUB_BRANCH_PLATFORM:-platform-xtcplugin} - GITHUB_BRANCH_XVM: ${GITHUB_BRANCH_XVM:-master} secrets: - gradle_properties volumes: @@ -43,10 +43,11 @@ services: env_file: - docker/.env - docker/.env.local - extra_hosts: - - "xtc-platform.localhost.xqiz.it:127.0.0.1" - - "xtc-platform.xqiz.it:127.0.0.10" + hostname: 'xtc-platform.localhost.xqiz.it' + #extra_hosts: + # - "xtc-platform.localhost.xqiz.it:127.0.0.1" + # - "xtc-platform.xqiz.it:127.0.0.10" ports: - - "8080:80" - - "8090:443" + - "8080:8080" + - "8090:8090" entrypoint: ['entrypoint.sh'] diff --git a/docker/Dockerfile.platform b/docker/Dockerfile.platform index 76823c6..17129a6 100644 --- a/docker/Dockerfile.platform +++ b/docker/Dockerfile.platform @@ -16,12 +16,10 @@ ARG GITHUB_BRANCH_PLATFORM ENV XTC_USER=$XTC_USER ENV XTC_USER_HOME=$XTC_USER_HOME -ENV XTC_VOLUME=$XTC_USER_HOME/xtc -ENV XQIZIT_HOME=$XTC_VOLUME/xqiz.it +ENV XQIZIT_HOME=$XTC_USER_HOME/xqiz.it ENV PLATFORM_HOME=$XQIZIT_HOME/platform ENV GITHUB_BRANCH_XVM=$GITHUB_BRANCH_XVM ENV GITHUB_BRANCH_PLATFORM=$GITHUB_BRANCH_PLATFORM -#ENV GRADLE_USER_HOME=$XTC_VOLUME/.gradle USER root diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index 520cc2f..cebf1e3 100755 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -38,6 +38,9 @@ check_name_resolution check_updated_source check_platform_build +pushd $SRC_DIR +./gradlew run + # Pass any remaining args or CMD on to the run command. if [ -z "${@}" ]; then echo "No extra entrypoint arguments. Container exiting from $0." From 20fe7ab3575e27dcc074c49fbe08099a2e691dff Mon Sep 17 00:00:00 2001 From: Marcus Lagergren <1062473+lagergren@users.noreply.github.com> Date: Tue, 12 Mar 2024 09:18:56 +0100 Subject: [PATCH 11/13] Checking changed server names. --- README.md | 2 +- common/src/main/x/common/names.x | 2 +- docker-compose.yaml | 2 +- docker/platform-down.sh | 2 +- kernel/src/main/resources/cfg.json | 2 +- platformUI/src/main/x/platformUI.x | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 79bb62e..c15b2df 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ as a container/Dockerfile/docker in the near future, so that you won't have to d 4. Make sure you can ping the local platform address: ``` - ping xtc-platform.localhost.xqiz.it + ping xtc-platform2.localhost.xqiz.it ``` The domain name `xtc-platform.localhost.xqiz.it` should resolve to `127.0.0.1`. This allows the same xqiz.it diff --git a/common/src/main/x/common/names.x b/common/src/main/x/common/names.x index 9c6ff24..d3d7a15 100644 --- a/common/src/main/x/common/names.x +++ b/common/src/main/x/common/names.x @@ -32,6 +32,6 @@ package names { /** * The platform landing page URI. */ - static String PlatformUri = "xtc-platform.localhost.xqiz.it"; + static String PlatformUri = "xtc-platform2.localhost.xqiz.it"; } diff --git a/docker-compose.yaml b/docker-compose.yaml index 2ac4a6d..0e836f4 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -43,7 +43,7 @@ services: env_file: - docker/.env - docker/.env.local - hostname: 'xtc-platform.localhost.xqiz.it' + hostname: 'xtc-platform2.localhost.xqiz.it' #extra_hosts: # - "xtc-platform.localhost.xqiz.it:127.0.0.1" # - "xtc-platform.xqiz.it:127.0.0.10" diff --git a/docker/platform-down.sh b/docker/platform-down.sh index 45d2835..9d192d3 100755 --- a/docker/platform-down.sh +++ b/docker/platform-down.sh @@ -8,4 +8,4 @@ else fi echo "Taking down platform: '$_platform'..." -https://xtc-platform.localhost.xqiz.itecho "Done." +https://xtc-platform2.localhost.xqiz.itecho "Done." diff --git a/kernel/src/main/resources/cfg.json b/kernel/src/main/resources/cfg.json index b3a3d3f..848a64b 100644 --- a/kernel/src/main/resources/cfg.json +++ b/kernel/src/main/resources/cfg.json @@ -1,5 +1,5 @@ { -"hostName":"xtc-platform.localhost.xqiz.it", +"hostName":"xtc-platform2.localhost.xqiz.it", "httpPort":8080, "httpsPort":8090 } \ No newline at end of file diff --git a/platformUI/src/main/x/platformUI.x b/platformUI/src/main/x/platformUI.x index f47ba01..521be6a 100644 --- a/platformUI/src/main/x/platformUI.x +++ b/platformUI/src/main/x/platformUI.x @@ -43,7 +43,7 @@ module platformUI.xqiz.it { */ void configure(HttpServer server, String hostAddr, KeyStore keystore, Realm realm, AccountManager accountManager, HostManager hostManager, ErrorLog errors) { - // the 'hostAddr' is a full URI of the platform server, e.g. "xtc-platform.localhost.xqiz.it"; + // the 'hostAddr' is a full URI of the platform server, e.g. "xtc-platform2.localhost.xqiz.it"; // we need to extract the base domain ("localhost.xqiz.it") String baseDomain; if (Int dot := hostAddr.indexOf('.')) { From 6c94e5bd61cefe054c5466fd99652c3bca4b6f0f Mon Sep 17 00:00:00 2001 From: Marcus Lagergren <1062473+lagergren@users.noreply.github.com> Date: Thu, 14 Mar 2024 12:33:46 +0100 Subject: [PATCH 12/13] 'dev style' container works, except for reverse proxy setup, when avoiding the globally configured DNS mapping for the xqiz.it domain, which resolves to 127.0.0.1 which causes some trouble to reroute stuff. For the use case 'docker run --pull' from the Internet, we would ideally like to have the release flow for the XDK finished, and it also has a higher priority, so temporarily pausing to do that. --- .env | 13 ++++ README.md | 2 +- build.gradle.kts | 81 ++++++++++++------------ docker-compose.yaml | 38 +++++++++--- docker/.env | 4 -- docker/.env.local | 4 -- docker/Dockerfile.platform | 35 +++-------- docker/Dockerfile.platform.dev | 7 +++ docker/cert/README.md | 3 + docker/config/cfg.json | 5 ++ docker/entrypoint.sh | 50 --------------- docker/scripts/entrypoint.sh | 85 ++++++++++++++++++++++++++ docker/{ => scripts}/platform-build.sh | 0 docker/{ => scripts}/platform-down.sh | 0 docker/{ => scripts}/platform-up.sh | 0 15 files changed, 197 insertions(+), 130 deletions(-) create mode 100644 .env delete mode 100644 docker/.env delete mode 100644 docker/.env.local create mode 100644 docker/Dockerfile.platform.dev create mode 100644 docker/cert/README.md create mode 100644 docker/config/cfg.json delete mode 100755 docker/entrypoint.sh create mode 100755 docker/scripts/entrypoint.sh rename docker/{ => scripts}/platform-build.sh (100%) mode change 100644 => 100755 rename docker/{ => scripts}/platform-down.sh (100%) rename docker/{ => scripts}/platform-up.sh (100%) diff --git a/.env b/.env new file mode 100644 index 0000000..35750e4 --- /dev/null +++ b/.env @@ -0,0 +1,13 @@ +# +# This env file is not the same as the one in docker compose env_file sections. +# This sets a default enviromnent from the build, e.g. with build args. +# The others set environment variables to be used in the container. +# +COMPOSE_PROJECT_NAME=platform + +GITHUB_BRANCH_PLATFORM=${GITHUB_BRANCH:-platform-xtcplugin} + +PLATFORM_HOSTNAME=${PLATFORM_HOSTNAME:-xtc-platform.container.xqiz.it} +PLATFORM_HOSTNAME_DEV=${PLATFORM_HOSTNAME_DEV:-xtc-platform.container-dev.xqiz.it} + +XTC_VERSION=0.4.3 diff --git a/README.md b/README.md index c15b2df..79bb62e 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ as a container/Dockerfile/docker in the near future, so that you won't have to d 4. Make sure you can ping the local platform address: ``` - ping xtc-platform2.localhost.xqiz.it + ping xtc-platform.localhost.xqiz.it ``` The domain name `xtc-platform.localhost.xqiz.it` should resolve to `127.0.0.1`. This allows the same xqiz.it diff --git a/build.gradle.kts b/build.gradle.kts index d4cbfdf..6088858 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -32,8 +32,48 @@ dependencies { xtcModule(project(":platformCLI")) // runtime library path } -// TODO: Automatically run a pre-pass to verify that the XTC init script is in place (until we are -// on Maven Central (and have a new XDK release from "master"that supports the XTC Plugin). +/** + * Gather all compiled XTC modules from subprojects into a single location: $rootProject/build/platform. + */ +val commonXtcOutputDir = layout.buildDirectory.dir("platform") + +allprojects { + tasks.withType().configureEach { + //outputs.dir(commonXtcOutputDir) + doLast { + copy { + val compilerOutput = outputs.files.asFileTree + compilerOutput.forEach { + logger.lifecycle("XTC module output: ${it.absolutePath} -> ${commonXtcOutputDir.get().asFile.absolutePath}") + } + from(compilerOutput) + into(commonXtcOutputDir) + } + } + } +} + +/** + * This is the run configuration, which configures all xtcRun taks for the main source set. (runXtc, runAllXtc) + * The DSL for modules to run is a list of "module { }" elements or a list of moduleName("...") statements. + * To look at the DSL for all parts of the XTC build, you can use your IDE and browse the implementing + * classes. For example, there should be a hint in IntelliJ with the type for the xtcRun element and + * the modules element (DefaultXtcRuntimeExtension and XtcRuntimeExtension.XtcRunModule, respectively). + * It is a good way to understand how the build DSL works, so you can add your own powerful XTC build + * syntax constructs and nice syntactic sugar/shorthand for things you feel should be simpler to write. + */ +xtcRun { + debug = false // Set to true to get the launcher to pause and wait for a debugger to attach. + verbose = true + stdin = System.`in` // Prevent Gradle from eating stdin; make it interactive with the Gradle process that executes the kernel. + module { + moduleName = "kernel" + moduleArg(passwordProvider) + //findProperty("keystorePassword")?.also { + // moduleArg(it.toString()) + //} + } +} /** * Lazy password resolution provider. @@ -67,43 +107,6 @@ internal val passwordProvider: Provider = provider { findProperty("keystorePassword")?.toString() ?: "" } -/** - * Gather all compiled XTC modules from subprojects into a single location: $rootProject/build/platform. - */ -val commonXtcOutputDir = layout.buildDirectory.dir("platform") - -allprojects { - tasks.withType().configureEach { - doLast { - copy { - from(outputs.files.asFileTree) - into(commonXtcOutputDir) - } - } - } -} - -/** - * This is the run configuration, which configures all xtcRun taks for the main source set. (runXtc, runAllXtc) - * The DSL for modules to run is a list of "module { }" elements or a list of moduleName("...") statements. - * To look at the DSL for all parts of the XTC build, you can use your IDE and browse the implementing - * classes. For example, there should be a hint in IntelliJ with the type for the xtcRun element and - * the modules element (DefaultXtcRuntimeExtension and XtcRuntimeExtension.XtcRunModule, respectively). - * It is a good way to understand how the build DSL works, so you can add your own powerful XTC build - * syntax constructs and nice syntactic sugar/shorthand for things you feel should be simpler to write. - */ -xtcRun { - verbose = true - //fork = false - stdin = System.`in` // Prevent Gradle from eating stdin; make it interactive with the Gradle process that executes the kernel. - module { - moduleName = "kernel" - findProperty("keystorePassword")?.also { - moduleArg(it.toString()) - } - } -} - /** * Run the XTC Platform. Note that this is a Gradle job, and as such gets is dependencies from the module path * in the Gradle plugin for all source in the project. It will use a module path precisely including diff --git a/docker-compose.yaml b/docker-compose.yaml index 0e836f4..679950c 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -29,21 +29,45 @@ services: # TODO: Create a platform that is more "dev container" style, and platform: image: ghcr.io/xtclang/xdk-platform:latest + env_file: + - .env.local build: - context: docker - dockerfile: Dockerfile.platform + context: . + dockerfile: docker/Dockerfile.platform args: - DOCKER_BUILDKIT: 1 PLATFORM_PASSWORD: ${PLATFORM_PASSWORD:-password} - GITHUB_BRANCH_PLATFORM: ${GITHUB_BRANCH_PLATFORM:-platform-xtcplugin} + hostname: ${PLATFORM_HOSTNAME:-xtc-platform.local.xqiz.it} + ports: + - "8080:8080" + - "8090:8090" + + # + # Container that grabs, updates and persists source code for 'platform' + # from GitHub, and enabled cached builds in a container. + # + # A third option would be to start a dev container where the root directory + # of the platform project just is symlinked, so you can build and test yourself + # in a normal environment but get deployed elsewhere. + # + dev: + image: ghcr.io/xtclang/xdk-platform-dev:latest + depends_on: + - platform + build: + context: . + dockerfile: docker/Dockerfile.platform.dev + args: + #PLATFORM_PASSWORD: ${PLATFORM_PASSWORD:-password} + GITHUB_BRANCH_PLATFORM: $GITHUB_BRANCH_PLATFORM + environment: + DEV_CONTAINER: 1 secrets: - gradle_properties volumes: - persistent:/persistent env_file: - - docker/.env - - docker/.env.local - hostname: 'xtc-platform2.localhost.xqiz.it' + - .env.local + hostname: ${PLATFORM_HOSTNAME:-xtc-platform.local-dev.xqiz.it} #extra_hosts: # - "xtc-platform.localhost.xqiz.it:127.0.0.1" # - "xtc-platform.xqiz.it:127.0.0.10" diff --git a/docker/.env b/docker/.env deleted file mode 100644 index fd1bd5c..0000000 --- a/docker/.env +++ /dev/null @@ -1,4 +0,0 @@ -COMPOSE_PROJECT_NAME=platform - -GITHUB_BRANCH=${GITHUB_BRANCH:-master} -XTC_VERSION=0.4.3 diff --git a/docker/.env.local b/docker/.env.local deleted file mode 100644 index a899be7..0000000 --- a/docker/.env.local +++ /dev/null @@ -1,4 +0,0 @@ - -# TODO: This should be exclude from source control. - -PLATFORM_PASSWORD=${PLATFORM_PASSWORD:-password} diff --git a/docker/Dockerfile.platform b/docker/Dockerfile.platform index 17129a6..9f7ed71 100644 --- a/docker/Dockerfile.platform +++ b/docker/Dockerfile.platform @@ -1,8 +1,4 @@ -#FROM openjdk:21 -FROM ubuntu:24.04 - -ARG DOCKER_BUILDKIT=$DOCKER_BUILDKIT -ENV DOCKER_BUILD_KIT=$DOCKER_BUILDKIT +FROM openjdk:21-jdk-slim-bookworm ENV LANG C.UTF-8 ENV LC_ALL C.UTF-8 @@ -10,30 +6,16 @@ ENV DEBIAN_FRONTEND=noninteractive ARG XTC_USER=xtc ARG XTC_USER_HOME=/home/$XTC_USER -ARG NPM_SAFE_VERSION='npm@10.4.0' -ARG GITHUB_BRANCH_XVM -ARG GITHUB_BRANCH_PLATFORM ENV XTC_USER=$XTC_USER ENV XTC_USER_HOME=$XTC_USER_HOME ENV XQIZIT_HOME=$XTC_USER_HOME/xqiz.it ENV PLATFORM_HOME=$XQIZIT_HOME/platform -ENV GITHUB_BRANCH_XVM=$GITHUB_BRANCH_XVM -ENV GITHUB_BRANCH_PLATFORM=$GITHUB_BRANCH_PLATFORM - -USER root RUN apt-get update && apt-get install --no-install-recommends -y \ - iputils-ping jq sudo wget curl git openjdk-21-jdk - -# Actually, we don't need a node installation. The Gradle plugin handles everything. -#RUN curl --silent --location https://deb.nodesource.com/setup_21.x | sudo bash - -#RUN apt-get -y --no-install-recommends install nodejs && npm -g install npm@${NPM_SAFE_VERSION} # && npm -g install yarn + iputils-ping jq sudo wget curl git emacs-nox -# Install dev tools. We should separate these out later. -RUN apt-get install --no-install-recommends -y emacs-nox - -COPY *.sh /usr/local/bin +COPY docker/scripts/*.sh /usr/local/bin RUN useradd -ms /bin/bash $XTC_USER \ && passwd -d $XTC_USER \ @@ -44,11 +26,14 @@ RUN useradd -ms /bin/bash $XTC_USER \ USER $XTC_USER -# From README.md: Create xqiz.it subdirectory and config -RUN mkdir -p $PLATFORM_HOME && mkdir -p $XQIZIT_HOME/config +RUN mkdir -p $PLATFORM_HOME +RUN mkdir -p $XTC_USER_HOME/lib/xdk + +# Copy the local build (todo could also bind mount it) +COPY build/platform/* $XTC_USER_HOME/lib +COPY build/xtc/xdk/lib/* $XTC_USER_HOME/lib/xdk -# From README.md: Create port forwarding config. -COPY config/port-forwarding.conf $PLATFORM_HOME +# We should probably use a real XDK, # From README.md create: a self-signed certificate for the platform web server. For example: ARG PLATFORM_PASSWORD diff --git a/docker/Dockerfile.platform.dev b/docker/Dockerfile.platform.dev new file mode 100644 index 0000000..a111543 --- /dev/null +++ b/docker/Dockerfile.platform.dev @@ -0,0 +1,7 @@ +FROM ghcr.io/xtclang/xdk-platform:latest as platform + +ARG GITHUB_BRANCH_PLATFORM +ENV GITHUB_BRANCH_PLATFORM=$GITHUB_BRANCH_PLATFORM + +USER root + diff --git a/docker/cert/README.md b/docker/cert/README.md new file mode 100644 index 0000000..8a8df26 --- /dev/null +++ b/docker/cert/README.md @@ -0,0 +1,3 @@ +This directory contains prebuild self signed certificates for the XTC Platform hostname, and with the +key store password 'password'. They should not be used in production, naturally. The dev container +generates these values itself. \ No newline at end of file diff --git a/docker/config/cfg.json b/docker/config/cfg.json new file mode 100644 index 0000000..b4bbb37 --- /dev/null +++ b/docker/config/cfg.json @@ -0,0 +1,5 @@ +{ + "hostName": "xtc-platform.container.xqiz.it", + "httpPort": 8080, + "httpsPort": 8090 +} diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh deleted file mode 100755 index cebf1e3..0000000 --- a/docker/entrypoint.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/bash - -# This is more of a devcontainer than a production container, since we set up a build enviromnment and -# make it possible to update and build sources from it. This should be split into separate responsibiliteis -# as -echo "Entrypoint for Platform..." - -function check_name_resolution() { - ping -c 1 xtc-platform.localhost.xqiz.it - if [ $? != 0 ]; then - echo "Ping to localhost failed using xtc-platform.localhost.xqiz.it" - exit 1 - fi - echo "xtc-platform.localhost.xqiz.it resolves and responds to ping." -} - -# Under root build we have have src and .gradle - -export PLATFORM_DIR=$HOME/build - -# Ensure persistent docker volume is set up, and link our secrets and build and Gradle cache dirs from it. -sudo chown -R $XTC_USER:$XTC_USER /persistent -ln -s /persistent $PLATFORM_DIR -export GRADLE_USER_HOME=$HOME/.gradle -if [ ! -d $PLATFORM_DIR/gradle ]; then - echo "Creating Gradle user home: $GRADLE_USER_HOME" - mkdir -p $PLATFORM_DIR/gradle -fi -ln -s $PLATFORM_DIR/gradle $GRADLE_USER_HOME -if [ ! -e $GRADLE_USER_HOME/gradle.properties ]; then - echo "Linking gradle.properties" - ln -s /var/run/secrets/gradle_properties $GRADLE_USER_HOME/gradle.properties -fi - -source /usr/local/bin/platform-build.sh - -check_name_resolution -check_updated_source -check_platform_build - -pushd $SRC_DIR -./gradlew run - -# Pass any remaining args or CMD on to the run command. -if [ -z "${@}" ]; then - echo "No extra entrypoint arguments. Container exiting from $0." -else - echo "Handing over entrypoint arguments to exec: ${@}" - exec "${@}" -fi diff --git a/docker/scripts/entrypoint.sh b/docker/scripts/entrypoint.sh new file mode 100755 index 0000000..0e180f0 --- /dev/null +++ b/docker/scripts/entrypoint.sh @@ -0,0 +1,85 @@ +#!/bin/bash + +# This is more of a devcontainer than a production container, since we set up a build enviromnment and +# make it possible to update and build sources from it. This should be split into separate responsibiliteis +# as +echo "Entrypoint for Platform..." + +export PLATFORM_DIR=$HOME/build + +function check_file() { + if [ -z "$1" ]; then + echo "No file name provided to check." + exit 1 + fi + if [ ! -f "$1" ]; then + echo "File $1 not found." + exit 1 + fi + _len=$(state --printf "%s" "$1") + if [ $_len -le 0 ]; then + echo "File "$1" reports size as <= bytes." + exit 1 + fi +} + +function check_name_resolution() { + ping -c 1 xtc-platform.localhost.xqiz.it + if [ $? != 0 ]; then + echo "Ping to localhost failed using xtc-platform.localhost.xqiz.it" + exit 1 + fi + echo "xtc-platform.localhost.xqiz.it resolves and responds to ping." +} + +# Ensure persistent docker volume is set up, and link our secrets and build and Gradle cache dirs from it. +function ensure_volume() { + sudo chown -R $XTC_USER:$XTC_USER /persistent + ln -s /persistent $PLATFORM_DIR + export GRADLE_USER_HOME=$HOME/.gradle + if [ ! -d $PLATFORM_DIR/gradle ]; then + echo "Creating Gradle user home: $GRADLE_USER_HOME" + mkdir -p $PLATFORM_DIR/gradle + fi + ln -s $PLATFORM_DIR/gradle $GRADLE_USER_HOME + if [ ! -e $GRADLE_USER_HOME/gradle.properties ]; then + echo "Linking gradle.properties" + ln -s /var/run/secrets/gradle_properties $GRADLE_USER_HOME/gradle.properties + fi +} + +check_name_resolution + +if [ -n "$DEV_CONTAINER" ]; then + echo "Dev container detected - syncing out source." + ensure_volumes + source /usr/local/bin/platform-build.sh + check_updated_source + check_platform_build + pushd $SRC_DIR + ./gradlew run + popd +else + echo "Prod container detected - everything should be installed already." + echo "Verifying installation." + pushd $HOME/lib + check_file "common.xtc" + check_file "host.xtc" + check_file "kernel.xtc" + check_file "platformDB.xtc" + check_file "platformUI.xtc" + check_file "xdk/javatools.jar" + popd + + export "Setting up aliases." + alias xcc="java -jar $HOME/lib/xdk/javatools.jar xcc" + alias xec"=java -jar $HOME/lib/xdk/ +fi + +# Pass any remaining args or CMD on to the run command. +if [ -z "${@}" ]; then + echo "No extra entrypoint arguments. Container exiting from $0." +else + echo "Handing over entrypoint arguments to exec: ${@}" + exec "${@}" +fi diff --git a/docker/platform-build.sh b/docker/scripts/platform-build.sh old mode 100644 new mode 100755 similarity index 100% rename from docker/platform-build.sh rename to docker/scripts/platform-build.sh diff --git a/docker/platform-down.sh b/docker/scripts/platform-down.sh similarity index 100% rename from docker/platform-down.sh rename to docker/scripts/platform-down.sh diff --git a/docker/platform-up.sh b/docker/scripts/platform-up.sh similarity index 100% rename from docker/platform-up.sh rename to docker/scripts/platform-up.sh From abb08a0763cb86efe2f0e8b6e1b198343fdc3a2b Mon Sep 17 00:00:00 2001 From: Marcus Lagergren <1062473+lagergren@users.noreply.github.com> Date: Thu, 14 Mar 2024 14:08:07 +0100 Subject: [PATCH 13/13] Update. --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index 1100854..7c0168d 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -21,7 +21,7 @@ pluginManagement { println("Plugin: mavenLocal=$mavenLocalRepo, xtclangGitHubRepo=$xtclangGitHubRepo") if (mavenLocalRepo != "true" && xtclangGitHubRepo != "true") { - throw GradleException("Error: either or both of mavenResolveFromMavenLocal and mavenResolveFromXtcGitHub must be set.") + throw GradleException("Error: either or both of mavenLocalRepo and xtclangGitHubRepo must be set.") } if (xtclangGitHubRepo == "true") {