-
Notifications
You must be signed in to change notification settings - Fork 52
Add run command resource #321
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
Merged
Merged
Changes from 25 commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
b3b298e
start RunCommandOnSet resource
tgauth 026bc72
implement get and set
tgauth 7006d64
add resource manifest
tgauth c6ad454
add tests and update return format for get and set
tgauth 4d4a340
add tests and add proj to build list
tgauth 04d6893
add tests for missing required input
tgauth b0967b6
Merge branch 'main' into add-run-command-resource
tgauth fd9611b
fix clippy
tgauth a86655b
Merge branch 'add-run-command-resource' of https://github.com/tgauth/…
tgauth 0d43c39
fix tests on linux/macos
tgauth 25b6e1b
fix spacing
tgauth b417409
fix tests on linux/macos part 2
tgauth 5d62a3b
Merge branch 'main' into add-run-command-resource
tgauth 849b1d0
rename resource and remove yaml processing from utils
tgauth de6f29d
Merge branch 'main' into add-run-command-resource
tgauth 3f9ccc8
address review feedback
tgauth ce48d66
fix test
tgauth 2449eef
Merge branch 'main' into add-run-command-resource
tgauth 046001b
print debug message from other os
tgauth f5c9d39
Merge branch 'add-run-command-resource' of https://github.com/tgauth/…
tgauth 7ac34ca
fix test
tgauth 6d5c64b
remove debug from tests
tgauth aef1b19
fix merge conflict
tgauth 8401c66
add return type as state for set
tgauth 97a58f6
check changed properties for exit code in tests
tgauth 62284cf
Merge branch 'main' into add-run-command-resource
tgauth 32effa7
update exit_code to exitCode for serialization
tgauth File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| [package] | ||
| name = "runcommandonset" | ||
| version = "0.1.0" | ||
| edition = "2021" | ||
|
|
||
| # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
|
||
| [dependencies] | ||
| atty = { version = "0.2" } | ||
| clap = { version = "4.4", features = ["derive"] } | ||
| serde = { version = "1.0", features = ["derive"] } | ||
| serde_json = { version = "1.0", features = ["preserve_order"] } | ||
| tracing = { version = "0.1.37" } | ||
| tracing-subscriber = { version = "0.3.17", features = ["ansi", "env-filter", "json"] } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| { | ||
| "$schema": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/bundled/resource/manifest.json", | ||
| "description": "Takes a single-command line to execute on DSC set operation", | ||
| "type": "Microsoft.DSC.Transitional/RunCommandOnSet", | ||
| "version": "0.1.0", | ||
| "get": { | ||
| "executable": "runcommandonset", | ||
| "args": [ | ||
| "get" | ||
| ], | ||
| "input": "stdin" | ||
| }, | ||
| "set": { | ||
| "executable": "runcommandonset", | ||
| "args": [ | ||
| "set" | ||
| ], | ||
| "input": "stdin", | ||
| "return": "state" | ||
| }, | ||
| "schema": { | ||
| "embedded": { | ||
| "$schema": "http://json-schema.org/draft-07/schema#", | ||
| "title": "RunCommandOnSet", | ||
| "type": "object", | ||
| "required": [ | ||
| "executable" | ||
| ], | ||
| "properties": { | ||
| "arguments": { | ||
| "title": "The argument(s), if any, to pass to the executable that runs on set", | ||
| "type": "array" | ||
| }, | ||
| "executable": { | ||
| "title": "The executable to run on set", | ||
| "type": "string" | ||
| }, | ||
| "exit_code": { | ||
| "title": "The expected exit code to indicate success, if non-zero. Default is zero for success.", | ||
| "type": "integer" | ||
| } | ||
| }, | ||
| "additionalProperties": false | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT License. | ||
|
|
||
| use clap::{Parser, Subcommand, ValueEnum}; | ||
|
|
||
| #[derive(Debug, Clone, PartialEq, Eq, ValueEnum)] | ||
| pub enum TraceFormat { | ||
| Default, | ||
| Plaintext, | ||
| Json, | ||
| } | ||
|
|
||
| #[derive(Debug, Clone, PartialEq, Eq, ValueEnum)] | ||
| pub enum TraceLevel { | ||
| Error, | ||
| Warning, | ||
| Info, | ||
| Debug, | ||
| Trace | ||
| } | ||
|
|
||
| #[derive(Parser)] | ||
| #[clap(name = "runcommandonset", version = "0.0.1", about = "Run a command on set", long_about = None)] | ||
| pub struct Arguments { | ||
|
|
||
| #[clap(subcommand)] | ||
| pub subcommand: SubCommand, | ||
| #[clap(short = 'l', long, help = "Trace level to use", value_enum, default_value = "info")] | ||
| pub trace_level: TraceLevel, | ||
| #[clap(short = 'f', long, help = "Trace format to use", value_enum, default_value = "json")] | ||
| pub trace_format: TraceFormat, | ||
| } | ||
|
|
||
| #[derive(Debug, PartialEq, Eq, Subcommand)] | ||
| pub enum SubCommand { | ||
| #[clap(name = "get", about = "Get formatted command to run on set.")] | ||
| Get { | ||
| #[clap(short = 'a', long, help = "The arguments to pass to the executable.")] | ||
| arguments: Option<Vec<String>>, | ||
| #[clap(short = 'e', long, help = "The executable to run.")] | ||
| executable: Option<String>, | ||
| #[clap(short = 'c', long, help = "The expected exit code to indicate success, if non-zero.", default_value = "0")] | ||
| exit_code: i32, | ||
| }, | ||
| #[clap(name = "set", about = "Run formatted command.")] | ||
| Set { | ||
| #[clap(short = 'a', long, help = "The arguments to pass to the executable.")] | ||
| arguments: Option<Vec<String>>, | ||
| #[clap(short = 'e', long, help = "The executable to run.")] | ||
| executable: Option<String>, | ||
| #[clap(short = 'c', long, help = "The expected exit code to indicate success, if non-zero.", default_value = "0")] | ||
| exit_code: i32, | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT License. | ||
|
|
||
| use atty::Stream; | ||
| use clap::{Parser}; | ||
| use std::{io::{self, Read}, process::exit}; | ||
| use tracing::{error, warn, debug}; | ||
|
|
||
| use args::{Arguments, SubCommand}; | ||
| use runcommand::{RunCommand}; | ||
| use utils::{enable_tracing, invoke_command, parse_input, EXIT_INVALID_ARGS}; | ||
|
|
||
| pub mod args; | ||
| pub mod runcommand; | ||
| pub mod utils; | ||
|
|
||
| fn main() { | ||
| let args = Arguments::parse(); | ||
| enable_tracing(&args.trace_level, &args.trace_format); | ||
| warn!("This resource is not idempotent"); | ||
|
|
||
| let stdin = if atty::is(Stream::Stdin) { | ||
| None | ||
| } else { | ||
| debug!("Reading input from STDIN"); | ||
| let mut buffer: Vec<u8> = Vec::new(); | ||
| io::stdin().read_to_end(&mut buffer).unwrap(); | ||
| let stdin = match String::from_utf8(buffer) { | ||
| Ok(stdin) => stdin, | ||
| Err(e) => { | ||
| error!("Invalid UTF-8 sequence: {e}"); | ||
| exit(EXIT_INVALID_ARGS); | ||
| }, | ||
| }; | ||
| // parse_input expects at most 1 input, so wrapping Some(empty input) would throw it off | ||
| if stdin.is_empty() { | ||
| debug!("Input from STDIN is empty"); | ||
| None | ||
| } | ||
| else { | ||
| Some(stdin) | ||
| } | ||
| }; | ||
|
|
||
| let mut command: RunCommand; | ||
|
|
||
| match args.subcommand { | ||
| SubCommand::Get { arguments, executable, exit_code } => { | ||
| command = parse_input(arguments, executable, exit_code, stdin); | ||
| } | ||
| SubCommand::Set { arguments, executable, exit_code } => { | ||
| command = parse_input(arguments, executable, exit_code, stdin); | ||
| let (exit_code, stdout, stderr) = invoke_command(command.executable.as_ref(), command.arguments.clone()); | ||
| // TODO: convert this to tracing json once other PR is merged to handle tracing from resources | ||
| eprintln!("Stdout: {stdout}"); | ||
| eprintln!("Stderr: {stderr}"); | ||
| command.exit_code = exit_code; | ||
| } | ||
| } | ||
|
|
||
| println!("{}", command.to_json()); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT License. | ||
|
|
||
| use serde::{Deserialize, Serialize}; | ||
|
|
||
| #[derive(Debug, Deserialize, Clone, PartialEq, Serialize)] | ||
| pub struct RunCommand { | ||
| pub executable: String, | ||
| #[serde(skip_serializing_if = "Option::is_none")] | ||
| pub arguments: Option<Vec<String>>, | ||
| // default value for exit code is 0 | ||
| #[serde(default, skip_serializing_if = "is_default")] | ||
| pub exit_code: i32, | ||
| } | ||
|
|
||
| impl RunCommand { | ||
| #[must_use] | ||
| pub fn to_json(&self) -> String { | ||
| match serde_json::to_string(self) { | ||
| Ok(json) => json, | ||
| Err(e) => { | ||
| eprintln!("Failed to serialize to JSON: {e}"); | ||
| String::new() | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| fn is_default<T: Default + PartialEq>(t: &T) -> bool { | ||
| t == &T::default() | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.