runlot
リファレンスAPI

データベース

データベースカテゴリの 13 個の API 操作を扱います。

メソッドパス説明
GET/v1/orgs/{orgSlug}/projects/{projectName}/databaseデータベースが利用可能かどうか
POST/v1/orgs/{orgSlug}/projects/{projectName}/databaseデータベースを作成します(runlot deploy\\"database\\": true という宣言を読み取ったときに呼び出されます)
GET/v1/orgs/{orgSlug}/projects/{projectName}/database/connectpsql やドライバーで接続するために必要な情報
GET/v1/orgs/{orgSlug}/projects/{projectName}/database/endpoint認証情報を含まない接続情報(runlot port-forward)
GET/v1/orgs/{orgSlug}/projects/{projectName}/database/tokens有効な短期認証情報の一覧
POST/v1/orgs/{orgSlug}/projects/{projectName}/database/tokens短期間の自動化用の認証情報を発行します(runlot pg token)
DELETE/v1/orgs/{orgSlug}/projects/{projectName}/database/tokens/{tokenUser}短期認証情報を失効させます
POST/v1/orgs/{orgSlug}/projects/{projectName}/database/export診断用イメージを作成します(runlot pg export)
GET/v1/orgs/{orgSlug}/projects/{projectName}/database/generationsバックアップ世代の一覧(runlot pg generations)
POST/v1/orgs/{orgSlug}/projects/{projectName}/database/restoreある世代に復元します(runlot pg restore)
POST/v1/orgs/{orgSlug}/projects/{projectName}/database/deleteデータベースを削除します(runlot pg delete)
GET/v1/orgs/{orgSlug}/projects/{projectName}/database/operations/{opId}1 つの操作の進行状況
POST/v1/orgs/{orgSlug}/projects/{projectName}/database/operations/{opId}/abort進行中の操作を中止します(runlot pg abort)

GET /v1/orgs/{orgSlug}/projects/{projectName}/database

レスポンスは単に {db: bool} です。サイズや世代などの物理的な状態はここには含まれません。それらについてはノードが正となる情報源だからです。

この認証情報(パスワード)はこのレスポンスには含まれません。 このルートは viewer も許可します — 接続の詳細は /database/connect に分離されました。

operationId getDatabase

ステータスコード説明レスポンスボディ
200データベースが利用可能かどうかobject
403
404

POST /v1/orgs/{orgSlug}/projects/{projectName}/database

データベース設定レコードの存在が利用可能性を示します。設定が完了すると、node-agent は次の収束時にプロジェクトの workerd を env.db が接続された設定に切り替えます。デプロイや epoch の変更は不要です。

これは冪等であり、パスワードをローテーションしません。 2 回目の呼び出しは行にすでにある値を再読み込みし、同じ接続情報を返します。ローテーションすると、最初のレスポンスで記録された接続文字列が黙って無効になり、それが失効したことを示す唯一のシグナルは次回のログイン失敗になってしまいます。

operationId createDatabase

ステータスコード説明レスポンスボディ
200認証情報と接続情報DatabaseConnect
403
404

GET /v1/orgs/{orgSlug}/projects/{projectName}/database/connect

/database から分離されている理由はロールです。 データベースが存在するかどうかは viewer が知ってもよい情報ですが、パスワードはそうではありません。1 つのレスポンスに両方を含めてロールごとにフィールドを取り除く方式にすると、取り除き忘れた 1 つの経路が漏洩になってしまいます。これを受け取れるのは member 以上だけです。

operationId getDatabaseConnect

ステータスコード説明レスポンスボディ
200接続情報DatabaseConnect
403
404プロジェクトが存在しないか、そのデータベースがまだ作成されていませんError

GET /v1/orgs/{orgSlug}/projects/{projectName}/database/endpoint

host・port・database・sslmode のみです。viewer によるアクセスも許可されています — ここに秘密情報はありません。runlot port-forward はログインセッションを使って接続するため(front がセッションを検証します、docs/pg-driver-support.md §4.4)、パスワードは不要であり、このエンドポイントだけで足ります。

operationId getDatabaseEndpoint

ステータスコード説明レスポンスボディ
200エンドポイントobject
403
404

GET /v1/orgs/{orgSlug}/projects/{projectName}/database/tokens

パスワードと検証子は含まれません。member 以上が使用できます。

operationId listDatabaseTokens

ステータスコード説明レスポンスボディ
200一覧取得object
403
404

POST /v1/orgs/{orgSlug}/projects/{projectName}/database/tokens

接続文字列で使用する user/password のペアです。パスワードが表示されるのはこのレスポンスのみです — CP は SCRAM 検証子しか保持しないため、パスワードを紛失した場合は再発行が必要です。セッションはあくまでプロジェクトのロールの下で開かれます。トークンの user は認証に使う名前であり、エンジンのロールではありません。member。

operationId createDatabaseToken

リクエストボディ: application/jsonobject

ステータスコード説明レスポンスボディ
201発行された認証情報DatabaseToken
400
403
404

DELETE /v1/orgs/{orgSlug}/projects/{projectName}/database/tokens/{tokenUser}

以降の接続は拒否されます。存在しない認証情報を削除しようとすると 404 が返ります。member 以上が利用できます。

operationId deleteDatabaseToken

ステータスコード説明レスポンスボディ
204破棄済み
403
404

POST /v1/orgs/{orgSlug}/projects/{projectName}/database/export

バックアップではありません(docs/env-db-assembly.md §5)。これが作成するのは、現在の (project, epoch) の下にある不変の診断用キーであり、latest・freshness・retention のいずれのポインタも動かさず、次回の自動バックアップの名前にも影響しません。

スケジュールされたバックアップは現在稼働しています(Phase 5、docs/phase5.md)。node-agent がスケジューラとノード全体のセマフォを所有し、step の世代は RPO 1 時間のグリッドで生成されます。これらの世代は gen/<project>/<epoch>/ の下に保存され、…/database/generations で一覧を取得し、…/database/restore で 1 つを選択します。このエンドポイントが作成する診断用イメージはその名前空間の外側にとどまります — restore はこれを選択できず、pruning もこれを数えず、latest を動かすこともできません。

冪等ではありません。 サーバーはリクエストごとに新しいスタンプを作成するため、呼び出すたびにイメージが 1 つ増えます。冪等に吸収されるのは、そのスタンプがノードに到達した後の同じスタンプの再試行だけです。

member 以上のみが利用できます。このイメージはデータベース全体であるため、viewer が 1 回の呼び出しで取得すべきものではありません。

低速です。レスポンスはダンプが完了した後にのみ届き――サイズに比例します――その間プロジェクトのアクターは占有されます。

operationId exportDatabase

ステータスコード説明レスポンスボディ
200作成された診断キーDatabaseExport
403
404プロジェクトが存在しないか、そのデータベースがまだ作成されていませんError
409配置がサスペンドされています(suspended)。診断エクスポートは実行中のインカーネーションからのみ生成されます。サスペンドされたプロジェクトからデータを取得するには、リストアの経路を使う必要があります。Error
502ノードがイメージのビルドに失敗しました(export_failedError
503エクスポート可能な状態ではありません――ホームノードのアドレスがない(no_home_node)か、CP にノード管理パスが設定されていない(no_node_admin)かのいずれかです。Error

GET /v1/orgs/{orgSlug}/projects/{projectName}/database/generations

リストアはそこにあるものからしか選べません(docs/phase5.md B1)。CP の db_generations テーブルを直接読み取ります。オフサイトストレージに直接問い合わせることはなく、受信したバイトを検証するには bytessha256 が CP 内にある必要があります。

lastCheckedAt変更なしスキップのハートビートです。世代が進んでいないこととバックアップが死んでいることは別物であり、この値が両者を切り分けます――空の場合はまだチェックが行われていないことを意味します。

member 以上が使用できます。リストにはオフサイトのキーとダイジェストが含まれます。

データベースが有効になっている必要はありません。 pg delete の後も最終セーフティ世代が残るため、削除後もこのリストで確認できます。

operationId listGenerations

ステータスコード説明レスポンスボディ
200世代のリスト(新しい順)DatabaseGenerations
403
404

POST /v1/orgs/{orgSlug}/projects/{projectName}/database/restore

世代のリストアとは、既存のインスタンスを終了してから再起動するプロセスです(docs/phase5.md B2)。pg.restore が空のストアしか受け付けないという事実がこの形を決めています。ドレイン → シール(まず現在のデータを持つリストア前の世代を保存します――戻り道です) → コミット(選択した世代を final_gen に書き込みます) → 再起動(epoch+1)という流れです。

その間に行われた書き込みは失われます。 そのため admin 以上が必要で、CLI はプロジェクト名の再入力を求めます。

サーバーは latest を解決しません。 リストで見た正確な (epoch, seq) を渡す必要があります――もしサーバー自身が「最新」を選んでいたら、その間にスケジュールで作成された世代のせいで、見ていたものとは別の世代に送られてしまう可能性があります。

202 を返します。返ってくるのは結果ではなくオペレーション id です。進捗は …/database/operations/{opId} で確認します。

operationId restoreDatabase

リクエストボディ:application/jsonRestoreRequest

ステータスコード説明レスポンスボディ
202オペレーションを開始しましたOperationStarted
400
403
404プロジェクトが存在しないか、そのデータベースがまだ作成されていませんError
409別のオペレーションがすでに進行中(operation_in_progress)か、デプロイメントがサスペンドされています(suspended)。Error
503リストア可能な状態ではありません(たとえば、利用可能なバッチノードがない場合など)Error

POST /v1/orgs/{orgSlug}/projects/{projectName}/database/delete

ドレイン → シール(最終セーフ世代を final として残します) → コミット(project_databases の行を削除します。次のコンバージェンスでノードはプロセスを env.db のないものに置き換え、データディレクトリを tombstone に移動します、docs/phase5.md B3)という流れです。admin 以上が必要です。

confirm はプロジェクト名と完全に一致する必要があります。 一致しない場合、400 confirm_mismatch が返され、何も開始されません。CLI のプロンプトだけでは不十分です――間違ったディレクトリで --yes 付きのスクリプトを実行すると、プロンプトはそもそも表示されません。

DELETE メソッドを使わない理由:このリクエストは単一の行を削除するものではなく、202 で開始し数分かけて完了するオペレーションであり、ボディに確認文字列が必要です――途中経路のプロキシは DELETE のボディの扱いが一貫していません。

operationId deleteDatabase

リクエストボディ:application/jsonDeleteRequest

ステータスコード説明レスポンスボディ
202オペレーションを開始しましたOperationStarted
400確認文字列がプロジェクト名と一致しません(confirm_mismatchError
403
404プロジェクトが存在しないか、そのデータベースがまだ作成されていませんError
409別のオペレーションがすでに進行中です(operation_in_progressError

GET /v1/orgs/{orgSlug}/projects/{projectName}/database/operations/{opId}

リストアまたは削除の進捗を監視します。CLI は 2 秒ごとにポーリングし、フェーズが変わるたびに出力します。

オペレーションがプロジェクト配下にあるのは、id が資格情報ではないからです。 cp-core の /v1/operations/{opId} は id を知っているどのクライアント(node、cp-public)にも応答しますが、ユーザー向けのサーフェスが同じことをすれば、単一の id が別の org のオペレーション状態を開く鍵になってしまいます。このルートは応答する前にオペレーションの projectId がパス内のプロジェクトと一致するかを確認し、一致しない場合は存在しないかのように 404 を返します。

member 以上が必要です。

operationId getDatabaseOperation

ステータスコード説明レスポンスボディ
200オペレーションのステータスOperation
403
404プロジェクトにそのようなオペレーションはありません(他のプロジェクトに属するオペレーションもここに該当します)Error

POST /v1/orgs/{orgSlug}/projects/{projectName}/database/operations/{opId}/abort

回復不能なフェーズ(docs/phase5.md B4)のでのみ可能です: evict、restore_generation、delete は commit されるまで中止可能ですが、restore はできません。中止するとバッチは active に戻り、terminalCode=aborted が残ります。

admin 以上です。サーバーはまず読み取ってから中止します — 順序を逆にすると、404 を返す前に他のプロジェクトの操作を実際に中止してしまいます。

operationId abortDatabaseOperation

ステータスコード説明レスポンスボディ
200中断された操作のステータスOperation
403
404プロジェクトにそのような操作はありませんError
409後戻りできない地点を過ぎています(not_abortable) — commit 後、または restore 操作の後です。Error

このページの目次