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

Fixes #17724: error about rudder lang in logs #3075

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
42 changes: 21 additions & 21 deletions rudder-lang/docs/usage.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ Optionally add rudderc to your path `export PATH=$PATH:/opt/rudder/bin/rudderc`

=== Usage

`rudderc` has 2 features:
`rudderc` has 2 features:

* Compile which is the default behavior: takes a _RL_ technique as an input and generates the desired
* Translate which is the alternative mode: takes a _JSON_ technique as an input and generates a _rudder-lang_ technique (_.rl_)

Expand All @@ -40,10 +41,6 @@ OPTIONS:
A configuration file is required (containing at least stdlib and generic_method paths)
[default: /opt/rudder/etc/rudderc.conf]

-d, --dest <dest>
Output file path, overrides config and technique-name.
If neither an output nor a configuration file output path is set, source path is used

-f, --format <format>
Enforce a compiler output format (overrides configuration format and manual technique extension)
[possible values: cf, dsc, json]
Expand All @@ -53,25 +50,28 @@ OPTIONS:
[default: warn]
[possible values: off, trace, debug, info, warn, error]

-o, --output-technique-name <output-technique-name>
Technique name to use for output (if no output provided), based on configuration file path

-s, --source <source>
Input file path. Overwrites base input

-n, --technique-name <technique-name>
Technique name to use for both input (if no input provided) and output (if no output or provided), based on configuration file paths

-d, --dest <dest>
Output file path, overrides config and technique-name.
If neither an output nor a configuration file output path is set, source path is used

-o, --output-technique-name <output-technique-name>
Technique name to use for output (if no output provided), based on configuration file path
----

Most options are pretty straightforward but some explanations might help:

* Flags and options must be written in `kebab-case`
*
* A configuration file is required because _rudderc_ needs its own libraries to work (default path should point to an already working _Rudder_ configuration if _rudder agent_ was installed like previously suggested)
* Unlike the prevailing `--source` and `--dest` options, the `--technique-name <technique joined>` option makes use of the configuration file input and output paths and concatenates the `technique joined>` to these
* Unlike the prevailing `--source` (`-s`) and `--dest` (`-d`) options, the `--technique-name <technique joined>` (`-n`) and `--technique-output-name <technique joined>` (`-o`) options makes use of the configuration file input and output paths and concatenates the `<technique joined>` to these
* `--source` > configuration source + `--technique-name` > configuration source if it is a file
* `--dest` > configuration dest + `--technique-name` > configuration dest if it is a file > `--source` as destination with updated format
* `--format` > configuration format > `--dest` technique extension
* `--dest` > configuration dest + `--technique-name` (`-n`) > configuration dest if it is a file > `--source` as destination with updated format
* `--format` (`-f`) > configuration format > `--dest` technique extension
* Log levels are ordered (trace > debug > info > warn > error)

==== Configuration file
Expand All @@ -96,6 +96,7 @@ Entire _rudder-lang_ environment is already set up alongside the agent: this inc
[translate]
source="tests/test_files/tester/"
dest="tests/test_files/tester/"
# format="dsc" # format here will just be ignored as translate can only generate rudder-lang

[testing_loop]
cfengine="/opt/rudder/bin/cf-promises"
Expand All @@ -117,13 +118,13 @@ The `source` and `dest` fields from both `[translate]` and `[compile]` can eithe
dest="cf/"
----

Paths will respectively be prepended to _rudderc_ `-i` and `-o` options
Paths will respectively be prepended to _rudderc_ `-n` and `-o` options

===== Configuration file set with files

Paths will be used as they are, since they already define a single technique.

Note that `-i` and `-o` _rudderc_ options will use the config specified directories and only override technique name
Note that `-n` and `-o` _rudderc_ options will use the config specified directories and only override technique name

==== Compilation example

Expand Down Expand Up @@ -179,7 +180,7 @@ rudderc -j -l debug -c tools/myconf

Or using `rl` and `dsc` directories with other techniques:
----
rudderc -j -l debug -c tools/myconf -i another.rl -o another_from_rl.rl.dsc
rudderc -j -l debug -c tools/myconf -n another.rl -o another_from_rl.rl.dsc
----

==== Translation example
Expand All @@ -204,11 +205,10 @@ rudderc -tj -l debug -c tools/myconf -s technique.json -d rl/from_json.rl
----

What it means:

* Translate (`-t`) `./json/technique.json` (`-s`) into `./rl/from_json.rl` (`-d`),
* Use the configuration file located at `./tools/myconf` (`-c`),
* Output log format is JSON (`-j`),
* The following log levels: error, warn will be printed to the terminal
- Translate (`-t`) `./json/technique.json` (`-s`) into `./rl/from_json.rl` (`-d`),
- Use the configuration file located at `./tools/myconf` (`-c`),
- Output log format is JSON (`-j`),
- The following log levels: error, warn will be printed to the terminal

4. CLI + config lightened version

Expand All @@ -233,7 +233,7 @@ rudderc -tj -l warn -c tools/myconf

Or using `json` and `rl` directories with other techniques:
----
rudderc -tj -l warn -c tools/myconf -i another.json -o another_from_json.rl
rudderc -tj -l warn -c tools/myconf -n another.json -o another_from_json.rl
----

== Using the Technique Editor
Expand Down
7 changes: 4 additions & 3 deletions rudder-lang/src/generators.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ pub enum Format {
RudderLang,
CFEngine,
DSC,
// JSON
JSON
}
impl fmt::Display for Format {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Expand All @@ -52,7 +52,7 @@ impl fmt::Display for Format {
Format::CFEngine => "cf",
Format::DSC => "dsc",
Format::RudderLang => "rl",
// Format::JSON => "json",
Format::JSON => "json",
}
)
}
Expand All @@ -65,7 +65,8 @@ impl FromStr for Format {
match format {
"cf" | "cfengine" => Ok(Format::CFEngine),
"dsc" => Ok(Format::DSC),
// "json" => Ok(Format::json),
"json" => Ok(Format::JSON),
"rl" => Ok(Format::RudderLang),
// RudderLang is an error, not a compilation format
_ => Err(Error::User(format!("Could not parse format {}", format))),
}
Expand Down
19 changes: 10 additions & 9 deletions rudder-lang/src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,15 +134,15 @@ fn get_dest(
};

// format is part of dest file so it makes sense to return it from this function plus it needs to be defined here to update dest if needed
let (format, format_as_str) = get_format(config, opt, &technique)?;
let (format, format_as_str) = get_dest_format(config, opt, &technique)?;
if technique.ends_with(&format_as_str) {

}
Ok((technique.with_extension(&format_as_str), format))
}

/// get explicit dest. If no explicit dest get default path + filename. I none, use source path (and update format). If none worked, error
fn get_format(config: &ActionConfig, opt: &IOOpt, dest: &PathBuf) -> Result<(Format, String)> {
fn get_dest_format(config: &ActionConfig, opt: &IOOpt, dest: &PathBuf) -> Result<(Format, String)> {
if opt.format.is_some() {
info!("Command line format used");
} else if config.format.is_some() {
Expand Down Expand Up @@ -170,9 +170,9 @@ fn get_format(config: &ActionConfig, opt: &IOOpt, dest: &PathBuf) -> Result<(For
if config.action == Some(Action::Compile) && fmt != Format::RudderLang {
Ok((fmt.clone(), format!("{}.{}", "rl", fmt))) // TODO discuss about file extension handling
// Ok((fmt.clone(), fmt.to_string()))
} else if config.action == Some(Action::Translate) && fmt == Format::RudderLang {
} else if config.action == Some(Action::Translate) {
// translate can only have RL as output format
Ok((fmt, "rl".to_owned()))
Ok((Format::RudderLang, "rl".to_owned()))
} else {
Err(Error::User(
format!("Could not determine format: {} is not a valid format for {}", fmt, config.action.unwrap()),
Expand Down Expand Up @@ -201,14 +201,15 @@ pub fn get(
action: Action,
opt: &IOOpt
) -> Result<IOContext> {
// Ease of read closure
let err_gen = |e: &str| Err(Error::User(e.to_string()));

let config: Config = match std::fs::read_to_string(&opt.config_file) {
Err(e) => return err_gen(&format!("Could not read toml config file: {}", e)),
Err(e) => return Err(Error::User(
format!("Could not read toml config file: {}", e)
)),
Ok(config_data) => match toml::from_str(&config_data) {
Ok(config) => config,
Err(e) => return err_gen(&format!("Could not parse (probably faulty) toml config file: {}", e)),
Err(e) => return Err(Error::User(
format!("Could not parse (probably faulty) toml config file: {}", e)
)),
},
};

Expand Down
3 changes: 3 additions & 0 deletions rudder-lang/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
#[macro_use]
extern crate log;

#[macro_use]
extern crate serde_json;

#[macro_use]
pub mod error;
pub mod opt;
Expand Down
30 changes: 18 additions & 12 deletions rudder-lang/src/translate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,11 @@ use typed_arena::Arena;

#[derive(Serialize, Deserialize)]
struct Technique {
name: String,
bundle_name: String,
description: String,
name: String,
version: String,
bundle_name: String,
parameter: Vec<Value>,
bundle_args: Vec<String>,
method_calls: Vec<MethodCall>,
}

Expand Down Expand Up @@ -104,8 +103,9 @@ struct Translator<'src> {

impl<'src> Translator<'src> {
fn translate(&self) -> Result<String> {
let parameters_meta = self.translate_meta_parameters(&self.technique.parameter).unwrap();
let parameters = self.technique.bundle_args.join(",");
let (parameters_meta, parameter_list) = self.translate_meta_parameters(&self.technique.parameter).unwrap();
// let parameter_list = self.technique.bundle_args.join(","); // bundle_args not used anynmore
// sounds like parameters are taken from technique parameter field TODO : monitor resource parameters behavior
let calls = map_strings_results(
self.technique.method_calls.iter(),
|c| self.translate_call(c),
Expand All @@ -119,7 +119,7 @@ impl<'src> Translator<'src> {
@version="{version}"
@parameters= [{newline}{parameters_meta}]

resource {bundle_name}({parameters})
resource {bundle_name}({parameter_list})
{bundle_name} state technique() {{
{calls}
}}
Expand All @@ -130,7 +130,7 @@ resource {bundle_name}({parameters})
bundle_name = self.technique.bundle_name,
newline = "\n",
parameters_meta = parameters_meta,
parameters = parameters,
parameter_list = parameter_list.join(","),
calls = calls
);
Ok(out)
Expand Down Expand Up @@ -241,8 +241,9 @@ resource {bundle_name}({parameters})
))
}

fn translate_meta_parameters(&self, parameters: &[Value]) -> Result<String> {
fn translate_meta_parameters(&self, parameters: &[Value]) -> Result<(String, Vec<String>)> {
let mut parameters_meta = String::new();
let mut parameter_list = Vec::new();
for param in parameters {
match param.as_object() {
Some(map) => {
Expand All @@ -254,14 +255,19 @@ resource {bundle_name}({parameters})
.get("id")
.expect("Unable to parse id parameter")
.to_string();
let description = &map
.get("description")
.unwrap_or(&json!(""))
.to_string();
let constraints = &map
.get("constraints")
.expect("Unable to parse constraints parameter")
.unwrap_or(&json!(""))
.to_string();
parameters_meta.push_str(&format!(
r#" {{ "name": {}, "id": {}, "constraints": {} }}{}"#,
name, id, constraints, ",\n"
r#" {{ "name": {}, "id": {}, "description": {}, "constraints": {} }}{}"#,
name, id, description, constraints, ",\n"
));
parameter_list.push(name.replace("\"", "").replace(" ", "_").to_owned());
}
None => return Err(Error::User(String::from("Unable to parse meta parameters"))),
}
Expand All @@ -270,7 +276,7 @@ resource {bundle_name}({parameters})
// if parameters_meta.is_err() {
// return Err(Error::User("Unable to parse technique file".to_string()));
// }
Ok(parameters_meta)
Ok((parameters_meta, parameter_list))
}

fn translate_arg(&self, arg: &str) -> Result<String> {
Expand Down
34 changes: 34 additions & 0 deletions rudder-lang/tests/test_files/tester/6.1.rc5/technique.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"bundle_name": "normal",
"description": "ewf",
"name": "normal",
"version": "1.0",
"parameter": [
{
"id": "c6e6cc3a-9ce8-4889-bccc-6bfc1b091d0d",
"name": "parameter wdd",
"description": ""
},
{
"name": "paramtest",
"id": "d74a03dd-5b0b-4b06-8dcf-b4e0cb387c60",
"constraints": {
"allow_whitespace_string": false,
"allow_empty_string": false,
"max_length": 16384
},
"type": "string"
}
],
"category": "systemSettings/misc",
"method_calls": [
{
"args": [
"mycond"
],
"class_context": "any",
"method_name": "condition_once",
"component": "Condition once"
}
]
}
15 changes: 15 additions & 0 deletions rudder-lang/tests/test_files/tester/6.1.rc5/technique.rl
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# This file has been generated with rltranslate
@format=0
@name="normal"
@description="ewf"
@version="1.0"
@parameters= [
{ "name": "parameter wdd", "id": "c6e6cc3a-9ce8-4889-bccc-6bfc1b091d0d", "description": "", "constraints": "" },
{ "name": "paramtest", "id": "d74a03dd-5b0b-4b06-8dcf-b4e0cb387c60", "description": "", "constraints": {"allow_empty_string":false,"allow_whitespace_string":false,"max_length":16384} },
]

resource normal(parameter_wdd,paramtest)
normal state technique() {
@component = "Condition once"
condition("mycond").once() as condition_once_mycond
}
15 changes: 15 additions & 0 deletions rudder-lang/tests/test_files/tester/6.1.rc5/technique.rl.cf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# generated by rudder-lang
# @name normal
# @description ewf
# @version 1.0
# @parameter { "name": "parameter wdd", "id": "c6e6cc3a-9ce8-4889-bccc-6bfc1b091d0d", "constraints": "" }
# @parameter { "name": "paramtest", "id": "d74a03dd-5b0b-4b06-8dcf-b4e0cb387c60", "constraints": { "allow_whitespace_string":1,"allow_empty_string":1,"max_length":16384 } }

bundle agent normal_technique(parameter_wdd,paramtest)
{
vars:
"resources_dir" string => "${this.promise_dirname}/resources";
methods:
"Condition once_${report_data.directive_id}_0" usebundle => _method_reporting_context("Condition once", "mycond");
"Condition once_${report_data.directive_id}_0" usebundle => condition_once("mycond");
}
18 changes: 18 additions & 0 deletions rudder-lang/tests/test_files/tester/simplest/technique.cf.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "simplest",
"description": "rudderlang simplest for a complete loop",
"version": "1.0",
"bundle_name": "simplest",
"bundle_args": [],
"parameter": [],
"method_calls": [
{
"class_context": "debian",
"component": "File absent",
"method_name": "file_absent",
"args": [
"tmp"
]
}
]
}
13 changes: 13 additions & 0 deletions rudder-lang/tests/test_files/tester/simplest/technique.cf.rl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# This file has been generated with rltranslate
@format=0
@name="simplest"
@description="rudderlang simplest for a complete loop"
@version="1.0"
@parameters= [
]

resource simplest()
simplest state technique() {
@component = "File absent"
if debian_family => file("tmp").absent() as file_absent_tmp
}
Loading