Skip to content

Commit 4d9a08b

Browse files
authored
Enable multi-node build (#431)
- arm64 qemu is unstable (see Update build to use native arm64 runners, remove qemu. NVIDIA/cuda-quantum#3127) - hasnt improved for months now, so switching to building locally with native arm - multi node builds goof up the bake output without image name, so we rebuild from the service key
1 parent f2b750a commit 4d9a08b

File tree

5 files changed

+313
-15
lines changed

5 files changed

+313
-15
lines changed

.github/workflows/clearfog-ubuntu-iso.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ permissions:
1616
jobs:
1717
build_iso:
1818
runs-on: self-hosted
19+
if: ${{ github.event.workflow_run.conclusion == 'success' }}
1920
steps:
2021
- name: Check out the repo
2122
uses: actions/checkout@v2

.github/workflows/docker-image.yml

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,6 @@ jobs:
3636
-
3737
name: Test release tag version and channel
3838
run: echo "RELEASE_VERSION == $RELEASE_VERSION CHANNEL == $RELEASE_CHANNEL"
39-
-
40-
name: Set up Docker Buildx
41-
id: buildx
42-
uses: docker/setup-buildx-action@v3
4339
-
4440
name: Authenticate to ghcr
4541
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
@@ -49,7 +45,7 @@ jobs:
4945
-
5046
name: Build and push with bake action
5147
id: bake
52-
uses: docker/bake-action@v5
48+
uses: docker/bake-action@v6
5349
with:
5450
sbom: true
5551
files: |
@@ -63,18 +59,20 @@ jobs:
6359
wifi_uplink*.context=./wifi_uplink
6460
ppp*.context=./ppp
6561
push: ${{ github.event_name == 'workflow_run' && github.ref_name == 'main' || env.RELEASE_CHANNEL != '' && github.event_name == 'push' }}
66-
provenance: false
62+
provenance: true
6763

6864
- name: Extract images and digests
6965
id: extract_info
7066
run: |
7167
echo 'IMAGE_INFO<<EOF' >> $GITHUB_OUTPUT
7268
echo '${{ steps.bake.outputs.metadata }}' | \
7369
jq -r '[ to_entries[] |
74-
select(.key != "buildx.build.warnings") |
75-
.value |
76-
(.["image.name"] | split(",")[]) as $name |
77-
$name + "@" + .["containerimage.digest"]
70+
select(.key != "buildx.build.warnings" and .value["containerimage.digest"]) |
71+
{
72+
name: ("ghcr.io/spr-networks/super_" + .key + ":${{ env.RELEASE_VERSION }}${{ env.RELEASE_CHANNEL }}"),
73+
digest: .value["containerimage.digest"]
74+
} |
75+
.name + "@" + .digest
7876
] | join(" ")' >> $GITHUB_OUTPUT
7977
echo 'EOF' >> $GITHUB_OUTPUT
8078
@@ -91,7 +89,14 @@ jobs:
9189
- name: Prepare Attestation Matrix
9290
id: container_digests
9391
run: |
94-
matrix=$(echo ${{ steps.extract_info.outputs.IMAGE_INFO }} | jq -R -s -c 'split(" ") | map(split("@") | {name: (.[0] | split(":")[0]), digest: .[1] | rtrimstr("\n") }) | group_by(.name) | map(.[0]) ')
92+
matrix=$(echo '${{ steps.bake.outputs.metadata }}' | \
93+
jq -c '[ to_entries[] |
94+
select(.key != "buildx.build.warnings" and .value["containerimage.digest"]) |
95+
{
96+
name: ("ghcr.io/spr-networks/super_" + .key ),
97+
digest: .value["containerimage.digest"]
98+
}
99+
]')
95100
echo "matrix=$matrix" >> $GITHUB_OUTPUT
96101
outputs:
97102
container_digests: ${{ steps.container_digests.outputs.matrix}}
@@ -104,17 +109,16 @@ jobs:
104109
attestations: write
105110
needs: build-images
106111
if: ${{ github.event_name == 'push' || github.event_name == 'workflow_run' || github.event_name == 'workflow_dispatch' }}
107-
runs-on: ubuntu-24.04
112+
runs-on: self-hosted
108113
strategy:
109114
matrix:
110115
image: ${{ fromJSON(needs.build-images.outputs.container_digests) }}
111-
112116
steps:
113117
-
114118
name: Authenticate to ghcr
115119
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
116120
- name: Attest Build Provenance
117-
uses: actions/attest-build-provenance@v1
121+
uses: actions/attest-build-provenance@v2
118122
with:
119123
subject-name: ${{ matrix.image.name }}
120124
subject-digest: ${{ matrix.image.digest }}

.github/workflows/pi-ubuntu-iso.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ permissions:
1616
jobs:
1717
build_iso:
1818
runs-on: self-hosted
19+
if: ${{ github.event.workflow_run.conclusion == 'success' }}
1920

2021
steps:
2122
- name: Check out the repo
Lines changed: 292 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,292 @@
1+
import React, { useContext, useState, useEffect } from 'react'
2+
3+
import { pluginAPI } from 'api'
4+
import { AlertContext } from 'layouts/Admin'
5+
6+
import {
7+
Button,
8+
ButtonText,
9+
Checkbox,
10+
CheckboxIcon,
11+
CheckboxIndicator,
12+
CheckboxLabel,
13+
FormControl,
14+
FormControlHelper,
15+
FormControlHelperText,
16+
FormControlLabel,
17+
FormControlLabelText,
18+
Input,
19+
InputField,
20+
VStack,
21+
HStack,
22+
Text
23+
} from '@gluestack-ui/themed'
24+
25+
const EditPlugin = ({ plugin, onClose, notifyChange, ...props }) => {
26+
const contextType = useContext(AlertContext)
27+
28+
const [Name, setName] = useState(plugin.Name || '')
29+
const [URI, setURI] = useState(plugin.URI || '')
30+
const [UnixPath, setUnixPath] = useState(plugin.UnixPath || '')
31+
const [ComposeFilePath, setComposeFilePath] = useState(plugin.ComposeFilePath || '')
32+
const [Enabled, setEnabled] = useState(plugin.Enabled || false)
33+
const [GitURL, setGitURL] = useState(plugin.GitURL || '')
34+
const [HasUI, setHasUI] = useState(plugin.HasUI || false)
35+
const [InstallTokenPath, setInstallTokenPath] = useState(plugin.InstallTokenPath || '')
36+
const [ScopedPaths, setScopedPaths] = useState(plugin.ScopedPaths ? plugin.ScopedPaths.join(', ') : '')
37+
38+
const handleChange = (name, value) => {
39+
if (name == 'Name') {
40+
setName(value)
41+
}
42+
if (name == 'URI') {
43+
setURI(value)
44+
}
45+
if (name == 'UnixPath') {
46+
setUnixPath(value)
47+
}
48+
if (name == 'ComposeFilePath') {
49+
setComposeFilePath(value)
50+
}
51+
if (name == 'GitURL') {
52+
setGitURL(value)
53+
}
54+
if (name == 'InstallTokenPath') {
55+
setInstallTokenPath(value)
56+
}
57+
if (name == 'ScopedPaths') {
58+
setScopedPaths(value)
59+
}
60+
}
61+
62+
const handleSubmit = (e) => {
63+
e.preventDefault()
64+
65+
// Convert ScopedPaths string to array
66+
const scopedPathsArray = ScopedPaths
67+
? ScopedPaths.split(',').map(path => path.trim()).filter(path => path.length > 0)
68+
: []
69+
70+
let updatedPlugin = {
71+
...plugin,
72+
Name,
73+
URI,
74+
UnixPath,
75+
ComposeFilePath,
76+
Enabled,
77+
GitURL,
78+
HasUI,
79+
InstallTokenPath,
80+
ScopedPaths: scopedPathsArray
81+
}
82+
83+
pluginAPI
84+
.update(updatedPlugin)
85+
.then((res) => {
86+
contextType.success('Plugin updated successfully')
87+
if (notifyChange) {
88+
notifyChange()
89+
}
90+
if (onClose) {
91+
onClose()
92+
}
93+
})
94+
.catch((err) => {
95+
contextType.error(`Failed to update plugin: ${err.message}`)
96+
})
97+
}
98+
99+
return (
100+
<VStack space="md">
101+
<FormControl>
102+
<FormControlLabel>
103+
<FormControlLabelText>Name</FormControlLabelText>
104+
</FormControlLabel>
105+
106+
<Input variant="underlined">
107+
<InputField
108+
type="text"
109+
name="Name"
110+
value={Name}
111+
onChangeText={(value) => handleChange('Name', value)}
112+
/>
113+
</Input>
114+
115+
<FormControlHelper>
116+
<FormControlHelperText>
117+
Plugin identifier name
118+
</FormControlHelperText>
119+
</FormControlHelper>
120+
</FormControl>
121+
<FormControl>
122+
<FormControlLabel>
123+
<FormControlLabelText>URI</FormControlLabelText>
124+
</FormControlLabel>
125+
126+
<Input variant="underlined">
127+
<InputField
128+
type="text"
129+
name="URI"
130+
value={URI}
131+
onChangeText={(value) => handleChange('URI', value)}
132+
/>
133+
</Input>
134+
135+
<FormControlHelper>
136+
<FormControlHelperText>
137+
{'Plugin will be @ "http://spr/plugins/' + (URI || 'URI') + '"'}
138+
</FormControlHelperText>
139+
</FormControlHelper>
140+
</FormControl>
141+
142+
<FormControl>
143+
<FormControlLabel>
144+
<FormControlLabelText>UNIX Path</FormControlLabelText>
145+
</FormControlLabel>
146+
147+
<Input variant="underlined">
148+
<InputField
149+
type="text"
150+
value={UnixPath}
151+
onChangeText={(value) => handleChange('UnixPath', value)}
152+
/>
153+
</Input>
154+
155+
<FormControlHelper>
156+
<FormControlHelperText>
157+
Plugin pathname for unix socket
158+
</FormControlHelperText>
159+
</FormControlHelper>
160+
</FormControl>
161+
162+
<FormControl>
163+
<FormControlLabel>
164+
<FormControlLabelText>ComposeFilePath</FormControlLabelText>
165+
</FormControlLabel>
166+
167+
<Input variant="underlined">
168+
<InputField
169+
type="text"
170+
value={ComposeFilePath}
171+
onChangeText={(value) => handleChange('ComposeFilePath', value)}
172+
/>
173+
</Input>
174+
175+
<FormControlHelper>
176+
<FormControlHelperText>
177+
Docker Compose Filepath
178+
</FormControlHelperText>
179+
</FormControlHelper>
180+
</FormControl>
181+
182+
<FormControl>
183+
<FormControlLabel>
184+
<FormControlLabelText>Git URL</FormControlLabelText>
185+
</FormControlLabel>
186+
187+
<Input variant="underlined">
188+
<InputField
189+
type="text"
190+
value={GitURL}
191+
onChangeText={(value) => handleChange('GitURL', value)}
192+
/>
193+
</Input>
194+
195+
<FormControlHelper>
196+
<FormControlHelperText>
197+
Git repository URL for the plugin
198+
</FormControlHelperText>
199+
</FormControlHelper>
200+
</FormControl>
201+
202+
<FormControl>
203+
<FormControlLabel>
204+
<FormControlLabelText>Install Token Path</FormControlLabelText>
205+
</FormControlLabel>
206+
207+
<Input variant="underlined">
208+
<InputField
209+
type="text"
210+
value={InstallTokenPath}
211+
onChangeText={(value) => handleChange('InstallTokenPath', value)}
212+
/>
213+
</Input>
214+
215+
<FormControlHelper>
216+
<FormControlHelperText>
217+
Path to installation token file
218+
</FormControlHelperText>
219+
</FormControlHelper>
220+
</FormControl>
221+
222+
<FormControl>
223+
<FormControlLabel>
224+
<FormControlLabelText>Scoped Paths</FormControlLabelText>
225+
</FormControlLabel>
226+
227+
<Input variant="underlined">
228+
<InputField
229+
type="text"
230+
value={ScopedPaths}
231+
onChangeText={(value) => handleChange('ScopedPaths', value)}
232+
/>
233+
</Input>
234+
235+
<FormControlHelper>
236+
<FormControlHelperText>
237+
Comma-separated list of paths the plugin can access
238+
</FormControlHelperText>
239+
</FormControlHelper>
240+
</FormControl>
241+
242+
<FormControl>
243+
<Checkbox
244+
value={Enabled}
245+
onChange={setEnabled}
246+
>
247+
<CheckboxIndicator mr="$2">
248+
<CheckboxIcon />
249+
</CheckboxIndicator>
250+
<CheckboxLabel>Enabled</CheckboxLabel>
251+
</Checkbox>
252+
253+
<FormControlHelper>
254+
<FormControlHelperText>
255+
Enable or disable the plugin
256+
</FormControlHelperText>
257+
</FormControlHelper>
258+
</FormControl>
259+
260+
<FormControl>
261+
<Checkbox
262+
value={HasUI}
263+
onChange={setHasUI}
264+
>
265+
<CheckboxIndicator mr="$2">
266+
<CheckboxIcon />
267+
</CheckboxIndicator>
268+
<CheckboxLabel>Has UI</CheckboxLabel>
269+
</Checkbox>
270+
271+
<FormControlHelper>
272+
<FormControlHelperText>
273+
Plugin provides a user interface
274+
</FormControlHelperText>
275+
</FormControlHelper>
276+
</FormControl>
277+
278+
<HStack space="md">
279+
<Button action="primary" size="md" onPress={handleSubmit}>
280+
<ButtonText>Update</ButtonText>
281+
</Button>
282+
{onClose && (
283+
<Button action="secondary" variant="outline" size="md" onPress={onClose}>
284+
<ButtonText>Cancel</ButtonText>
285+
</Button>
286+
)}
287+
</HStack>
288+
</VStack>
289+
)
290+
}
291+
292+
export default EditPlugin

watchdog/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM ubuntu:22.04
1+
FROM ubuntu:24.04
22
ENV DEBIAN_FRONTEND=noninteractive
33
RUN apt-get update
44
RUN apt-get install -y watchdog netbase

0 commit comments

Comments
 (0)