Skip to content
Merged
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
30 changes: 30 additions & 0 deletions rust/agama-lib/share/profile.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@
"$ref": "#/$defs/preScript"
}
},
"postPartitioning": {
"title": "Post-partitioning scripts",
"description": "User-defined scripts to run after the partitioning finishes",
"type": "array",
"items": {
"$ref": "#/$defs/postPartitioning"
}
},
"post": {
"title": "Post-installation scripts",
"description": "User-defined scripts to run after the installation finishes",
Expand Down Expand Up @@ -1466,6 +1474,28 @@
"required": ["name"],
"oneOf": [{ "required": ["body"] }, { "required": ["url"] }]
},
"postPartitioning": {
"title": "User-defined installation script that runs after the partitioning finishes",
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"description": "Script name, to be used as file name",
"type": "string"
},
"body": {
"title": "Script content",
"description": "Script content, starting with the shebang",
"type": "string"
},
"url": {
"title": "Script URL",
"description": "URL to fetch the script from"
}
},
"required": ["name"],
"oneOf": [{ "required": ["body"] }, { "required": ["url"] }]
},
"postScript": {
"title": "User-defined installation script that runs after the installation finishes",
"type": "object",
Expand Down
32 changes: 31 additions & 1 deletion rust/agama-lib/src/scripts/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ use super::ScriptError;
#[serde(rename_all = "camelCase")]
pub enum ScriptsGroup {
Pre,
PostPartitioning,
Post,
Init,
}
Expand Down Expand Up @@ -84,9 +85,10 @@ pub enum ScriptSource {
///
/// There are different types of scripts that can run at different stages of the installation.
#[derive(Clone, Debug, Serialize, Deserialize, utoipa::ToSchema)]
#[serde(tag = "type")]
#[serde(tag = "type", rename_all = "camelCase")]
pub enum Script {
Pre(PreScript),
PostPartitioning(PostPartitioningScript),
Post(PostScript),
Init(InitScript),
}
Expand All @@ -95,6 +97,7 @@ impl Script {
fn base(&self) -> &BaseScript {
match self {
Script::Pre(inner) => &inner.base,
Script::PostPartitioning(inner) => &inner.base,
Script::Post(inner) => &inner.base,
Script::Init(inner) => &inner.base,
}
Expand All @@ -119,6 +122,7 @@ impl Script {
pub fn group(&self) -> ScriptsGroup {
match self {
Script::Pre(_) => ScriptsGroup::Pre,
Script::PostPartitioning(_) => ScriptsGroup::PostPartitioning,
Script::Post(_) => ScriptsGroup::Post,
Script::Init(_) => ScriptsGroup::Init,
}
Expand All @@ -136,6 +140,7 @@ impl Script {
.join(self.name());
let runner = match self {
Script::Pre(inner) => &inner.runner(),
Script::PostPartitioning(inner) => &inner.runner(),
Script::Post(inner) => &inner.runner(),
Script::Init(inner) => &inner.runner(),
};
Expand Down Expand Up @@ -183,6 +188,31 @@ impl TryFrom<Script> for PreScript {

impl WithRunner for PreScript {}

/// Represents a script that runs after partitioning.
#[derive(Clone, Debug, Serialize, Deserialize, utoipa::ToSchema)]
pub struct PostPartitioningScript {
#[serde(flatten)]
pub base: BaseScript,
}

impl From<PostPartitioningScript> for Script {
fn from(value: PostPartitioningScript) -> Self {
Self::PostPartitioning(value)
}
}

impl TryFrom<Script> for PostPartitioningScript {
type Error = ScriptError;

fn try_from(value: Script) -> Result<Self, Self::Error> {
match value {
Script::PostPartitioning(inner) => Ok(inner),
_ => Err(ScriptError::WrongScriptType),
}
}
}

impl WithRunner for PostPartitioningScript {}
/// Represents a script that runs after the installation finishes.
#[derive(Clone, Debug, Serialize, Deserialize, utoipa::ToSchema)]
pub struct PostScript {
Expand Down
5 changes: 4 additions & 1 deletion rust/agama-lib/src/scripts/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,17 @@

use serde::{Deserialize, Serialize};

use super::{InitScript, PostScript, PreScript};
use super::{InitScript, PostPartitioningScript, PostScript, PreScript};

#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ScriptsConfig {
/// User-defined pre-installation scripts
#[serde(skip_serializing_if = "Option::is_none")]
pub pre: Option<Vec<PreScript>>,
/// User-defined post-partitioning scripts
#[serde(skip_serializing_if = "Option::is_none")]
pub post_partitioning: Option<Vec<PostPartitioningScript>>,
/// User-defined post-installation scripts
#[serde(skip_serializing_if = "Option::is_none")]
pub post: Option<Vec<PostScript>>,
Expand Down
7 changes: 7 additions & 0 deletions rust/agama-lib/src/scripts/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ impl ScriptsStore {

Ok(ScriptsConfig {
pre: Self::scripts_by_type(&scripts),
post_partitioning: Self::scripts_by_type(&scripts),
post: Self::scripts_by_type(&scripts),
init: Self::scripts_by_type(&scripts),
})
Expand All @@ -58,6 +59,12 @@ impl ScriptsStore {
}
}

if let Some(scripts) = &settings.post_partitioning {
for post in scripts {
self.scripts.add_script(post.clone().into()).await?;
}
}

if let Some(scripts) = &settings.post {
for post in scripts {
self.scripts.add_script(post.clone().into()).await?;
Expand Down
1 change: 1 addition & 0 deletions rust/agama-server/src/web/docs/scripts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ impl ApiDocBuilder for ScriptsApiDocBuilder {
ComponentsBuilder::new()
.schema_from::<agama_lib::scripts::BaseScript>()
.schema_from::<agama_lib::scripts::InitScript>()
.schema_from::<agama_lib::scripts::PostPartitioningScript>()
.schema_from::<agama_lib::scripts::PostScript>()
.schema_from::<agama_lib::scripts::PreScript>()
.schema_from::<agama_lib::scripts::Script>()
Expand Down
12 changes: 12 additions & 0 deletions service/lib/agama/autoyast/scripts_reader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ def initialize(profile)
# @return [Hash] Agama "scripts" section
def read
scripts = {}
.merge(read_post_partitioning_scripts)
.merge(read_post_scripts)
.merge(read_init_scripts)
return {} if scripts.empty?
Expand All @@ -68,6 +69,17 @@ def scripts_section
@scripts_section ||= profile.fetch("scripts", {})
end

# Reads the "postpartitioning-scripts" section and builds an Agama "postPartitioning"
# section.
def read_post_partitioning_scripts
scripts = scripts_section.fetch("postpartitioning-scripts", []).map do |script|
read_script(script)
end
return {} if scripts.empty?

{ "postPartitioning" => scripts }
end

# Reads the "chroot-scripts" section and builds an Agama "post" section.
def read_post_scripts
scripts = scripts_section.fetch("chroot-scripts", []).map do |script|
Expand Down
12 changes: 10 additions & 2 deletions service/lib/agama/manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
require "agama/dbus/clients/software"
require "agama/dbus/clients/storage"
require "agama/helpers"
require "agama/http"

Yast.import "Stage"

Expand Down Expand Up @@ -108,7 +109,7 @@ def config_phase
end

# Runs the install phase
# rubocop:disable Metrics/AbcSize
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
def install_phase
service_status.busy
installation_phase.install
Expand All @@ -122,6 +123,7 @@ def install_phase

progress.step do
storage.install
run_post_partitioning_scripts
proxy.propose
# propose software after /mnt is already separated, so it uses proper
# target
Expand All @@ -147,7 +149,7 @@ def install_phase
installation_phase.finish
finish_progress
end
# rubocop:enable Metrics/AbcSize
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength

def locale=(locale)
service_status.busy
Expand Down Expand Up @@ -285,5 +287,11 @@ def probe_and_recover_storage
storage.probe
storage.config = storage_config unless storage_config.empty?
end

# Runs post partitioning scripts
def run_post_partitioning_scripts
client = Agama::HTTP::Clients::Scripts.new
client.run("post_partitioning")
end
end
end
1 change: 1 addition & 0 deletions service/lib/agama/storage/finisher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
require "y2storage/storage_manager"
require "agama/with_progress"
require "agama/helpers"
require "agama/http"
require "abstract_method"

Yast.import "Arch"
Expand Down
5 changes: 5 additions & 0 deletions service/package/rubygem-agama-yast.changes
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
-------------------------------------------------------------------
Mon Feb 17 09:17:47 UTC 2025 - Imobach Gonzalez Sosa <igonzalezsosa@suse.com>

- Add support for post-partitioning scripts (jsc#AGM-108).

-------------------------------------------------------------------
Thu Feb 13 21:37:32 UTC 2025 - Imobach Gonzalez Sosa <igonzalezsosa@suse.com>

Expand Down
31 changes: 31 additions & 0 deletions service/share/autoyast-compat.json
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,37 @@
{ "key": "rerun", "support": "no" }
]
},
{
"key": "postpartitioning-scripts[]",
"children": [
{
"key": "filename",
"support": "yes",
"agama": "scripts.postPartitioning[].name"
},
{
"key": "location",
"support": "yes",
"agama": "scripts.postPartitioning[].url"
},
{
"key": "source",
"support": "yes",
"agama": "scripts.postPartitioning[].body"
},
{
"key": "interpreter",
"support": "no",
"notes": "Use the shebang line in your scripts."
},
{ "key": "feedback", "support": "no" },
{ "key": "feedback_type", "support": "no" },
{ "key": "debug", "support": "no" },
{ "key": "notification", "support": "no" },
{ "key": "param-list", "support": "no" },
{ "key": "rerun", "support": "no" }
]
},
{
"key": "chroot-scripts[]",
"agama": "scripts.post[]",
Expand Down
4 changes: 4 additions & 0 deletions service/test/agama/autoyast/scripts_reader_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@
end
end

context "when a post-partitioning scripts is defined" do
it_behaves_like "a script reader", "postpartitioning-scripts", "postPartitioning"
end

context "when an init script is defined" do
it_behaves_like "a script reader", "init-scripts", "init"
end
Expand Down
8 changes: 8 additions & 0 deletions service/test/agama/manager_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@
on_service_status_change: nil, errors?: false
)
end
let(:scripts) do
instance_double(
Agama::HTTP::Clients::Scripts, run: nil
)
end

let(:product) { nil }

Expand All @@ -70,6 +75,8 @@
allow(Agama::DBus::Clients::Software).to receive(:new).and_return(software)
allow(Agama::DBus::Clients::Storage).to receive(:new).and_return(storage)
allow(Agama::Users).to receive(:new).and_return(users)
allow(Agama::HTTP::Clients::Scripts).to receive(:new)
.and_return(scripts)
end

describe "#startup_phase" do
Expand Down Expand Up @@ -133,6 +140,7 @@
expect(software).to receive(:finish)
expect(locale).to receive(:finish)
expect(storage).to receive(:install)
expect(scripts).to receive(:run).with("post_partitioning")
expect(storage).to receive(:finish)
expect(users).to receive(:write)
subject.install_phase
Expand Down