Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,8 @@ jobs:
cargo build --release \
--bin server \
--bin cleanup-notify \
--bin backfill_field_policy
--bin backfill_field_policy \
--bin bake
cargo build --release --bin console --features explain

- name: Set up Node.js
Expand Down Expand Up @@ -202,6 +203,7 @@ jobs:
cp target/release/console app/stacker/console
cp target/release/cleanup-notify app/stacker/cleanup-notify
cp target/release/backfill_field_policy app/stacker/backfill_field_policy
cp target/release/bake app/stacker/bake
if [ -d web/dist ]; then cp -a web/dist/. app/stacker; fi
cp Dockerfile app/Dockerfile
cp access_control.conf.dist app/access_control.conf.dist
Expand Down Expand Up @@ -248,8 +250,8 @@ jobs:
tar -xzf app.tar.gz -C "${{ runner.temp }}/prebuilt"
cd "${{ runner.temp }}/prebuilt"
mv stacker/server stacker/console stacker/cleanup-notify \
stacker/backfill_field_policy .
chmod +x server console cleanup-notify backfill_field_policy
stacker/backfill_field_policy stacker/bake .
chmod +x server console cleanup-notify backfill_field_policy bake
rm -f "${GITHUB_WORKSPACE}/app.tar.gz"

-
Expand Down
5 changes: 4 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ RUN apt-get update && apt-get install --no-install-recommends -y libssl-dev; \
cargo build --release --bin server; \
cargo build --release --bin console --features explain; \
cargo build --release --bin cleanup-notify; \
cargo build --release --bin backfill_field_policy
cargo build --release --bin backfill_field_policy; \
cargo build --release --bin bake

#RUN ls -la /app/target/release/ >&2

Expand All @@ -78,6 +79,7 @@ COPY --from=builder /app/target/release/server /server
COPY --from=builder /app/target/release/console /console
COPY --from=builder /app/target/release/cleanup-notify /cleanup-notify
COPY --from=builder /app/target/release/backfill_field_policy /backfill_field_policy
COPY --from=builder /app/target/release/bake /bake

FROM ${BINARIES}-source AS binaries

Expand All @@ -94,6 +96,7 @@ COPY --from=binaries /server .
COPY --from=binaries /console .
COPY --from=binaries /cleanup-notify .
COPY --from=binaries /backfill_field_policy .
COPY --from=binaries /bake .
COPY --from=config /app/.env .
COPY --from=config /app/configuration.yaml .
COPY --from=config /usr/local/cargo/bin/sqlx /usr/local/bin/sqlx
Expand Down
2 changes: 2 additions & 0 deletions migrations/20261015100000_bake_job.down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
DELETE FROM public.casbin_rule WHERE ptype = 'p' AND v1 IN ('/api/admin/bake', '/api/admin/bake/:id');
DROP TABLE IF EXISTS bake_job;
23 changes: 23 additions & 0 deletions migrations/20261015100000_bake_job.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
-- Bake started from the API: one row per POST /api/admin/bake.
CREATE TABLE IF NOT EXISTS bake_job (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
stack TEXT NOT NULL,
version TEXT NOT NULL,
deployment_id INTEGER NOT NULL,
server_id INTEGER NOT NULL,
server_ip TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'running' CHECK (status IN ('running', 'done', 'failed')),
image_id BIGINT,
snapshot_id INTEGER,
error TEXT,
created_by TEXT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS bake_job_created_at_idx ON bake_job (created_at DESC);

INSERT INTO public.casbin_rule (ptype, v0, v1, v2, v3, v4, v5) VALUES ('p', 'group_admin', '/api/admin/bake', 'POST', '', '', '') ON CONFLICT ON CONSTRAINT unique_key_sqlx_adapter DO NOTHING;
INSERT INTO public.casbin_rule (ptype, v0, v1, v2, v3, v4, v5) VALUES ('p', 'group_admin', '/api/admin/bake/:id', 'GET', '', '', '') ON CONFLICT ON CONSTRAINT unique_key_sqlx_adapter DO NOTHING;
INSERT INTO public.casbin_rule (ptype, v0, v1, v2, v3, v4, v5) VALUES ('p', 'admin_service', '/api/admin/bake', 'POST', '', '', '') ON CONFLICT ON CONSTRAINT unique_key_sqlx_adapter DO NOTHING;
INSERT INTO public.casbin_rule (ptype, v0, v1, v2, v3, v4, v5) VALUES ('p', 'admin_service', '/api/admin/bake/:id', 'GET', '', '', '') ON CONFLICT ON CONSTRAINT unique_key_sqlx_adapter DO NOTHING;
80 changes: 80 additions & 0 deletions src/db/bake_job.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
use crate::models::BakeJob;
use sqlx::PgPool;

pub struct NewBakeJob<'a> {
pub stack: &'a str,
pub version: &'a str,
pub deployment_id: i32,
pub server_id: i32,
pub server_ip: &'a str,
pub created_by: &'a str,
}

pub async fn insert(pool: &PgPool, job: NewBakeJob<'_>) -> Result<BakeJob, String> {
sqlx::query_as::<_, BakeJob>(
r#"
INSERT INTO bake_job (stack, version, deployment_id, server_id, server_ip, created_by)
VALUES ($1, $2, $3, $4, $5, $6)
RETURNING *
"#,
)
.bind(job.stack)
.bind(job.version)
.bind(job.deployment_id)
.bind(job.server_id)
.bind(job.server_ip)
.bind(job.created_by)
.fetch_one(pool)
.await
.map_err(|e| format!("Failed to record bake job: {e}"))
}

pub async fn fetch(pool: &PgPool, id: uuid::Uuid) -> Result<Option<BakeJob>, String> {
sqlx::query_as::<_, BakeJob>("SELECT * FROM bake_job WHERE id = $1")
.bind(id)
.fetch_optional(pool)
.await
.map_err(|e| format!("Failed to read bake job: {e}"))
}

/// A bake already running for this build box. One at a time: two would
/// sanitize and snapshot the same box concurrently.
pub async fn running_for_server(pool: &PgPool, server_id: i32) -> Result<Option<BakeJob>, String> {
sqlx::query_as::<_, BakeJob>(
"SELECT * FROM bake_job WHERE server_id = $1 AND status = 'running' LIMIT 1",
)
.bind(server_id)
.fetch_optional(pool)
.await
.map_err(|e| format!("Failed to read bake jobs: {e}"))
}

pub async fn mark_done(
pool: &PgPool,
id: uuid::Uuid,
image_id: i64,
snapshot_id: i32,
) -> Result<(), String> {
sqlx::query(
"UPDATE bake_job SET status = 'done', image_id = $2, snapshot_id = $3, updated_at = NOW() WHERE id = $1",
)
.bind(id)
.bind(image_id)
.bind(snapshot_id)
.execute(pool)
.await
.map(|_| ())
.map_err(|e| format!("Failed to finish bake job: {e}"))
}

pub async fn mark_failed(pool: &PgPool, id: uuid::Uuid, error: &str) -> Result<(), String> {
sqlx::query(
"UPDATE bake_job SET status = 'failed', error = $2, updated_at = NOW() WHERE id = $1",
)
.bind(id)
.bind(error)
.execute(pool)
.await
.map(|_| ())
.map_err(|e| format!("Failed to mark bake job failed: {e}"))
}
1 change: 1 addition & 0 deletions src/db/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod agent;
pub mod agent_audit_log;
pub(crate) mod agreement;
pub mod bake_job;
pub mod baked_snapshot;
pub mod chat;
pub mod chat_admin;
Expand Down
Loading
Loading