Application that runs in each Code FREAK Cloud Workspace. It uses a hybrid protocol based on GraphQL over Websockets and REST/HTTP. GraphQL is used for control messages and REST for native file upload/download. The application is written in Kotlin based on Spring Boot, WebFlux (Java RX) and Java GraphQL. It is shipped as self-contained container image that can be run on Docker, Kubernetes etc.
Current Features:
- Download/Upload files
- List and watch project files on the server
- Start/Stop processes and attach to them via websockets
The companion is used for Code FREAK's Cloud Workspaces feature which allows writing code in your browser and running it on the server. Each user receives its own "workspace" on the server which is created from multiple containers.
The companion is a standard Spring Boot web application which can be run locally for development/testing.
Please copy the file src/main/resources/application-dev.yml.dist to src/main/resources/application-dev.yml and make sure you are running the application with the dev profile.
To start the webserver on port 8080 (default) using Gradle run the following command:
SPRING_PROFILES_ACTIVE=dev ./gradlew bootRunThe GraphQL server is available at /graphql. You can find the full schema at src/main/resources/graphql/schema.graphqls.
During development, you can use the GraphiQL playground for testing at /playground. Make sure you have set up your src/main/resources/application-dev.yml correctly!
The server accepts both POST and Websocket queries.
The GQL websocket protocol is based on graphql-ws!
Expects a multipart/form-data request with one or multiple field with the name files.
Each file will be stored inside the container in /code by default.
The filename can also contain slashes to upload to sub-directories.
If the sub-directories do not exist the will be created.
If part of the sub-directory are existing files an exception will be thrown.
Existing files will be overridden without further questioning.
The server responds with 201 Created in case everything was uploaded properly.
Example request:
POST /files HTTP/1.1
Host: localhost:8080
Content-Type: multipart/form-data; boundary=----random-string-generated-by-browser
...
------random-string-generated-by-browser
Content-Disposition: form-data; name="files"; filename="main.c"
...
------random-string-generated-by-browser
Content-Disposition: form-data; name="files"; filename="lib/func.c"
Content-Type: application/x-object
...
------random-string-generated-by-browser
Allows downloading a file specified by {filepath}, e.g. /files/main.c.
The will serve the workspace file (if it exists) with the one of the following mime-types:
text/plainfor all textual files- The proper mime type for images (mime starts with
image/*) application/octet-streamfor everything else
Download a tar archive that contains all project files.
You can optionally specify a ?filter= parameter which allows narrowing down the files contained in the final archive. So /files-tar?filter=**/*.txt will make the archive contain only all .txt files. The pattern must be a valid AntPathMatcher.
Upload a tar archive which WILL REPLACE ALL EXISTING PROJECT FILES! So uploading an empty archive will delete everything!
The body of the request must be a single 3valid application/x-tar archive (no multipart request, form-data etc. needed!).
The request will be upgraded to Websocket!
After starting a process using the GraphQL startProcess mutation you can attach to the process via this endpoint. Please supply the process-id returned from the start mutation.
./gradlew checkTo build the container image we use Google's Jib.
The image will be built to your local Docker daemon as ghcr.io/codefreak/codefreak-cloud-companion with the following command:
./gradlew jibDockerBuildSee the LICENSE file that is shipped with the source code.