Add some extra export action

This commit is contained in:
J H
2024-03-27 15:28:54 -06:00
parent f770d5072e
commit 9cf62f03fa
3 changed files with 98 additions and 28 deletions

View File

@@ -29,6 +29,7 @@ import {
import { HostSystemStartOs } from "../../HostSystemStartOs"
import { JsonPath, unNestPath } from "../../../Models/JsonPath"
import { RpcResult, matchRpcResult } from "../../RpcListener"
import { InputSpec } from "@start9labs/start-sdk/cjs/sdk/lib/config/configTypes"
type Optional<A> = A | undefined | null
function todo(): never {
@@ -259,6 +260,35 @@ export class SystemForEmbassy implements System {
): Promise<void> {
if (previousVersion) await this.migration(effects, previousVersion)
await effects.setMainStatus({ status: "stopped" })
await this.exportActions(effects)
}
async exportActions(effects: HostSystemStartOs) {
const manifest = this.manifest
if (!manifest.actions) return
for (const [actionId, action] of Object.entries(manifest.actions)) {
const hasRunning = !!action["allowed-statuses"].find(
(x) => x === "running",
)
const hasStopped = !!action["allowed-statuses"].find(
(x) => x === "stopped",
)
// prettier-ignore
const allowedStatuses = hasRunning && hasStopped ? "any":
hasRunning ? "onlyRunning" :
"onlyStopped"
await effects.exportAction({
id: actionId,
metadata: {
name: action.name,
description: action.description,
warning: action.warning || null,
input: action["input-spec"] as InputSpec,
disabled: false,
allowedStatuses,
group: null,
},
})
}
}
private async uninit(
effects: HostSystemStartOs,

View File

@@ -3,7 +3,7 @@ use std::collections::{BTreeMap, BTreeSet};
use chrono::{DateTime, Utc};
use emver::VersionRange;
use imbl_value::InternedString;
use models::{DataUrl, HealthCheckId, HostId, PackageId};
use models::{ActionId, DataUrl, HealthCheckId, HostId, PackageId};
use patch_db::json_ptr::JsonPointer;
use patch_db::HasModel;
use reqwest::Url;
@@ -293,6 +293,28 @@ pub struct InstallingInfo {
pub new_manifest: Manifest,
pub progress: FullProgress,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub enum AllowedStatuses {
OnlyRunning, // onlyRunning
OnlyStopped,
Any,
}
#[derive(Clone, Debug, Deserialize, Serialize, HasModel, TS)]
#[serde(rename_all = "camelCase")]
#[model = "Model<Self>"]
pub struct ActionMetadata {
name: String,
description: String,
warning: Option<String>,
#[ts(type = "any")]
input: Value,
disabled: bool,
allowedStatuses: AllowedStatuses,
group: Option<String>,
}
#[derive(Debug, Deserialize, Serialize, HasModel, TS)]
#[serde(rename_all = "camelCase")]
@@ -312,6 +334,7 @@ pub struct PackageDataEntry {
pub hosts: HostInfo,
#[ts(type = "string[]")]
pub store_exposed_dependents: Vec<JsonPointer>,
pub exposed_actions: BTreeMap<ActionId, ActionMetadata>,
}
impl AsRef<PackageDataEntry> for PackageDataEntry {
fn as_ref(&self) -> &PackageDataEntry {

View File

@@ -20,7 +20,7 @@ use ts_rs::TS;
use url::Url;
use crate::db::model::package::{
CurrentDependencies, CurrentDependencyInfo, CurrentDependencyKind,
ActionMetadata, CurrentDependencies, CurrentDependencyInfo, CurrentDependencyKind,
};
use crate::disk::mount::filesystem::idmapped::IdMapped;
use crate::disk::mount::filesystem::loop_dev::LoopDev;
@@ -254,14 +254,6 @@ struct ListServiceInterfacesParams {
struct RemoveAddressParams {
id: String,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
enum AllowedStatuses {
OnlyRunning, // onlyRunning
OnlyStopped,
Any,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[ts(export)]
@@ -274,21 +266,9 @@ struct ExportActionParams {
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
struct ActionMetadata {
name: String,
description: String,
warning: Option<String>,
disabled: bool,
#[ts(type = "{[key: string]: any}")]
input: Value,
allowed_statuses: AllowedStatuses,
group: Option<String>,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
struct RemoveActionParams {
id: String,
#[ts(type = "string")]
id: ActionId,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[ts(export)]
@@ -387,11 +367,48 @@ async fn list_service_interfaces(
async fn remove_address(context: EffectContext, data: RemoveAddressParams) -> Result<Value, Error> {
todo!()
}
async fn export_action(context: EffectContext, data: ExportActionParams) -> Result<Value, Error> {
todo!()
async fn export_action(context: EffectContext, data: ExportActionParams) -> Result<(), Error> {
let context = context.deref()?;
let package_id = context.id.clone();
context
.ctx
.db
.mutate(|db| {
let model = db
.as_public_mut()
.as_package_data_mut()
.as_idx_mut(&package_id)
.or_not_found(&package_id)?
.as_exposed_actions_mut();
let mut value = model.de()?;
value
.insert(data.id, data.metadata)
.map(|_| ())
.unwrap_or_default();
model.ser(&value)
})
.await?;
Ok(())
}
async fn remove_action(context: EffectContext, data: RemoveActionParams) -> Result<Value, Error> {
todo!()
async fn remove_action(context: EffectContext, data: RemoveActionParams) -> Result<(), Error> {
let context = context.deref()?;
let package_id = context.id.clone();
context
.ctx
.db
.mutate(|db| {
let model = db
.as_public_mut()
.as_package_data_mut()
.as_idx_mut(&package_id)
.or_not_found(&package_id)?
.as_exposed_actions_mut();
let mut value = model.de()?;
value.remove(&data.id).map(|_| ()).unwrap_or_default();
model.ser(&value)
})
.await?;
Ok(())
}
async fn reverse_proxy(context: EffectContext, data: ReverseProxyParams) -> Result<Value, Error> {
todo!()