Skip to content

Commit 3d582b2

Browse files
authored
Add archival_config endpoint to pageserver (#8414)
This adds an archival_config endpoint to the pageserver. Currently it has no effect, and always "works", but later the intent is that it will make a timeline archived/unarchived. - [x] add yml spec - [x] add endpoint handler Part of #8088
1 parent 3fbb84d commit 3d582b2

File tree

4 files changed

+115
-3
lines changed

4 files changed

+115
-3
lines changed

libs/pageserver_api/src/models.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,17 @@ pub struct TenantDetails {
651651
pub timelines: Vec<TimelineId>,
652652
}
653653

654+
#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Copy, Debug)]
655+
pub enum TimelineArchivalState {
656+
Archived,
657+
Unarchived,
658+
}
659+
660+
#[derive(Serialize, Deserialize, PartialEq, Eq, Clone)]
661+
pub struct TimelineArchivalConfigRequest {
662+
pub state: TimelineArchivalState,
663+
}
664+
654665
/// This represents the output of the "timeline_detail" and "timeline_list" API calls.
655666
#[derive(Debug, Serialize, Deserialize, Clone)]
656667
pub struct TimelineInfo {

pageserver/src/http/openapi_spec.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,51 @@ paths:
397397
"202":
398398
description: Tenant scheduled to load successfully
399399

400+
/v1/tenant/{tenant_shard_id}/timeline/{timeline_id}/archival_config:
401+
parameters:
402+
- name: tenant_shard_id
403+
in: path
404+
required: true
405+
schema:
406+
type: string
407+
- name: timeline_id
408+
in: path
409+
required: true
410+
schema:
411+
type: string
412+
put:
413+
description: |
414+
Either archives or unarchives the given timeline.
415+
An archived timeline may not have any non-archived children.
416+
requestBody:
417+
required: false
418+
content:
419+
application/json:
420+
schema:
421+
$ref: "#/components/schemas/ArchivalConfigRequest"
422+
responses:
423+
"200":
424+
description: Timeline (un)archived successfully
425+
"409":
426+
description: |
427+
The tenant/timeline is already being modified, perhaps by a concurrent call to this API
428+
content:
429+
application/json:
430+
schema:
431+
$ref: "#/components/schemas/ConflictError"
432+
"500":
433+
description: Generic operation error
434+
content:
435+
application/json:
436+
schema:
437+
$ref: "#/components/schemas/Error"
438+
"503":
439+
description: Temporarily unavailable, please retry.
440+
content:
441+
application/json:
442+
schema:
443+
$ref: "#/components/schemas/ServiceUnavailableError"
444+
400445
/v1/tenant/{tenant_id}/synthetic_size:
401446
parameters:
402447
- name: tenant_id
@@ -846,6 +891,15 @@ components:
846891
warm:
847892
type: boolean
848893
description: Whether to poll remote storage for layers to download. If false, secondary locations don't download anything.
894+
ArchivalConfigRequest:
895+
type: object
896+
required
897+
- state
898+
properties:
899+
state:
900+
description: The archival state of a timeline
901+
type: string
902+
enum: ["Archived", "Unarchived"]
849903
TenantConfig:
850904
type: object
851905
properties:

pageserver/src/http/routes.rs

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,27 +18,28 @@ use hyper::StatusCode;
1818
use hyper::{Body, Request, Response, Uri};
1919
use metrics::launch_timestamp::LaunchTimestamp;
2020
use pageserver_api::models::AuxFilePolicy;
21+
use pageserver_api::models::DownloadRemoteLayersTaskSpawnRequest;
2122
use pageserver_api::models::IngestAuxFilesRequest;
2223
use pageserver_api::models::ListAuxFilesRequest;
2324
use pageserver_api::models::LocationConfig;
2425
use pageserver_api::models::LocationConfigListResponse;
26+
use pageserver_api::models::LocationConfigMode;
2527
use pageserver_api::models::LsnLease;
2628
use pageserver_api::models::LsnLeaseRequest;
2729
use pageserver_api::models::ShardParameters;
2830
use pageserver_api::models::TenantDetails;
31+
use pageserver_api::models::TenantLocationConfigRequest;
2932
use pageserver_api::models::TenantLocationConfigResponse;
3033
use pageserver_api::models::TenantScanRemoteStorageResponse;
3134
use pageserver_api::models::TenantScanRemoteStorageShard;
3235
use pageserver_api::models::TenantShardLocation;
3336
use pageserver_api::models::TenantShardSplitRequest;
3437
use pageserver_api::models::TenantShardSplitResponse;
3538
use pageserver_api::models::TenantSorting;
39+
use pageserver_api::models::TimelineArchivalConfigRequest;
3640
use pageserver_api::models::TopTenantShardItem;
3741
use pageserver_api::models::TopTenantShardsRequest;
3842
use pageserver_api::models::TopTenantShardsResponse;
39-
use pageserver_api::models::{
40-
DownloadRemoteLayersTaskSpawnRequest, LocationConfigMode, TenantLocationConfigRequest,
41-
};
4243
use pageserver_api::shard::ShardCount;
4344
use pageserver_api::shard::TenantShardId;
4445
use remote_storage::DownloadError;
@@ -664,6 +665,39 @@ async fn timeline_preserve_initdb_handler(
664665
json_response(StatusCode::OK, ())
665666
}
666667

668+
async fn timeline_archival_config_handler(
669+
mut request: Request<Body>,
670+
_cancel: CancellationToken,
671+
) -> Result<Response<Body>, ApiError> {
672+
let tenant_shard_id: TenantShardId = parse_request_param(&request, "tenant_shard_id")?;
673+
let timeline_id: TimelineId = parse_request_param(&request, "timeline_id")?;
674+
675+
let request_data: TimelineArchivalConfigRequest = json_request(&mut request).await?;
676+
check_permission(&request, Some(tenant_shard_id.tenant_id))?;
677+
let state = get_state(&request);
678+
679+
async {
680+
let tenant = state
681+
.tenant_manager
682+
.get_attached_tenant_shard(tenant_shard_id)?;
683+
684+
tenant
685+
.apply_timeline_archival_config(timeline_id, request_data.state)
686+
.await
687+
.context("applying archival config")
688+
.map_err(ApiError::InternalServerError)?;
689+
Ok::<_, ApiError>(())
690+
}
691+
.instrument(info_span!("timeline_archival_config",
692+
tenant_id = %tenant_shard_id.tenant_id,
693+
shard_id = %tenant_shard_id.shard_slug(),
694+
state = ?request_data.state,
695+
%timeline_id))
696+
.await?;
697+
698+
json_response(StatusCode::OK, ())
699+
}
700+
667701
async fn timeline_detail_handler(
668702
request: Request<Body>,
669703
_cancel: CancellationToken,
@@ -2789,6 +2823,10 @@ pub fn make_router(
27892823
"/v1/tenant/:tenant_shard_id/timeline/:timeline_id/preserve_initdb_archive",
27902824
|r| api_handler(r, timeline_preserve_initdb_handler),
27912825
)
2826+
.post(
2827+
"/v1/tenant/:tenant_shard_id/timeline/:timeline_id/archival_config",
2828+
|r| api_handler(r, timeline_archival_config_handler),
2829+
)
27922830
.get("/v1/tenant/:tenant_shard_id/timeline/:timeline_id", |r| {
27932831
api_handler(r, timeline_detail_handler)
27942832
})

pageserver/src/tenant.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use futures::FutureExt;
2121
use futures::StreamExt;
2222
use pageserver_api::models;
2323
use pageserver_api::models::AuxFilePolicy;
24+
use pageserver_api::models::TimelineArchivalState;
2425
use pageserver_api::models::TimelineState;
2526
use pageserver_api::models::TopTenantShardItem;
2627
use pageserver_api::models::WalRedoManagerStatus;
@@ -1228,6 +1229,14 @@ impl Tenant {
12281229
Ok(timeline_preloads)
12291230
}
12301231

1232+
pub async fn apply_timeline_archival_config(
1233+
&self,
1234+
_timeline_id: TimelineId,
1235+
_config: TimelineArchivalState,
1236+
) -> anyhow::Result<()> {
1237+
Ok(())
1238+
}
1239+
12311240
pub(crate) fn tenant_shard_id(&self) -> TenantShardId {
12321241
self.tenant_shard_id
12331242
}

0 commit comments

Comments
 (0)