diff --git a/.env b/.env index c749a6b..f1447bf 100644 --- a/.env +++ b/.env @@ -1,4 +1,6 @@ PORT=8043 FLASK_DEBUG=true SECRET_KEY=secret_key +FLASK_SECRET_KEY=secret_key DEVEL=true +FLASK_GOOGLE_SEARCH_API_KEY=insecure_development_key diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml new file mode 100644 index 0000000..2ad706c --- /dev/null +++ b/.github/workflows/deploy.yaml @@ -0,0 +1,93 @@ +name: Deploy site + +on: + push: + branches: + - main + +env: + CHARMCRAFT_ENABLE_EXPERIMENTAL_EXTENSIONS: true + ROCKCRAFT_ENABLE_EXPERIMENTAL_EXTENSIONS: true + +jobs: + pack-charm: + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v3 + + - name: Setup LXD + uses: canonical/setup-lxd@main + + - name: Setup Charmcraft + run: sudo snap install charmcraft --classic --channel=latest/edge + + - name: Fetch libs + run: | + cd ./charm + charmcraft fetch-libs + + - name: Pack charm + run: charmcraft pack -v --project-dir ./charm + + - name: Upload charm + uses: actions/upload-artifact@v3 + with: + name: anbox-cloud-io-charm + path: ./*.charm + + pack-rock: + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v3 + + - name: Use Node.js + uses: actions/setup-node@v3 + + - name: Build Assets + run: | + yarn install + yarn run build + + - name: Setup LXD + uses: canonical/setup-lxd@main + + - name: Setup Rockcraft + run: sudo snap install rockcraft --classic --channel=latest/edge + + - name: Pack Rock + run: rockcraft pack + + - name: Upload Rock + uses: actions/upload-artifact@v3 + with: + name: anbox-cloud-io-rock + path: ./*.rock + + publish-image: + runs-on: ubuntu-latest + needs: pack-rock + outputs: + image_url: ${{ steps.set_image_url.outputs.image_url }} + steps: + - name: Get Rock + uses: actions/download-artifact@v3 + with: + name: anbox-cloud-io-rock + + - name: Set image URL + id: set_image_url + run: echo "image_url=ghcr.io/canonical/anbox-cloud.io:$(date +%s)-${GITHUB_SHA:0:7}" >> $GITHUB_OUTPUT + + - name: Push to GHCR + run: skopeo --insecure-policy copy oci-archive:$(ls *.rock) docker://${{ steps.set_image_url.outputs.image_url }} --dest-creds "canonical:${{ secrets.GITHUB_TOKEN }}" + + deploy: + runs-on: ubuntu-latest + needs: [pack-charm, publish-image] + steps: + - name: Workflow run ID + run : echo ${{ github.run_id }} + - name: Image URL + run : echo ${{ needs.publish-image.outputs.image_url }} diff --git a/.gitignore b/.gitignore index c0ea1c7..eaaf42a 100644 --- a/.gitignore +++ b/.gitignore @@ -47,6 +47,7 @@ package-lock.json *.snap _site/ *.*.map +*.rock # [env] Local environment settings .docker-project diff --git a/app.py b/app.py new file mode 100644 index 0000000..59928dd --- /dev/null +++ b/app.py @@ -0,0 +1,9 @@ +# This file serves as an entry point for the rock image. It is required by the PaaS app charmer. +# The flask application must be defined in this file under the variable name `app`. +# See - https://documentation.ubuntu.com/rockcraft/en/latest/reference/extensions/flask-framework/ +import os + +# canonicalwebteam.flask-base requires SECRET_KEY to be set, this must be done before importing the app +os.environ["SECRET_KEY"] = os.environ["FLASK_SECRET_KEY"] + +from webapp.app import app diff --git a/charm/.gitignore b/charm/.gitignore new file mode 100644 index 0000000..75188f3 --- /dev/null +++ b/charm/.gitignore @@ -0,0 +1,10 @@ +venv/ +build/ +*.charm +.tox/ +.coverage +__pycache__/ +*.py[cod] +.idea +.vscode/ +lib/ diff --git a/charm/charmcraft.yaml b/charm/charmcraft.yaml new file mode 100644 index 0000000..8a66213 --- /dev/null +++ b/charm/charmcraft.yaml @@ -0,0 +1,26 @@ +name: anbox-cloud-io + +type: charm + +bases: + - build-on: + - name: ubuntu + channel: "22.04" + run-on: + - name: ubuntu + channel: "22.04" + +summary: This is the charm for the anbox-cloud.io website. + +description: This is the charm for the anbox-cloud.io website. + +extensions: + - flask-framework + +config: + options: + google-search-api-key: + description: Google search API key + type: string + required: true + default: "" diff --git a/charm/requirements.txt b/charm/requirements.txt new file mode 100644 index 0000000..c73cf0c --- /dev/null +++ b/charm/requirements.txt @@ -0,0 +1 @@ +paas-app-charmer==1.0.4 diff --git a/charm/src/charm.py b/charm/src/charm.py new file mode 100755 index 0000000..5212a3a --- /dev/null +++ b/charm/src/charm.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python3 +# Copyright 2024 Canonical Ltd. +# See LICENSE file for licensing details. + +"""Flask Charm entrypoint.""" + +import logging +import typing + +import ops +import paas_app_charmer.flask + +logger = logging.getLogger(__name__) + + +class FlaskCharm(paas_app_charmer.flask.Charm): + """Flask Charm service.""" + + def __init__(self, *args: typing.Any) -> None: + """Initialize the instance. + + Args: + args: passthrough to CharmBase. + """ + super().__init__(*args) + + +if __name__ == "__main__": + ops.main.main(FlaskCharm) diff --git a/konf/site.yaml b/konf/site.yaml index a68e6c9..027e07b 100644 --- a/konf/site.yaml +++ b/konf/site.yaml @@ -6,11 +6,16 @@ env: - name: SENTRY_DSN value: https://37706e022f2841448dbb094990420522@sentry.is.canonical.com//23 - - name: SEARCH_API_KEY + - name: FLASK_GOOGLE_SEARCH_API_KEY secretKeyRef: key: google-custom-search-key name: google-api + - name: FLASK_SECRET_KEY + secretKeyRef: + key: anbox-cloud-io + name: secret-keys + production: replicas: 5 nginxConfigurationSnippet: | diff --git a/rockcraft.yaml b/rockcraft.yaml new file mode 100644 index 0000000..15ce3bb --- /dev/null +++ b/rockcraft.yaml @@ -0,0 +1,24 @@ +name: anbox-cloud-io +base: ubuntu@22.04 +version: "0.1" +summary: Scalable Android in the cloud +description: | + Anbox Cloud lets you stream mobile apps securely, at any scale, to any + device letting you focus on your apps. Run Android in system containers, + not emulators, on AWS, OCI, Azure, GCP or your private cloud with ultra + low streaming latency. +platforms: + amd64: + +extensions: + - flask-framework + +parts: + flask-framework/install-app: + prime: + - flask/app/.env + - flask/app/app.py + - flask/app/webapp + - flask/app/templates + - flask/app/static + - flask/app/redirects.yaml