Add http API for templates on timeline creation

This commit is contained in:
Arpad Müller
2025-05-20 17:34:38 +02:00
parent f4150614d0
commit 5df8284961
4 changed files with 44 additions and 2 deletions

View File

@@ -325,6 +325,7 @@ impl TimelineCreateRequest {
match &self.mode {
TimelineCreateRequestMode::Branch { .. } => "branch",
TimelineCreateRequestMode::ImportPgdata { .. } => "import",
TimelineCreateRequestMode::Template { .. } => "template",
TimelineCreateRequestMode::Bootstrap { .. } => "bootstrap",
}
}
@@ -406,6 +407,10 @@ pub enum TimelineCreateRequestMode {
ImportPgdata {
import_pgdata: TimelineCreateRequestModeImportPgdata,
},
Template {
template_tenant_id: TenantId,
template_timeline_id: TimelineId,
},
// NB: Bootstrap is all-optional, and thus the serde(untagged) will cause serde to stop at Bootstrap.
// (serde picks the first matching enum variant, in declaration order).
Bootstrap {

View File

@@ -629,6 +629,12 @@ paths:
existing_initdb_timeline_id:
type: string
format: hex
template_tenant_id:
type: string
format: hex
template_timeline_id:
type: string
format: hex
import_pgdata:
$ref: "#/components/schemas/TimelineCreateRequestImportPgdata"
responses:

View File

@@ -607,6 +607,14 @@ async fn timeline_create_handler(
}
},
}),
TimelineCreateRequestMode::Template {
template_tenant_id,
template_timeline_id,
} => tenant::CreateTimelineParams::Template(tenant::CreateTimelineParamsTemplate {
new_timeline_id,
template_tenant_id,
template_timeline_id,
}),
};
let ctx = RequestContext::new(TaskKind::MgmtRequest, DownloadBehavior::Error);

View File

@@ -107,7 +107,7 @@ use crate::{InitializationOrder, TEMP_FILE_SUFFIX, import_datadir, span, task_mg
static INIT_DB_SEMAPHORE: Lazy<Semaphore> = Lazy::new(|| Semaphore::new(8));
use utils::crashsafe;
use utils::generation::Generation;
use utils::id::TimelineId;
use utils::id::{TenantId, TimelineId};
use utils::lsn::{Lsn, RecordLsn};
pub mod blob_io;
@@ -864,6 +864,7 @@ impl Debug for SetStoppingError {
#[derive(Debug)]
pub(crate) enum CreateTimelineParams {
Bootstrap(CreateTimelineParamsBootstrap),
Template(CreateTimelineParamsTemplate),
Branch(CreateTimelineParamsBranch),
ImportPgdata(CreateTimelineParamsImportPgdata),
}
@@ -875,6 +876,13 @@ pub(crate) struct CreateTimelineParamsBootstrap {
pub(crate) pg_version: u32,
}
#[derive(Debug)]
pub(crate) struct CreateTimelineParamsTemplate {
pub(crate) new_timeline_id: TimelineId,
pub(crate) template_tenant_id: TenantId,
pub(crate) template_timeline_id: TimelineId,
}
/// NB: See comment on [`CreateTimelineIdempotency::Branch`] for why there's no `pg_version` here.
#[derive(Debug)]
pub(crate) struct CreateTimelineParamsBranch {
@@ -2665,6 +2673,9 @@ impl TenantShard {
CreateTimelineParams::ImportPgdata(params) => {
self.create_timeline_import_pgdata(params, ctx).await?
}
CreateTimelineParams::Template(params) => {
self.create_timeline_from_template(params, ctx).await?
}
};
// At this point we have dropped our guard on [`Self::timelines_creating`], and
@@ -2729,6 +2740,19 @@ impl TenantShard {
Ok(activated_timeline)
}
async fn create_timeline_from_template(
self: &Arc<Self>,
params: CreateTimelineParamsTemplate,
ctx: &RequestContext,
) -> Result<CreateTimelineResult, CreateTimelineError> {
let CreateTimelineParamsTemplate {
new_timeline_id,
template_tenant_id,
template_timeline_id,
} = params;
todo!()
}
/// The returned [`Arc<Timeline>`] is NOT in the [`TenantShard::timelines`] map until the import
/// completes in the background. A DIFFERENT [`Arc<Timeline>`] will be inserted into the
/// [`TenantShard::timelines`] map when the import completes.
@@ -5683,7 +5707,6 @@ pub(crate) mod harness {
use pageserver_api::models::ShardParameters;
use pageserver_api::record::NeonWalRecord;
use pageserver_api::shard::ShardIndex;
use utils::id::TenantId;
use utils::logging;
use super::*;