diff --git a/.github/workflows/publish_arm.yml b/.github/workflows/publish_arm.yml
new file mode 100644
index 0000000000..b47cc9d1d4
--- /dev/null
+++ b/.github/workflows/publish_arm.yml
@@ -0,0 +1,68 @@
+name: Publish ARM
+
+on:
+ workflow_run:
+ workflows: ["Full Clients Publish"]
+ types:
+ - completed
+
+jobs:
+ docker-image-grid-http-server:
+ if: ${{ github.event.workflow_run.conclusion == 'success' }}
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ packages: write
+ steps:
+ - name: 'Get tag'
+ id: tag
+ uses: actions/github-script@v6
+ with:
+ result-encoding: string
+ script: |
+ let run = await github.rest.actions.getWorkflowRun({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ run_id: context.payload.workflow_run.id,
+ });
+ return run.data.head_branch;
+
+ - name: Checkout the repo
+ uses: actions/checkout@v3
+ with:
+ ref: ${{ steps.tag.outputs.result }}
+
+ - name: Set up QEMU
+ uses: docker/setup-qemu-action@v2
+
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v2
+
+ - name: Log in to the Container registry
+ uses: docker/login-action@v2.1.0
+ with:
+ registry: ghcr.io
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Extract metadata for Docker
+ id: meta
+ uses: docker/metadata-action@v4
+ with:
+ context: git
+ images: ghcr.io/${{ github.repository_owner }}/grid_http_server
+ flavor: |
+ suffix=-arm,onlatest=true
+ tags: |
+ type=semver,pattern={{version}}
+
+ - name: Build and push Docker image
+ uses: docker/build-push-action@v4
+ with:
+ context: packages/grid_http_server/arm
+ push: true
+ platforms: linux/arm64,linux/armhf
+ tags: ${{ steps.meta.outputs.tags }}
+ labels: ${{ steps.meta.outputs.labels }}
+ build-args: |
+ GRID_VERSION=${{ steps.tag.outputs.result }}
diff --git a/packages/grid_http_server/arm/Dockerfile b/packages/grid_http_server/arm/Dockerfile
new file mode 100644
index 0000000000..660915b979
--- /dev/null
+++ b/packages/grid_http_server/arm/Dockerfile
@@ -0,0 +1,11 @@
+FROM alpine AS build
+
+ARG GRID_VERSION
+RUN apk add nodejs npm curl python3 build-base && npm install --global yarn && yarn add @threefold/grid_http_server@${GRID_VERSION}
+
+FROM alpine
+RUN apk add nodejs npm curl && npm install --global yarn
+COPY --from=build /node_modules /node_modules
+COPY --from=build /package.json /yarn.lock /
+
+ENTRYPOINT [ "yarn" ]
diff --git a/packages/playground/src/components/vm_deployment_table.vue b/packages/playground/src/components/vm_deployment_table.vue
index e8b9527814..a37f839f71 100644
--- a/packages/playground/src/components/vm_deployment_table.vue
+++ b/packages/playground/src/components/vm_deployment_table.vue
@@ -36,6 +36,10 @@
{{ item.value[0].planetary || "-" }}
+
+ {{ item.value[0].interfaces[0].ip || "-" }}
+
+
@@ -112,6 +116,7 @@ const filteredHeaders = computed(() => {
{ title: "Public IPv4", key: "ipv4" },
{ title: "Public IPv6", key: "ipv6" },
{ title: "Planetary Network IP", key: "planetary" },
+ { title: "WireGuard", key: "wireguard" },
{ title: "Flist", key: "flist" },
{ title: "Cost", key: "billing" },
{ title: "Actions", key: "actions" },
@@ -129,6 +134,8 @@ const filteredHeaders = computed(() => {
ProjectName.Nextcloud,
] as string[];
+ const WireguardSolutions = [ProjectName.VM, ProjectName.Fullvm, ProjectName.Umbrel] as string[];
+
const flistSolutions = [ProjectName.VM, ProjectName.Fullvm] as string[];
if (!IPV6Solutions.includes(props.projectName)) {
@@ -139,6 +146,10 @@ const filteredHeaders = computed(() => {
headers = headers.filter(h => h.key !== "ipv4");
}
+ if (!WireguardSolutions.includes(props.projectName)) {
+ headers = headers.filter(h => h.key !== "wireguard");
+ }
+
if (!flistSolutions.includes(props.projectName)) {
headers = headers.filter(h => h.key !== "flist");
}
diff --git a/packages/playground/src/weblets/tf_deployment_list.vue b/packages/playground/src/weblets/tf_deployment_list.vue
index 46fc819cca..36e6251b81 100644
--- a/packages/playground/src/weblets/tf_deployment_list.vue
+++ b/packages/playground/src/weblets/tf_deployment_list.vue
@@ -248,7 +248,9 @@
'http://' +
(item.value[0].publicIP?.ip
? item.value[0].publicIP.ip.slice(0, -3)
- : '[' + item.value[0].planetary + ']')
+ : item.value[0].planetary
+ ? '[' + item.value[0].planetary + ']'
+ : item.value[0].interfaces[0].ip)
"
/>
diff --git a/packages/playground/src/weblets/tf_umbrel.vue b/packages/playground/src/weblets/tf_umbrel.vue
index dad7712da1..1c9bd1df06 100644
--- a/packages/playground/src/weblets/tf_umbrel.vue
+++ b/packages/playground/src/weblets/tf_umbrel.vue
@@ -65,7 +65,14 @@
-
+
import { computed, type Ref, ref } from "vue";
+import Network from "../components/networks.vue";
import { useLayout } from "../components/weblet_layout.vue";
import { useProfileManager } from "../stores";
import type { Farm, Flist, solutionFlavor as SolutionFlavor } from "../types";
@@ -142,6 +150,9 @@ const name = ref(generateName({ prefix: "um" }));
const username = ref("admin");
const password = ref(generatePassword());
const ipv4 = ref(false);
+const planetary = ref(true);
+const wireguard = ref(false);
+const network = ref();
const solution = ref() as Ref;
const farm = ref() as Ref;
const loadingFarm = ref(false);
@@ -166,6 +177,9 @@ async function deploy() {
const vm = await deployVM(grid!, {
name: name.value,
+ network: {
+ addAccess: wireguard.value,
+ },
machines: [
{
name: name.value,
@@ -186,7 +200,7 @@ async function deploy() {
farmId: farm.value.farmID,
farmName: farm.value.name,
country: farm.value.country,
- planetary: true,
+ planetary: planetary.value,
publicIpv4: ipv4.value,
envs: [
{ key: "SSH_KEY", value: profileManager.profile!.ssh },