Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
joseivanlopez committed Nov 15, 2024
1 parent 30af376 commit 079e768
Show file tree
Hide file tree
Showing 10 changed files with 144 additions and 4 deletions.
3 changes: 2 additions & 1 deletion rust/agama-lib/share/storage.model.schema.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"title": "Config model",
"title": "Config",
"description": "Config model",
"type": "object",
"additionalProperties": false,
"properties": {
Expand Down
8 changes: 8 additions & 0 deletions rust/agama-lib/src/storage/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ use zbus::fdo::ObjectManagerProxy;
use zbus::names::{InterfaceName, OwnedInterfaceName};
use zbus::zvariant::{OwnedObjectPath, OwnedValue};
use zbus::Connection;
use serde_json::value::RawValue;
pub mod dasd;
pub mod iscsi;
pub mod zfcp;
Expand Down Expand Up @@ -160,6 +161,13 @@ impl<'a> StorageClient<'a> {
Ok(settings)
}

/// Get the storage config model according to the JSON schema
pub async fn get_config_model(&self) -> Result<Box<RawValue>, ServiceError> {
let serialized_config_model = self.storage_proxy.get_config_model().await?;
let config_model = serde_json::from_str(serialized_config_model.as_str()).unwrap();
Ok(config_model)
}

pub async fn calculate(&self, settings: ProposalSettingsPatch) -> Result<u32, ServiceError> {
Ok(self.calculator_proxy.calculate(settings.into()).await?)
}
Expand Down
3 changes: 3 additions & 0 deletions rust/agama-lib/src/storage/proxies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ trait Storage1 {
/// Get the current storage solved config according to the JSON schema
fn get_solved_config(&self) -> zbus::Result<String>;

/// Get the storage config model according to the JSON schema
fn get_config_model(&self) -> zbus::Result<String>;

/// DeprecatedSystem property
#[dbus_proxy(property)]
fn deprecated_system(&self) -> zbus::Result<bool>;
Expand Down
26 changes: 26 additions & 0 deletions rust/agama-server/src/storage/web.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ use axum::{
Json, Router,
};
use serde::{Deserialize, Serialize};
use serde_json::value::RawValue;
use tokio_stream::{Stream, StreamExt};
use zfcp::{zfcp_service, zfcp_stream};

Expand Down Expand Up @@ -114,6 +115,7 @@ pub async fn storage_service(dbus: zbus::Connection) -> Result<Router, ServiceEr
let router = Router::new()
.route("/config", put(set_config).get(get_config))
.route("/solved_config", get(get_solved_config))
.route("/config_model", get(get_config_model))
.route("/probe", post(probe))
.route("/devices/dirty", get(devices_dirty))
.route("/devices/system", get(system_devices))
Expand Down Expand Up @@ -181,6 +183,30 @@ async fn get_solved_config(
Ok(Json(settings))
}

/// Returns the storage config model.
///
/// * `state` : service state.
#[utoipa::path(
get,
path = "/config_model",
context_path = "/api/storage",
operation_id = "get_storage_config_model",
responses(
(status = 200, description = "storage config model", body = Box<RawValue>),
(status = 400, description = "The D-Bus service could not perform the action")
)
)]
async fn get_config_model(
State(state): State<StorageState<'_>>,
) -> Result<Json<Box<RawValue>>, Error> {
let config_model = state
.client
.get_config_model()
.await
.map_err(Error::Service)?;
Ok(Json(config_model))
}

/// Sets the storage configuration.
///
/// * `state`: service state.
Expand Down
6 changes: 6 additions & 0 deletions service/lib/agama/dbus/storage/manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,11 @@ def recover_config(solved: false)
JSON.pretty_generate(json)
end

def recover_model
json = proposal.model_json
JSON.pretty_generate(json)
end

def install
busy_while { backend.install }
end
Expand All @@ -142,6 +147,7 @@ def deprecated_system
end
dbus_method(:GetConfig, "out serialized_config:s") { recover_config }
dbus_method(:GetSolvedConfig, "out serialized_config:s") { recover_config(solved: true) }
dbus_method(:GetConfigModel, "out serialized_model:s") { recover_model }
dbus_method(:Install) { install }
dbus_method(:Finish) { finish }
dbus_reader(:deprecated_system, "b")
Expand Down
8 changes: 8 additions & 0 deletions service/lib/agama/storage/proposal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
require "agama/storage/actions_generator"
require "agama/storage/config_conversions/from_json"
require "agama/storage/config_conversions/to_json"
require "agama/storage/config_conversions/to_model"
require "agama/storage/proposal_settings"
require "agama/storage/proposal_strategies"
require "json"
Expand Down Expand Up @@ -97,6 +98,13 @@ def storage_json(solved: false)
end
end

def model_json
config = config(solved: true)
return nil.to_json unless config

ConfigConversions::ToModel.new(config).convert
end

# Calculates a new proposal using the given JSON.
#
# @raise If the JSON is not valid.
Expand Down
6 changes: 5 additions & 1 deletion web/src/api/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import { get, post, put } from "~/api/http";
import { Job } from "~/types/job";
import { calculate, fetchSettings } from "~/api/storage/proposal";
import { config } from "~/api/storage/types";
import { config, configModel } from "~/api/storage/types";

/**
* Starts the storage probing process.
Expand All @@ -38,6 +38,9 @@ const fetchConfig = (): Promise<config.Config | undefined> =>
const fetchSolvedConfig = (): Promise<config.Config | undefined> =>
get("/api/storage/solved_config").then((config) => config.storage);

const fetchConfigModel = (): Promise<configModel.Config | undefined> =>
get("/api/storage/config_model");

const setConfig = (config: config.Config) => put("/api/storage/config", config);

/**
Expand Down Expand Up @@ -68,6 +71,7 @@ export {
probe,
fetchConfig,
fetchSolvedConfig,
fetchConfigModel,
setConfig,
fetchStorageJobs,
findStorageJob,
Expand Down
3 changes: 2 additions & 1 deletion web/src/api/storage/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
*/

import * as config from "./types/config";
import * as configModel from "./types/config_model";

export * from "./types/openapi";
export { config };
export { config, configModel };
65 changes: 65 additions & 0 deletions web/src/api/storage/types/config_model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/* eslint-disable */
/**
* This file was automatically generated by json-schema-to-typescript.
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
* and run json-schema-to-typescript to regenerate this file.
*/

export type FilesystemType =
| "bcachefs"
| "btrfs"
| "exfat"
| "ext2"
| "ext3"
| "ext4"
| "f2fs"
| "jfs"
| "nfs"
| "nilfs2"
| "ntfs"
| "reiserfs"
| "swap"
| "tmpfs"
| "vfat"
| "xfs";
export type SpacePolicy = "delete" | "resize" | "keep" | "custom";
export type PtableType = "gpt" | "msdos" | "dasd";
export type PartitionId = "linux" | "swap" | "lvm" | "raid" | "esp" | "prep" | "bios_boot";

/**
* Config model
*/
export interface Config {
drives?: Drive[];
}
export interface Drive {
name: string;
alias?: string;
mountPath?: string;
filesystem?: Filesystem;
spacePolicy?: SpacePolicy;
ptableType?: PtableType;
partitions?: Partition[];
}
export interface Filesystem {
default: boolean;
type?: FilesystemType;
snapshots?: boolean;
}
export interface Partition {
name?: string;
alias?: string;
id?: PartitionId;
mountPath?: string;
filesystem?: Filesystem;
size?: Size;
delete?: boolean;
deleteIfNeeded?: boolean;
resize?: boolean;
resizeIfNeeded?: boolean;
}
export interface Size {
default: boolean;
min: number;
max?: number;
}
20 changes: 19 additions & 1 deletion web/src/queries/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import {
useSuspenseQuery,
} from "@tanstack/react-query";
import React from "react";
import { fetchConfig, fetchSolvedConfig, setConfig } from "~/api/storage";
import { fetchConfig, fetchSolvedConfig, fetchConfigModel, setConfig } from "~/api/storage";
import { fetchDevices, fetchDevicesDirty } from "~/api/storage/devices";
import {
calculate,
Expand All @@ -40,6 +40,7 @@ import {
import { useInstallerClient } from "~/context/installer";
import {
config,
configModel,
ProductParams,
Volume as APIVolume,
ProposalSettingsPatch,
Expand Down Expand Up @@ -67,6 +68,12 @@ const solvedConfigQuery = {
staleTime: Infinity,
};

const configModelQuery = {
queryKey: ["storage", "configModel"],
queryFn: fetchConfigModel,
staleTime: Infinity,
};

const devicesQuery = (scope: "result" | "system") => ({
queryKey: ["storage", "devices", scope],
queryFn: () => fetchDevices(scope),
Expand Down Expand Up @@ -137,6 +144,16 @@ const useSolvedConfig = (options?: QueryHookOptions): config.Config => {
return data;
};

/**
* Hook that returns the config model.
*/
const useConfigModel = (options?: QueryHookOptions): configModel.Config => {
const query = configModelQuery;
const func = options?.suspense ? useSuspenseQuery : useQuery;
const { data } = func(query);
return data;
};

/**
* Hook for setting a new config.
*/
Expand Down Expand Up @@ -347,6 +364,7 @@ export {
useConfig,
useSolvedConfig,
useConfigMutation,
useConfigModel,
useConfigDevices,
useDevices,
useAvailableDevices,
Expand Down

0 comments on commit 079e768

Please sign in to comment.