Skip to content

Commit

Permalink
feat(*): add process label (resty-cli v0.30) (#12)
Browse files Browse the repository at this point in the history
  • Loading branch information
flrgh committed Oct 10, 2023
1 parent 3f20120 commit 39cbcd4
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 21 deletions.
12 changes: 12 additions & 0 deletions .github/workflows/test-compat.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,18 @@ jobs:
--with-stream_ssl_module
--with-stream_ssl_preread_module
- openresty: 1.21.4.2
resty-cli: v0.30
openssl: 1.1.1n
openresty-opts: >
--with-compat
--with-pcre-jit
--with-stream
--with-threads
--with-http_ssl_module
--with-stream_ssl_module
--with-stream_ssl_preread_module
steps:
- name: install gdb
run: |
Expand Down
33 changes: 30 additions & 3 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ pub struct NginxExec {
prefix: String,
runner: Runner,
bin: String,
label: Option<String>,
}

impl From<NginxExec> for Command {
Expand All @@ -180,6 +181,11 @@ impl From<NginxExec> for Command {
String::from("conf/nginx.conf"),
];

if let Some(label) = ngx.label {
nginx_args.insert(0, String::from("-g"));
nginx_args.insert(1, label);
}

let bin: String;
let mut args: Vec<String> = vec![];

Expand All @@ -202,9 +208,7 @@ impl From<NginxExec> for Command {
}
args.push("-c".to_owned());
nginx_args.insert(0, nginx);
args.push(join_shell_args(
nginx_args.iter_mut().map(|s| s.as_str()).collect(),
));
args.push(join_shell_args(&nginx_args));
}
Runner::Valgrind(opts) => {
bin = "valgrind".to_owned();
Expand Down Expand Up @@ -485,6 +489,28 @@ impl Action {
user.inline_lua.insert(0, jit.to_lua());
}

let mut label = None;
if get_resty_compat_version() >= 30 {
let mut s = String::from("# ");
if !user.inline_lua.is_empty() {
s.push_str("-e '");
s.push_str(user.inline_lua.join("; ").as_ref());
s.push('\'');

if user.lua_file.is_some() {
s.push(' ');
}
}

if let Some(fname) = &user.lua_file {
s.push_str(fname);
}

s = s.replace(['\r', '\n'], "");

label = Some(s);
}

let lua_loader = match generate_lua_loader(
&prefix,
&user.lua_file,
Expand Down Expand Up @@ -519,6 +545,7 @@ impl Action {
bin: find_nginx_bin(user.nginx_bin).to_str().unwrap().to_string(),
prefix: prefix.root.to_str().unwrap().to_string(),
runner: user.runner,
label,
};

run(Command::from(ngx))
Expand Down
4 changes: 2 additions & 2 deletions src/nginx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::env;
use std::path::PathBuf;

const RESTY_COMPAT_VAR: &str = "RESTY_CLI_COMPAT_VERSION";
const RESTY_COMPAT_LATEST: u64 = 28;
const RESTY_COMPAT_LATEST: u64 = 30;

const TEMPLATE: &str = include_str!("nginx.conf.tpl");
const TEMPLATE_NAME: &str = "nginx.conf";
Expand Down Expand Up @@ -69,7 +69,7 @@ pub fn find_nginx_bin(nginx: Option<String>) -> PathBuf {
PathBuf::from("nginx")
}

fn get_resty_compat_version() -> u64 {
pub fn get_resty_compat_version() -> u64 {
// TODO: maybe make this a build config item?
match env::var_os(RESTY_COMPAT_VAR) {
Some(value) => {
Expand Down
62 changes: 56 additions & 6 deletions src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,39 @@ pub(crate) fn try_parse_resolv_conf() -> Vec<IpAddr> {
nameservers
}

pub fn split_shell_args(s: &str) -> Vec<String> {
shlex::split(s).expect("Invalid runner options")
pub(crate) fn split_shell_args<T: AsRef<str> + ?Sized>(s: &T) -> Vec<String> {
shlex::split(s.as_ref()).expect("Invalid runner options")
}

pub fn join_shell_args(args: Vec<&str>) -> String {
shlex::join(args)
pub(crate) fn join_shell_args<T: AsRef<str>>(args: &Vec<T>) -> String {
let mut out = Vec::with_capacity(args.len());

// The shlex crate takes a slightly different approach of wrapping the
// entire string in double quotes and then only escaping a few chars
// within the string. It's a little bit cleaner, but in the interest of
// compatibility we'll duplicate the resty-cli algorithm exactly:
//
// s/([\\\s'"><`\[\]\&\$#*?!()|;])/\\$1/g;
//
for arg in args {
let mut new = Vec::new();

for c in arg.as_ref().bytes() {
match c as char {
'\\' | ' ' | '\t' | '\r' | '\n' | '\'' | '"' | '`' | '<' | '>' | '[' | ']'
| '(' | ')' | '|' | ';' | '&' | '$' | '#' | '*' | '?' | '!' => {
new.push(b'\\');
}
_ => {}
}

new.push(c);
}

out.push(String::from_utf8(new).unwrap());
}

out.join(" ")
}

#[cfg(test)]
Expand Down Expand Up @@ -94,8 +121,8 @@ mod tests {
#[test]
fn test_join_shell_args() {
assert_eq!(
"--nx -batch -ex \"b main\" -ex run -ex bt -ex \"b lj_cf_io_method_write\" -ex c -ex bt",
join_shell_args(vec![
"--nx -batch -ex b\\ main -ex run -ex bt -ex b\\ lj_cf_io_method_write -ex c -ex bt",
join_shell_args(&vec![
"--nx",
"-batch",
"-ex",
Expand All @@ -113,4 +140,27 @@ mod tests {
])
);
}

#[test]
fn test_args_round_trip() {
let args = vec![
"--nx",
"-batch",
"-ex",
"b main",
"--test",
"!",
"--test",
"($",
"'\\\\\\\"",
"`echo 123`",
];

let joined = join_shell_args(&args);
let split = split_shell_args(&joined);
let rejoined = join_shell_args(&split);
let resplit = split_shell_args(&rejoined);
assert_eq!(joined, rejoined);
assert_eq!(args, resplit);
}
}
5 changes: 4 additions & 1 deletion tests/lua-arg.sh
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,10 @@ run() {

cmd+=( "${ARGS[@]}" )

env - PATH="$RUNNER_PATH" "${cmd[@]}" \
env - \
PATH="$RUNNER_PATH" \
RESTY_CLI_COMPAT_VERSION="${RESTY_CLI_COMPAT_VERSION:-0.28}" \
"${cmd[@]}" \
> "$TMP/$name.stdout" \
2> "$TMP/$name.stderr"

Expand Down
57 changes: 50 additions & 7 deletions tests/lua/print-argv.lua
Original file line number Diff line number Diff line change
@@ -1,18 +1,61 @@
local fname = os.getenv("RUSTY_CLI_TEST_OUTPUT") or "/dev/stdout"
local fh = assert(io.open(fname, "w+"))

local keys = {}
local PROC_SELF = "/proc/" .. ngx.worker.pid()

for k in pairs(arg) do
table.insert(keys, k)
local function exec(cmd)
local proc = io.popen(cmd, "r")
local out = proc:read("*a")
proc:close()

out = out:gsub("\n$", "")
return out
end

table.sort(keys)
local function get_cmd()
local proc = io.open(PROC_SELF .. "/cmdline", "r")
local data = proc:read("*a")
proc:close()

local items = {}

data:gsub("[^%z]+", function(item)
table.insert(items, item)
end)

return items
end

local function printf(...)
return fh:write(string.format(...))
end


printf("CWD = %q\n", exec("readlink " .. PROC_SELF .. "/cwd"))
printf("EXE = %q\n", exec("readlink " .. PROC_SELF .. "/exe"))

do
printf("CMD = {\n")
for i, elem in ipairs(get_cmd()) do
printf(" [%s] = %q\n", i, elem)
end
printf("}\n")
end

do
local keys = {}

for k in pairs(arg) do
table.insert(keys, k)
end

for _, k in ipairs(keys) do
local key = ("arg[%s]"):format(k)
table.sort(keys)

fh:write(("%-10s = %q\n"):format(key, arg[k]))
printf("ARG = {\n")
for _, k in ipairs(keys) do
printf(" [%s] = %q\n", k, arg[k])
end
printf("}\n")
end

fh:close()
5 changes: 4 additions & 1 deletion tests/runners.sh
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,10 @@ run() {

cmd+=( "${ARGS[@]}" )

env - PATH="$RUNNER_PATH" "${cmd[@]}" \
env - \
PATH="$RUNNER_PATH" \
RESTY_CLI_COMPAT_VERSION="${RESTY_CLI_COMPAT_VERSION:-0.28}" \
"${cmd[@]}" \
> "$TMP/$name.stdout" \
2> "$TMP/$name.stderr"

Expand Down
2 changes: 1 addition & 1 deletion tests/runners/bin/debug-argv
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ printf 'ARGC = %d\n' "$#"
printf 'ARGV[0] = %q\n' "$0"

for ((i = 1; i <= $#; i++)); do
printf 'ARGV[%d] = %q\n' "$i" "${!i}"
printf 'ARGV[%d] = %s\n' "$i" "${!i}"
done

0 comments on commit 39cbcd4

Please sign in to comment.