Skip to content

Commit 34ca0e8

Browse files
committed
Merge branch 'main' of https://github.com/Gijsreyn/operation-methods into add-pending-reboot-reason
2 parents 12a095e + 3562d88 commit 34ca0e8

25 files changed

+1471
-80
lines changed

.github/workflows/rust.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ name: Rust
22

33
on:
44
push:
5-
branches: [ "main" ]
5+
branches: [ "main", "release/v3.0.0", "release/v3.1" ]
66
pull_request:
7-
branches: [ "main" ]
7+
branches: [ "main", "release/v3.0.0", "release/v3.1" ]
88
paths-ignore:
99
- "docs/**"
1010
- "*.md"

build.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ if (!$SkipBuild) {
256256
}
257257

258258
# make sure dependencies are built first so clippy runs correctly
259-
$windows_projects = @("pal", "registry", "reboot_pending", "wmi-adapter", "configurations/windows", 'extensions/appx')
259+
$windows_projects = @("pal", "registry_lib", "registry", "reboot_pending", "wmi-adapter", "configurations/windows", 'extensions/appx')
260260
$macOS_projects = @("resources/brew")
261261
$linux_projects = @("resources/apt")
262262

dsc/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dsc/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "dsc"
3-
version = "3.1.0-preview.7"
3+
version = "3.2.0-preview.1"
44
edition = "2021"
55

66
[profile.release]

dsc/locales/en-us.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ resource = "The name of the resource to invoke"
3737
ctrlCReceived = "Ctrl-C received"
3838
failedCtrlCHandler = "Failed to set Ctrl-C handler"
3939
failedReadingParametersFile = "Failed to read parameters file"
40+
readingParametersFromStdin = "Reading parameters from STDIN"
4041
generatingCompleter = "Generating completion script for"
4142
readingParametersFile = "Reading parameters from file"
4243
usingDscVersion = "Running DSC version"
@@ -133,3 +134,4 @@ failedToAbsolutizePath = "Error making config path absolute"
133134
failedToGetParentPath = "Error reading config path parent"
134135
dscConfigRootAlreadySet = "The current value of DSC_CONFIG_ROOT env var will be overridden"
135136
settingDscConfigRoot = "Setting DSC_CONFIG_ROOT env var as"
137+
stdinNotAllowedForBothParametersAndInput = "Cannot read from STDIN for both parameters and input."

dsc/src/args.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ pub enum OutputFormat {
1919
pub enum GetOutputFormat {
2020
Json,
2121
JsonArray,
22+
PassThrough,
2223
PrettyJson,
2324
Yaml,
2425
}

dsc/src/main.rs

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ use args::{Args, SubCommand};
55
use clap::{CommandFactory, Parser};
66
use clap_complete::generate;
77
use rust_i18n::{i18n, t};
8-
use std::{io, process::exit};
8+
use std::{io, io::Read, process::exit};
99
use sysinfo::{Process, RefreshKind, System, get_current_pid, ProcessRefreshKind};
1010
use tracing::{error, info, warn, debug};
1111
use dsc_lib::progress::ProgressFormat;
1212

13+
use crate::util::EXIT_INVALID_INPUT;
14+
1315
#[cfg(debug_assertions)]
1416
use crossterm::event;
1517
#[cfg(debug_assertions)]
@@ -51,17 +53,40 @@ fn main() {
5153
},
5254
SubCommand::Config { subcommand, parameters, parameters_file, system_root, as_group, as_assert, as_include } => {
5355
if let Some(file_name) = parameters_file {
56+
if file_name == "-" {
57+
info!("{}", t!("main.readingParametersFromStdin"));
58+
let mut stdin = Vec::<u8>::new();
59+
let parameters = match io::stdin().read_to_end(&mut stdin) {
60+
Ok(_) => {
61+
match String::from_utf8(stdin) {
62+
Ok(input) => {
63+
input
64+
},
65+
Err(err) => {
66+
error!("{}: {err}", t!("util.invalidUtf8"));
67+
exit(EXIT_INVALID_INPUT);
68+
}
69+
}
70+
},
71+
Err(err) => {
72+
error!("{}: {err}", t!("util.failedToReadStdin"));
73+
exit(EXIT_INVALID_INPUT);
74+
}
75+
};
76+
subcommand::config(&subcommand, &Some(parameters), true, system_root.as_ref(), &as_group, &as_assert, &as_include, progress_format);
77+
return;
78+
}
5479
info!("{}: {file_name}", t!("main.readingParametersFile"));
5580
match std::fs::read_to_string(&file_name) {
56-
Ok(parameters) => subcommand::config(&subcommand, &Some(parameters), system_root.as_ref(), &as_group, &as_assert, &as_include, progress_format),
81+
Ok(parameters) => subcommand::config(&subcommand, &Some(parameters), false, system_root.as_ref(), &as_group, &as_assert, &as_include, progress_format),
5782
Err(err) => {
5883
error!("{} '{file_name}': {err}", t!("main.failedReadingParametersFile"));
5984
exit(util::EXIT_INVALID_INPUT);
6085
}
6186
}
6287
}
6388
else {
64-
subcommand::config(&subcommand, &parameters, system_root.as_ref(), &as_group, &as_assert, &as_include, progress_format);
89+
subcommand::config(&subcommand, &parameters, false, system_root.as_ref(), &as_group, &as_assert, &as_include, progress_format);
6590
}
6691
},
6792
SubCommand::Extension { subcommand } => {

dsc/src/resource_command.rs

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use dsc_lib::{
1616
};
1717
use std::process::exit;
1818

19-
pub fn get(dsc: &DscManager, resource_type: &str, input: &str, format: Option<&OutputFormat>) {
19+
pub fn get(dsc: &DscManager, resource_type: &str, input: &str, format: Option<&GetOutputFormat>) {
2020
let Some(resource) = get_resource(dsc, resource_type) else {
2121
error!("{}", DscError::ResourceNotFound(resource_type.to_string()).to_string());
2222
exit(EXIT_DSC_RESOURCE_NOT_FOUND);
@@ -30,18 +30,37 @@ pub fn get(dsc: &DscManager, resource_type: &str, input: &str, format: Option<&O
3030

3131
match resource.get(input) {
3232
Ok(result) => {
33+
if let GetResult::Resource(response) = &result {
34+
if format == Some(&GetOutputFormat::PassThrough) {
35+
let json = match serde_json::to_string(&response.actual_state) {
36+
Ok(json) => json,
37+
Err(err) => {
38+
error!("{}", t!("resource_command.jsonError", err = err));
39+
exit(EXIT_JSON_ERROR);
40+
}
41+
};
42+
write_object(&json, Some(&OutputFormat::Json), false);
43+
return;
44+
}
45+
}
46+
3347
// convert to json
3448
let json = match serde_json::to_string(&result) {
3549
Ok(json) => json,
3650
Err(err) => {
37-
error!("JSON Error: {err}");
51+
error!("{}", t!("resource_command.jsonError", err = err));
3852
exit(EXIT_JSON_ERROR);
3953
}
4054
};
55+
let format = match format {
56+
Some(&GetOutputFormat::PrettyJson) => Some(&OutputFormat::PrettyJson),
57+
Some(&GetOutputFormat::Yaml) => Some(&OutputFormat::Yaml),
58+
_ => Some(&OutputFormat::Json),
59+
};
4160
write_object(&json, format, false);
4261
}
4362
Err(err) => {
44-
error!("Error: {err}");
63+
error!("{err}");
4564
exit(EXIT_DSC_ERROR);
4665
}
4766
}
@@ -63,7 +82,7 @@ pub fn get_all(dsc: &DscManager, resource_type: &str, format: Option<&GetOutputF
6382
let export_result = match resource.export(&input) {
6483
Ok(export) => { export }
6584
Err(err) => {
66-
error!("Error: {err}");
85+
error!("{err}");
6786
exit(EXIT_DSC_ERROR);
6887
}
6988
};
@@ -127,14 +146,14 @@ pub fn set(dsc: &DscManager, resource_type: &str, input: &str, format: Option<&O
127146
let json = match serde_json::to_string(&result) {
128147
Ok(json) => json,
129148
Err(err) => {
130-
error!("JSON Error: {err}");
149+
error!("{}", t!("resource_command.jsonError", err = err));
131150
exit(EXIT_JSON_ERROR);
132151
}
133152
};
134153
write_object(&json, format, false);
135154
}
136155
Err(err) => {
137-
error!("Error: {err}");
156+
error!("{err}");
138157
exit(EXIT_DSC_ERROR);
139158
}
140159
}
@@ -191,7 +210,7 @@ pub fn delete(dsc: &DscManager, resource_type: &str, input: &str) {
191210
match resource.delete(input) {
192211
Ok(()) => {}
193212
Err(err) => {
194-
error!("Error: {err}");
213+
error!("{err}");
195214
exit(EXIT_DSC_ERROR);
196215
}
197216
}
@@ -213,14 +232,14 @@ pub fn schema(dsc: &DscManager, resource_type: &str, format: Option<&OutputForma
213232
match serde_json::from_str::<serde_json::Value>(json.as_str()) {
214233
Ok(_) => (),
215234
Err(err) => {
216-
error!("Error: {err}");
235+
error!("{err}");
217236
exit(EXIT_JSON_ERROR);
218237
}
219238
}
220239
write_object(&json, format, false);
221240
}
222241
Err(err) => {
223-
error!("Error: {err}");
242+
error!("{err}");
224243
exit(EXIT_DSC_ERROR);
225244
}
226245
}

dsc/src/subcommand.rs

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -271,15 +271,16 @@ fn initialize_config_root(path: Option<&String>) -> Option<String> {
271271
}
272272

273273
#[allow(clippy::too_many_lines)]
274-
pub fn config(subcommand: &ConfigSubCommand, parameters: &Option<String>, mounted_path: Option<&String>, as_group: &bool, as_assert: &bool, as_include: &bool, progress_format: ProgressFormat) {
274+
#[allow(clippy::too_many_arguments)]
275+
pub fn config(subcommand: &ConfigSubCommand, parameters: &Option<String>, parameters_from_stdin: bool, mounted_path: Option<&String>, as_group: &bool, as_assert: &bool, as_include: &bool, progress_format: ProgressFormat) {
275276
let (new_parameters, json_string) = match subcommand {
276277
ConfigSubCommand::Get { input, file, .. } |
277278
ConfigSubCommand::Set { input, file, .. } |
278279
ConfigSubCommand::Test { input, file, .. } |
279280
ConfigSubCommand::Validate { input, file, .. } |
280281
ConfigSubCommand::Export { input, file, .. } => {
281282
let new_path = initialize_config_root(file.as_ref());
282-
let document = get_input(input.as_ref(), new_path.as_ref());
283+
let document = get_input(input.as_ref(), new_path.as_ref(), parameters_from_stdin);
283284
if *as_include {
284285
let (new_parameters, config_json) = match get_contents(&document) {
285286
Ok((parameters, config_json)) => (parameters, config_json),
@@ -295,7 +296,7 @@ pub fn config(subcommand: &ConfigSubCommand, parameters: &Option<String>, mounte
295296
},
296297
ConfigSubCommand::Resolve { input, file, .. } => {
297298
let new_path = initialize_config_root(file.as_ref());
298-
let document = get_input(input.as_ref(), new_path.as_ref());
299+
let document = get_input(input.as_ref(), new_path.as_ref(), parameters_from_stdin);
299300
let (new_parameters, config_json) = match get_contents(&document) {
300301
Ok((parameters, config_json)) => (parameters, config_json),
301302
Err(err) => {
@@ -391,7 +392,7 @@ pub fn config(subcommand: &ConfigSubCommand, parameters: &Option<String>, mounte
391392
};
392393
if *as_include {
393394
let new_path = initialize_config_root(file.as_ref());
394-
let input = get_input(input.as_ref(), new_path.as_ref());
395+
let input = get_input(input.as_ref(), new_path.as_ref(), parameters_from_stdin);
395396
match serde_json::from_str::<Include>(&input) {
396397
Ok(_) => {
397398
// valid, so do nothing
@@ -582,40 +583,36 @@ pub fn resource(subcommand: &ResourceSubCommand, progress_format: ProgressFormat
582583
},
583584
ResourceSubCommand::Export { resource, input, file, output_format } => {
584585
dsc.find_resources(&[resource.to_string()], progress_format);
585-
let parsed_input = get_input(input.as_ref(), file.as_ref());
586+
let parsed_input = get_input(input.as_ref(), file.as_ref(), false);
586587
resource_command::export(&mut dsc, resource, &parsed_input, output_format.as_ref());
587588
},
588589
ResourceSubCommand::Get { resource, input, file: path, all, output_format } => {
589590
dsc.find_resources(&[resource.to_string()], progress_format);
590-
if *all { resource_command::get_all(&dsc, resource, output_format.as_ref()); }
591+
if *all {
592+
resource_command::get_all(&dsc, resource, output_format.as_ref());
593+
}
591594
else {
592-
let parsed_input = get_input(input.as_ref(), path.as_ref());
593-
let format = match output_format {
594-
Some(GetOutputFormat::Json) => Some(OutputFormat::Json),
595-
Some(GetOutputFormat::JsonArray) => {
596-
error!("{}", t!("subcommand.jsonArrayNotSupported"));
597-
exit(EXIT_INVALID_ARGS);
598-
},
599-
Some(GetOutputFormat::PrettyJson) => Some(OutputFormat::PrettyJson),
600-
Some(GetOutputFormat::Yaml) => Some(OutputFormat::Yaml),
601-
None => None,
602-
};
603-
resource_command::get(&dsc, resource, &parsed_input, format.as_ref());
595+
if *output_format == Some(GetOutputFormat::JsonArray) {
596+
error!("{}", t!("subcommand.jsonArrayNotSupported"));
597+
exit(EXIT_INVALID_ARGS);
598+
}
599+
let parsed_input = get_input(input.as_ref(), path.as_ref(), false);
600+
resource_command::get(&dsc, resource, &parsed_input, output_format.as_ref());
604601
}
605602
},
606603
ResourceSubCommand::Set { resource, input, file: path, output_format } => {
607604
dsc.find_resources(&[resource.to_string()], progress_format);
608-
let parsed_input = get_input(input.as_ref(), path.as_ref());
605+
let parsed_input = get_input(input.as_ref(), path.as_ref(), false);
609606
resource_command::set(&dsc, resource, &parsed_input, output_format.as_ref());
610607
},
611608
ResourceSubCommand::Test { resource, input, file: path, output_format } => {
612609
dsc.find_resources(&[resource.to_string()], progress_format);
613-
let parsed_input = get_input(input.as_ref(), path.as_ref());
610+
let parsed_input = get_input(input.as_ref(), path.as_ref(), false);
614611
resource_command::test(&dsc, resource, &parsed_input, output_format.as_ref());
615612
},
616613
ResourceSubCommand::Delete { resource, input, file: path } => {
617614
dsc.find_resources(&[resource.to_string()], progress_format);
618-
let parsed_input = get_input(input.as_ref(), path.as_ref());
615+
let parsed_input = get_input(input.as_ref(), path.as_ref(), false);
619616
resource_command::delete(&dsc, resource, &parsed_input);
620617
},
621618
}

dsc/src/util.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ pub fn validate_json(source: &str, schema: &Value, json: &Value) -> Result<(), D
426426
Ok(())
427427
}
428428

429-
pub fn get_input(input: Option<&String>, file: Option<&String>) -> String {
429+
pub fn get_input(input: Option<&String>, file: Option<&String>, parameters_from_stdin: bool) -> String {
430430
trace!("Input: {input:?}, File: {file:?}");
431431
let value = if let Some(input) = input {
432432
debug!("{}", t!("util.readingInput"));
@@ -442,6 +442,10 @@ pub fn get_input(input: Option<&String>, file: Option<&String>) -> String {
442442
// check if need to read from STDIN
443443
if path == "-" {
444444
info!("{}", t!("util.readingInputFromStdin"));
445+
if parameters_from_stdin {
446+
error!("{}", t!("util.stdinNotAllowedForBothParametersAndInput"));
447+
exit(EXIT_INVALID_INPUT);
448+
}
445449
let mut stdin = Vec::<u8>::new();
446450
match std::io::stdin().read_to_end(&mut stdin) {
447451
Ok(_) => {
@@ -535,13 +539,13 @@ pub fn set_dscconfigroot(config_path: &str) -> String
535539

536540

537541
/// Check if the test result is in the desired state.
538-
///
542+
///
539543
/// # Arguments
540-
///
544+
///
541545
/// * `test_result` - The test result to check
542-
///
546+
///
543547
/// # Returns
544-
///
548+
///
545549
/// * `bool` - True if the test result is in the desired state, false otherwise
546550
#[must_use]
547551
pub fn in_desired_state(test_result: &ResourceTestResult) -> bool {

0 commit comments

Comments
 (0)