Skip to content

Commit 00ddf47

Browse files
author
Jan Kamieth
committed
linter fixes;
1 parent 2a1d226 commit 00ddf47

26 files changed

Lines changed: 712 additions & 372 deletions

backend/.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
!config.dist.yml
21
config.*.yml
2+
!config.dist.yml
33
public/*
4+
!public/index.html
5+
!public/fav.png
46
/flink-admin

backend/build/Dockerfile

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Stage 1: Build the frontend
2+
FROM oven/bun:1 AS frontend-builder
3+
WORKDIR /app/frontend
4+
5+
# Copy package files first to leverage Docker cache
6+
COPY frontend/package.json frontend/bun.lock ./
7+
RUN bun install --frozen-lockfile
8+
9+
# Copy the rest of the frontend source code
10+
COPY frontend/ ./
11+
# Build the frontend (outputs to /app/frontend/dist)
12+
RUN bun run build
13+
14+
# Stage 2: Build the backend with embedded frontend
15+
FROM golang:1.25 AS backend-builder
16+
WORKDIR /app
17+
18+
# Copy backend module files first
19+
COPY backend/go.mod backend/go.sum ./
20+
RUN go mod download
21+
22+
# Copy backend source code
23+
COPY backend/ ./
24+
25+
# Copy the built frontend artifacts into the backend source tree
26+
# This is crucial for the //go:embed directive to pick them up
27+
COPY --from=frontend-builder /app/frontend/dist ./public
28+
29+
# Build the Go binary
30+
# CGO_ENABLED=0 creates a statically linked binary
31+
RUN CGO_ENABLED=0 GOOS=linux go build -o flink-admin .
32+
33+
# Stage 3: Create the final runtime image
34+
# distroless/static is ideal for static Go binaries (small, secure)
35+
FROM gcr.io/distroless/static-debian12 AS runtime
36+
37+
WORKDIR /app
38+
39+
# Copy the binary from the builder stage
40+
COPY --from=backend-builder /app/flink-admin .
41+
42+
# Expose the port configured in config.dist.yml
43+
EXPOSE 8081
44+
45+
# Run the binary
46+
ENTRYPOINT ["./flink-admin"]

backend/build/Dockerfile.release

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Dockerfile.release - Packaging-only Dockerfile for CI multi-arch builds
2+
# This Dockerfile contains NO RUN commands, allowing Buildx to assemble
3+
# images for any target platform without QEMU emulation.
4+
#
5+
# Prerequisites (provided by CI workflow):
6+
# - Pre-built flink-admin binary at: dist/<arch>/flink-admin
7+
# - Migrations in repo at: backend/build/migrations/
8+
#
9+
# Usage:
10+
# docker buildx build --platform linux/amd64 \
11+
# --build-arg TARGETARCH=amd64 \
12+
# -f build/Dockerfile.release .
13+
14+
FROM gcr.io/distroless/static-debian12
15+
16+
ARG TARGETARCH
17+
18+
WORKDIR /app
19+
20+
# Copy the pre-built binary for the target architecture
21+
COPY dist/${TARGETARCH}/flink-admin ./flink-admin
22+
23+
# Expose the application port
24+
EXPOSE 8081
25+
26+
# Run the binary
27+
ENTRYPOINT ["./flink-admin"]

backend/config.dist.yml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
env: "sandbox"
2+
3+
app_project: "justtrack"
4+
app_family: "gosoline"
5+
app_group: "flink"
6+
app_name: "admin"
7+
8+
aws:
9+
account_id: "047452524847"
10+
organizational_unit: "sdlc"
11+
12+
cloud:
13+
aws:
14+
defaults:
15+
endpoint: ""
16+
profile: "{aws.organizational_unit}-marketing"
17+
s3:
18+
clients:
19+
default:
20+
region: eu-central-1
21+
22+
flink:
23+
namespaces:
24+
- annotators
25+
- denormalizers
26+
- lake-ingesters
27+
- parquetizers
28+
- session-tracker
29+
30+
httpserver:
31+
default:
32+
port: 8082
33+
timeout:
34+
read: 60s
35+
write: 60s
36+
idle: 60s
37+
compression:
38+
exclude:
39+
path:
40+
- /api/deployments/watch
41+
42+
kube:
43+
context: "arn:aws:eks:eu-central-1:{aws.account_id}:cluster/{aws.organizational_unit}-marketing"

backend/internal/checkpoint/checkpoint_properties.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,6 @@ func binaryBigEndianUint16(data []byte) uint16 {
5858
if len(data) < 2 {
5959
return 0
6060
}
61+
6162
return uint16(data[0])<<8 | uint16(data[1])
6263
}

backend/internal/checkpoint/keyed_state.go

Lines changed: 49 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -181,65 +181,28 @@ func readHandleAndLocalPathList(br *binaryReader) ([]HandleAndLocalPath, error)
181181
// Type 14 (V2) includes a separate checkpointId field.
182182
func readChangelogStateHandle(br *binaryReader, kind KeyedStateHandleType, parseFull bool) (KeyedStateHandle, error) {
183183
_ = parseFull
184-
isV2 := kind == KeyedStateHandleChangelogV2
185-
186-
startKeyGroup, err := br.ReadInt32()
187-
if err != nil {
188-
return nil, fmt.Errorf("read changelog start key group: %w", err)
189-
}
190-
count, err := br.ReadInt32()
191-
if err != nil {
192-
return nil, fmt.Errorf("read changelog key group count: %w", err)
193-
}
194-
checkpointedSize, err := br.ReadInt64()
184+
startKeyGroup, numKeyGroups, checkpointedSize, err := readChangelogHeader(br)
195185
if err != nil {
196-
return nil, fmt.Errorf("read changelog checkpointed size: %w", err)
186+
return nil, err
197187
}
198188

199-
materializedCount, err := br.ReadInt32()
189+
materialized, err := readChangelogKeyedStateHandles(br, "materialized")
200190
if err != nil {
201-
return nil, fmt.Errorf("read changelog materialized count: %w", err)
202-
}
203-
if materializedCount < 0 {
204-
return nil, fmt.Errorf("changelog materialized count negative: %d", materializedCount)
205-
}
206-
materialized := make([]KeyedStateHandle, 0, materializedCount)
207-
for i := int32(0); i < materializedCount; i++ {
208-
handle, err := readKeyedStateHandle(br, true)
209-
if err != nil {
210-
return nil, fmt.Errorf("read changelog materialized handle: %w", err)
211-
}
212-
if handle != nil {
213-
materialized = append(materialized, handle)
214-
}
191+
return nil, err
215192
}
216193

217-
nonMaterializedCount, err := br.ReadInt32()
194+
nonMaterialized, err := readChangelogKeyedStateHandles(br, "non materialized")
218195
if err != nil {
219-
return nil, fmt.Errorf("read changelog non materialized count: %w", err)
220-
}
221-
if nonMaterializedCount < 0 {
222-
return nil, fmt.Errorf("changelog non materialized count negative: %d", nonMaterializedCount)
223-
}
224-
nonMaterialized := make([]KeyedStateHandle, 0, nonMaterializedCount)
225-
for i := int32(0); i < nonMaterializedCount; i++ {
226-
handle, err := readKeyedStateHandle(br, true)
227-
if err != nil {
228-
return nil, fmt.Errorf("read changelog non materialized handle: %w", err)
229-
}
230-
if handle != nil {
231-
nonMaterialized = append(nonMaterialized, handle)
232-
}
196+
return nil, err
233197
}
234198

235199
materializationID, err := br.ReadInt64()
236200
if err != nil {
237201
return nil, fmt.Errorf("read changelog materialization id: %w", err)
238202
}
239203

240-
// checkpointId is only present in V2 (type 14); for V1, use materializationID
241204
checkpointID := materializationID
242-
if isV2 {
205+
if kind == KeyedStateHandleChangelogV2 {
243206
checkpointID, err = br.ReadInt64()
244207
if err != nil {
245208
return nil, fmt.Errorf("read changelog checkpoint id: %w", err)
@@ -254,7 +217,7 @@ func readChangelogStateHandle(br *binaryReader, kind KeyedStateHandleType, parse
254217
return ChangelogStateHandle{
255218
Type: kind,
256219
StartKeyGroup: startKeyGroup,
257-
NumKeyGroups: count,
220+
NumKeyGroups: numKeyGroups,
258221
CheckpointedSize: checkpointedSize,
259222
Materialized: materialized,
260223
NonMaterialized: nonMaterialized,
@@ -264,6 +227,46 @@ func readChangelogStateHandle(br *binaryReader, kind KeyedStateHandleType, parse
264227
}, nil
265228
}
266229

230+
func readChangelogHeader(br *binaryReader) (startKeyGroup int32, numKeyGroups int32, checkpointedSize int64, err error) {
231+
startKeyGroup, err = br.ReadInt32()
232+
if err != nil {
233+
return 0, 0, 0, fmt.Errorf("read changelog start key group: %w", err)
234+
}
235+
count, err := br.ReadInt32()
236+
if err != nil {
237+
return 0, 0, 0, fmt.Errorf("read changelog key group count: %w", err)
238+
}
239+
checkpointedSize, err = br.ReadInt64()
240+
if err != nil {
241+
return 0, 0, 0, fmt.Errorf("read changelog checkpointed size: %w", err)
242+
}
243+
244+
return startKeyGroup, count, checkpointedSize, nil
245+
}
246+
247+
func readChangelogKeyedStateHandles(br *binaryReader, label string) ([]KeyedStateHandle, error) {
248+
count, err := br.ReadInt32()
249+
if err != nil {
250+
return nil, fmt.Errorf("read changelog %s count: %w", label, err)
251+
}
252+
if count < 0 {
253+
return nil, fmt.Errorf("changelog %s count negative: %d", label, count)
254+
}
255+
256+
handles := make([]KeyedStateHandle, 0, count)
257+
for i := int32(0); i < count; i++ {
258+
handle, err := readKeyedStateHandle(br, true)
259+
if err != nil {
260+
return nil, fmt.Errorf("read changelog %s handle: %w", label, err)
261+
}
262+
if handle != nil {
263+
handles = append(handles, handle)
264+
}
265+
}
266+
267+
return handles, nil
268+
}
269+
267270
// readChangelogByteIncrementHandle parses in-memory changelog increments.
268271
func readChangelogByteIncrementHandle(br *binaryReader, kind KeyedStateHandleType, parseFull bool) (KeyedStateHandle, error) {
269272
startKeyGroup, err := br.ReadInt32()
@@ -304,6 +307,7 @@ func readChangelogByteIncrementHandle(br *binaryReader, kind KeyedStateHandleTyp
304307
if _, err := br.ReadBytes(int(length)); err != nil {
305308
return nil, fmt.Errorf("read changelog byte data: %w", err)
306309
}
310+
307311
continue
308312
}
309313
data, err := br.ReadBytes(int(length))

backend/internal/checkpoint/metadata.go

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,25 +104,43 @@ func ParseSummary(reader io.Reader, options ParseOptions) (*CheckpointSummary, e
104104
}
105105

106106
// ParseFile opens the given file path and parses it as _metadata.
107-
func ParseFile(path string, options ParseOptions) (*CheckpointMetadata, error) {
107+
func ParseFile(path string, options ParseOptions) (metadata *CheckpointMetadata, err error) {
108108
file, err := os.Open(path)
109109
if err != nil {
110110
return nil, fmt.Errorf("open metadata file: %w", err)
111111
}
112-
defer file.Close()
112+
defer func() {
113+
if cerr := file.Close(); cerr != nil && err == nil {
114+
err = fmt.Errorf("close metadata file: %w", cerr)
115+
}
116+
}()
113117

114-
return Parse(file, options)
118+
metadata, err = Parse(file, options)
119+
if err != nil {
120+
return nil, err
121+
}
122+
123+
return metadata, nil
115124
}
116125

117126
// ParseFileSummary opens the given file path and parses it as a summary.
118-
func ParseFileSummary(path string, options ParseOptions) (*CheckpointSummary, error) {
127+
func ParseFileSummary(path string, options ParseOptions) (summary *CheckpointSummary, err error) {
119128
file, err := os.Open(path)
120129
if err != nil {
121130
return nil, fmt.Errorf("open metadata file: %w", err)
122131
}
123-
defer file.Close()
132+
defer func() {
133+
if cerr := file.Close(); cerr != nil && err == nil {
134+
err = fmt.Errorf("close metadata file: %w", cerr)
135+
}
136+
}()
137+
138+
summary, err = ParseSummary(file, options)
139+
if err != nil {
140+
return nil, err
141+
}
124142

125-
return ParseSummary(file, options)
143+
return summary, nil
126144
}
127145

128146
// readMasterStates parses master state entries from the stream.
@@ -350,6 +368,7 @@ func readOptionalOperatorStateHandle(br *binaryReader, parseFull bool) (*Operato
350368
if err != nil {
351369
return nil, err
352370
}
371+
353372
return handle, nil
354373
}
355374

@@ -360,5 +379,6 @@ func buildOperatorID(low int64, high int64) [16]byte {
360379
id[i] = byte(high >> uint(56-8*i))
361380
id[i+8] = byte(low >> uint(56-8*i))
362381
}
382+
363383
return id
364384
}

0 commit comments

Comments
 (0)