Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(rust): describe the licenses API in OpenAPI #1929

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions rust/agama-lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ chrono = { version = "0.4.38", default-features = false, features = [
home = "0.5.9"
strum = { version = "0.26.3", features = ["derive"] }
fs_extra = "1.3.0"
serde_with = "3.12.0"
regex = "1.11.1"

[dev-dependencies]
httpmock = "0.7.0"
Expand Down
107 changes: 7 additions & 100 deletions rust/agama-lib/src/software/model.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) [2024] SUSE LLC
// Copyright (c) [2025] SUSE LLC
//
// All Rights Reserved.
//
Expand All @@ -18,103 +18,10 @@
// To contact SUSE LLC about this file by physical or electronic mail, you may
// find current contact information at www.suse.com.

use serde::{Deserialize, Serialize};
use std::collections::HashMap;
mod license;
mod packages;
mod registration;

/// Software service configuration (product, patterns, etc.).
#[derive(Clone, Serialize, Deserialize, utoipa::ToSchema)]
pub struct SoftwareConfig {
/// A map where the keys are the pattern names and the values whether to install them or not.
pub patterns: Option<HashMap<String, bool>>,
/// Name of the product to install.
pub product: Option<String>,
}

/// Software service configuration (product, patterns, etc.).
#[derive(Clone, Serialize, Deserialize, utoipa::ToSchema)]
pub struct RegistrationParams {
/// Registration key.
pub key: String,
/// Registration email.
pub email: String,
}

/// Information about registration configuration (product, patterns, etc.).
#[derive(Clone, Serialize, Deserialize, utoipa::ToSchema)]
#[serde(rename_all = "camelCase")]
pub struct RegistrationInfo {
/// Registration key. Empty value mean key not used or not registered.
pub key: String,
/// Registration email. Empty value mean email not used or not registered.
pub email: String,
}

#[derive(
Clone,
Default,
Debug,
Serialize,
Deserialize,
strum::Display,
strum::EnumString,
utoipa::ToSchema,
)]
#[strum(serialize_all = "camelCase")]
#[serde(rename_all = "camelCase")]
pub enum RegistrationRequirement {
/// Product does not require registration
#[default]
No = 0,
/// Product has optional registration
Optional = 1,
/// It is mandatory to register the product
Mandatory = 2,
}

#[derive(Clone, Serialize, Deserialize, utoipa::ToSchema)]
pub struct RegistrationError {
/// ID of error. See dbus API for possible values
pub id: u32,
/// human readable error string intended to be displayed to user
pub message: String,
}

/// Software resolvable type (package or pattern).
#[derive(Deserialize, Serialize, strum::Display, utoipa::ToSchema)]
#[strum(serialize_all = "camelCase")]
#[serde(rename_all = "camelCase")]
pub enum ResolvableType {
Package = 0,
Pattern = 1,
}

/// Resolvable list specification.
#[derive(Deserialize, Serialize, utoipa::ToSchema)]
pub struct ResolvableParams {
/// List of resolvables.
pub names: Vec<String>,
/// Resolvable type.
pub r#type: ResolvableType,
/// Whether the resolvables are optional or not.
pub optional: bool,
}

/// Repository list specification.
#[derive(Deserialize, Serialize, utoipa::ToSchema)]
#[serde(rename_all = "camelCase")]
pub struct Repository {
/// repository identifier
pub id: i32,
/// repository alias. Has to be unique
pub alias: String,
/// repository name
pub name: String,
/// Repository url (raw format without expanded variables)
pub url: String,
/// product directory (currently not used, valid only for multiproduct DVDs)
pub product_dir: String,
/// Whether the repository is enabled
pub enabled: bool,
/// Whether the repository is loaded
pub loaded: bool,
}
pub use license::*;
pub use packages::*;
pub use registration::*;
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) [2024] SUSE LLC
// Copyright (c) [2024-2025] SUSE LLC
//
// All Rights Reserved.
//
Expand Down Expand Up @@ -34,9 +34,11 @@ use thiserror::Error;
///
/// It contains the license ID and the list of languages that with a translation.
#[serde_as]
#[derive(Clone, Debug, Serialize)]
#[derive(Clone, Debug, Serialize, utoipa::ToSchema)]
pub struct License {
/// License ID.
pub id: String,
/// Languages in which the license is translated.
#[serde_as(as = "Vec<DisplayFromStr>")]
pub languages: Vec<LanguageTag>,
}
Expand All @@ -46,9 +48,11 @@ pub struct License {
/// It contains the license ID and the body.
///
/// TODO: in the future it might contain a title, extracted from the text.
#[derive(Clone, Debug, Serialize)]
#[derive(Clone, Debug, Serialize, utoipa::ToSchema)]
pub struct LicenseContent {
/// License ID.
pub id: String,
/// License text.
pub body: String,
}

Expand Down Expand Up @@ -106,13 +110,13 @@ impl LicensesRepo {
}
candidates.push(format!("license.{}.txt", language.language));
candidates.push("license.txt".to_string());
tracing::info!("Searching for license: {:?}", &candidates);
log::info!("Searching for license: {:?}", &candidates);

let license_path = candidates
.into_iter()
.map(|p| self.path.join(id).join(p))
.find(|p| p.exists())?;
tracing::info!("Reading license from {}", &license_path.display());
log::info!("Reading license from {}", &license_path.display());

let body: String = std::fs::read_to_string(license_path).ok()?;

Expand Down Expand Up @@ -146,7 +150,7 @@ impl LicensesRepo {
/// The language is inferred from the file name (e.g., "es-ES" for license.es_ES.txt").
fn language_tag_from_file(name: &str) -> Option<LanguageTag> {
if !name.starts_with("license") {
tracing::warn!("Unexpected file in the licenses directory: {}", &name);
log::warn!("Unexpected file in the licenses directory: {}", &name);
return None;
}
let mut parts = name.split(".");
Expand Down Expand Up @@ -175,7 +179,7 @@ impl Default for LicensesRepo {
/// Simplified representation of the RFC 5646 language code.
///
/// It only considers xx and xx-XX formats.
#[derive(Clone, Debug, Serialize, PartialEq)]
#[derive(Clone, Debug, Serialize, PartialEq, utoipa::ToSchema)]
pub struct LanguageTag {
// ISO-639
pub language: String,
Expand Down Expand Up @@ -225,8 +229,7 @@ impl TryFrom<&str> for LanguageTag {

#[cfg(test)]
mod test {
use super::LicensesRepo;
use crate::software::license::LanguageTag;
use super::{LanguageTag, LicensesRepo};
use std::path::Path;

fn build_repo() -> LicensesRepo {
Expand Down
71 changes: 71 additions & 0 deletions rust/agama-lib/src/software/model/packages.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Copyright (c) [2025] SUSE LLC
//
// All Rights Reserved.
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 of the License, or (at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, contact SUSE LLC.
//
// To contact SUSE LLC about this file by physical or electronic mail, you may
// find current contact information at www.suse.com.

use serde::{Deserialize, Serialize};
use std::collections::HashMap;

/// Software service configuration (product, patterns, etc.).
#[derive(Clone, Serialize, Deserialize, utoipa::ToSchema)]
pub struct SoftwareConfig {
/// A map where the keys are the pattern names and the values whether to install them or not.
pub patterns: Option<HashMap<String, bool>>,
/// Name of the product to install.
pub product: Option<String>,
}

/// Software resolvable type (package or pattern).
#[derive(Deserialize, Serialize, strum::Display, utoipa::ToSchema)]
#[strum(serialize_all = "camelCase")]
#[serde(rename_all = "camelCase")]
pub enum ResolvableType {
Package = 0,
Pattern = 1,
}

/// Resolvable list specification.
#[derive(Deserialize, Serialize, utoipa::ToSchema)]
pub struct ResolvableParams {
/// List of resolvables.
pub names: Vec<String>,
/// Resolvable type.
pub r#type: ResolvableType,
/// Whether the resolvables are optional or not.
pub optional: bool,
}

/// Repository list specification.
#[derive(Deserialize, Serialize, utoipa::ToSchema)]
#[serde(rename_all = "camelCase")]
pub struct Repository {
/// repository identifier
pub id: i32,
/// repository alias. Has to be unique
pub alias: String,
/// repository name
pub name: String,
/// Repository url (raw format without expanded variables)
pub url: String,
/// product directory (currently not used, valid only for multiproduct DVDs)
pub product_dir: String,
/// Whether the repository is enabled
pub enabled: bool,
/// Whether the repository is loaded
pub loaded: bool,
}
70 changes: 70 additions & 0 deletions rust/agama-lib/src/software/model/registration.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright (c) [2025] SUSE LLC
//
// All Rights Reserved.
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 of the License, or (at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, contact SUSE LLC.
//
// To contact SUSE LLC about this file by physical or electronic mail, you may
// find current contact information at www.suse.com.

use serde::{Deserialize, Serialize};

/// Software service configuration (product, patterns, etc.).
#[derive(Clone, Serialize, Deserialize, utoipa::ToSchema)]
pub struct RegistrationParams {
/// Registration key.
pub key: String,
/// Registration email.
pub email: String,
}

/// Information about registration configuration (product, patterns, etc.).
#[derive(Clone, Serialize, Deserialize, utoipa::ToSchema)]
#[serde(rename_all = "camelCase")]
pub struct RegistrationInfo {
/// Registration key. Empty value mean key not used or not registered.
pub key: String,
/// Registration email. Empty value mean email not used or not registered.
pub email: String,
}

#[derive(
Clone,
Default,
Debug,
Serialize,
Deserialize,
strum::Display,
strum::EnumString,
utoipa::ToSchema,
)]
#[strum(serialize_all = "camelCase")]
#[serde(rename_all = "camelCase")]
pub enum RegistrationRequirement {
/// Product does not require registration
#[default]
No = 0,
/// Product has optional registration
Optional = 1,
/// It is mandatory to register the product
Mandatory = 2,
}

#[derive(Clone, Serialize, Deserialize, utoipa::ToSchema)]
pub struct RegistrationError {
/// ID of error. See dbus API for possible values
pub id: u32,
/// human readable error string intended to be displayed to user
pub message: String,
}
1 change: 0 additions & 1 deletion rust/agama-server/src/software.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,3 @@

pub mod web;
pub use web::{software_service, software_streams};
mod license;
Loading
Loading