-
Notifications
You must be signed in to change notification settings - Fork 185
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
jq integration #2319
jq integration #2319
Conversation
@jimis I'm not sure how to proceed, can you take a look? |
Can one of the admins verify this patch? |
Argh, linking statically is not an easy job. Both CFEngine and jq are using yacc and lex it seems:
In this case I don't think it's worth making them cooperate. If I abandon this path, the only other way is to link dynamically to |
@tzz you think you can try patching CFEngine in order to change the lexer/parser keywords, for example In addition, can you see if there is a way to pass down options to the Dynamic linking seems to work for me, and "make install" installs both libpromises and libjq. But I'm skeptical of conflicts with systems that already have libjq installed. |
I think static linking is better for CFEngine specifically. We don't want to lose core functionality by surprise. |
41a3255
to
b5e1f07
Compare
I imported the actual Git contents of jq 1.5 and get the
I had to run I was then able to immediately build |
The example at the beginning was updated to show a successful invocation. This is very exciting! The current data passing mechanism is inefficient, dumping the data to JSON back and forth. I'd love for someone else to hack on that. The function always returns an array. I think that's OK. The real Still missing: acceptance tests and docs. If the current state of the code is acceptable I can write those next. |
As I commented in the ticket, I'm not so sure we want such a huge library imported in our source tree. It is a big bunch of code to import unreviewed, and it's not really used everywhere to just trust it. |
@jimis I need your approval of the pipe approach here or in the ticket; then I will resubmit this PR and we can proceed. |
@@ -2775,6 +2847,22 @@ static FnCallResult FnCallMapData(EvalContext *ctx, ARG_UNUSED const Policy *pol | |||
return FnFailure(); | |||
} | |||
|
|||
if (mapdatamode && jqmode) | |||
{ | |||
// TODO: make this customizable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need advice on how to make this customizable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe the jq
options should also be customizable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another proposal I made in the ticket https://dev.cfengine.com/issues/7435 was to support the syntax mapdata("|/usr/bin/jq", ...)
which would make this moot. The user decides what to pipe.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what kind of customizations you would like to have in the jq
command line. For start, this looks OK. The pipe thing you brought up on the ticket is obviously the most extensible, but also the ugliest, it's up to policy writers to decide ... ;-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, some people may not have it in /usr/bin
:)
Maybe it can be in def.jq
so you can override it from def.json
, if the general pipe proposal doesn't fly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm you are right. Actually it would be preferable if we were only executing "jq" and having the system look it up in PATH
. Unfortunately cf_popen_full_duplex()
uses execv()
, what I think would make sense would be to use execvp()
instead. Quoting the man page:
The execlp(), execvp(), and execvpe() functions duplicate the actions of the shell in searching for an executable file if the specified filename does not contain a slash (/) character.
Maybe change cf_popen_full_duplex()
or duplicate it in an alternative? Do you think this would cover most customization issues?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it should be enough for now. I just changed cf_popen_full_duplex()
in a backwards-compatible way.
@jimis @kacf @estenberg I didn't hear back for months, so I've rewritten this using pipes anyway. The change is to:
I can split the pipe code move from the rest of the commit if you want. Note that this is now a very small change as far as |
I have asked @jimis to look at this again. |
*response = res; | ||
return 0; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kacf you might want to review these package module changes since it is your domain. The functionality was moved to generic functions in pipes_unix.c
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can break that into a separate commit if it helps.
I fixed those two minor issues (unused context and too-verbose log mesage). |
41a9fae
to
e637e88
Compare
Changed to just run |
@@ -267,11 +269,16 @@ IOData cf_popen_full_duplex(const char *command, bool capture_stderr) | |||
CloseChildrenFD(); | |||
|
|||
char **argv = ArgSplitCommand(command); | |||
if (execv(argv[0], argv) == -1) | |||
if (require_full_path && execv(argv[0], argv) == -1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please keep the logic clear, something like the following or similar:
if (require_full_path)
res=execv();
else
res=execvp();
if (res == -1)
Log("err (exec: %s)");
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK; done.
trigger build |
I assume this is because In addition, |
I fixed up the last commit to include the I don't know why this is failing on exotics, sorry. If you can't replicate it, I'll try to spin up one of those and test there, but it will take me a while. |
I'll see if I can find anything on the problem. |
This is getting stranger by the minute: It only fails if run in parallel with other tests, not on its own. It's quite consistently failing though. |
At least I'm getting some output now:
Any idea is welcome here.... |
It's clear that cf-promises is crashing somehow, but the core file is corrupted, so I'm not able to a backtrace. |
I see the |
The acceptance test doesn't use |
It certainly can be stdin/stdout related, but it's more likely it happens in CFEngine's own handling of those descriptors, since this test in particular makes use of them (by calling |
Nice, thank you for working on this and finding the issue. I really appreciate it. |
Otherwise we may get an error because the cat tool closed its stdin before CFEngine could write everything it needs to it.
Superseded by #2572. |
see https://dev.cfengine.com/issues/7435
Here's a minimal example to test things:
output: