cf-agent -Kf ./example.cf error: readjson: data error parsing JSON file '/tmp/mydata.json': No data error: readjson: data error parsing JSON file '/tmp/mydata.json': No data error: readjson: data error parsing JSON file '/tmp/mydata.json': No data error: readjson: data error parsing JSON file '/tmp/mydata.json': No data error: readjson: data error parsing JSON file '/tmp/mydata.json': No data error: readjson: data error parsing JSON file '/tmp/mydata.json': No data error: readjson: data error parsing JSON file '/tmp/mydata.json': No data error: readjson: data error parsing JSON file '/tmp/mydata.json': No data error: readjson: data error parsing JSON file '/tmp/mydata.json': No data error: readjson: data error parsing JSON file '/tmp/mydata.json': No data error: readjson: data error parsing JSON file '/tmp/mydata.json': No data error: readjson: data error parsing JSON file '/tmp/mydata.json': No data error: readjson: data error parsing JSON file '/tmp/mydata.json': No data
I have policy that puts a data file into place and reads data from it. Why do I
get so many readjson()
errors and how can I suppress them?
The minimum required to reproduce the error from readjson is:
|
|
Now, what happens if we add a promise that manages the file?
|
|
We can run with verbose logging to see more details.
Snips for brevity …
cf-agent -Kvf /tmp/example.cf verbose: CFEngine Core 3.11.0 ... verbose: ---------------------------------------------------------------- verbose: Initialization preamble verbose: ---------------------------------------------------------------- ... verbose: ---------------------------------------------------------------- verbose: Environment discovery verbose: ---------------------------------------------------------------- ... verbose: Verifying the syntax of the inputs... verbose: Checking policy with command '"/home/nickanderson/.cfagent/bin/cf-promises" -c "./example.cf"' error: readjson: data error parsing JSON file '/tmp/mydata.json': No data error: readjson: data error parsing JSON file '/tmp/mydata.json': No data error: readjson: data error parsing JSON file '/tmp/mydata.json': No data error: readjson: data error parsing JSON file '/tmp/mydata.json': No data verbose: Saved policy validated marker file '/home/nickanderson/.cfagent/state/cf_promises_validated'
The four above errors are emitted during syntax validation.
verbose: ---------------------------------------------------------------- verbose: Loading policy verbose: ---------------------------------------------------------------- verbose: BEGIN parsing file: ./example.cf verbose: END parsing file: ./example.cf error: readjson: data error parsing JSON file '/tmp/mydata.json': No data error: readjson: data error parsing JSON file '/tmp/mydata.json': No data verbose: BEGIN parsing file: /home/nickanderson/.cfagent/inputs/lib/files.cf verbose: END parsing file: /home/nickanderson/.cfagent/inputs/lib/files.cf verbose: BEGIN parsing file: /home/nickanderson/.cfagent/inputs/lib/common.cf verbose: END parsing file: /home/nickanderson/.cfagent/inputs/lib/common.cf verbose: Running full policy integrity checks
The above errors are emitted during the resolution that occurs during parsing inputs.
verbose: ---------------------------------------------------------------- verbose: Preliminary variable/class-context convergence verbose: ---------------------------------------------------------------- error: readjson: data error parsing JSON file '/tmp/mydata.json': No data error: readjson: data error parsing JSON file '/tmp/mydata.json': No data verbose: string_mustache: argument 'default:main.myvar' does not resolve to a container or a list or a CFEngine array ... verbose: Skipping promise 'DEBUG $(this.bundle): $(link) will be a symlink to $(target)' because 'if'/'ifvarclass' is not defined error: readjson: data error parsing JSON file '/tmp/mydata.json': No data error: readjson: data error parsing JSON file '/tmp/mydata.json': No data
The above errors are emitted during pre-evaluation.
verbose: Setting minimum acceptable TLS version: 1.0 verbose: ---------------------------------------------------------------- verbose: Begin policy/promise evaluation verbose: ---------------------------------------------------------------- verbose: Using bundlesequence => {"main"} verbose: B: ***************************************************************** verbose: B: BEGIN bundle main verbose: B: ***************************************************************** verbose: V: ......................................................... verbose: V: BEGIN variables (pass 1) error: readjson: data error parsing JSON file '/tmp/mydata.json': No data verbose: V: Computing value of 'myvar' error: readjson: data error parsing JSON file '/tmp/mydata.json': No data error: readjson: data error parsing JSON file '/tmp/mydata.json': No data
The above errors are emitted during the first pass of variables during normal order (main evaluation).
After that the json data file is created.
verbose: P: ......................................................... verbose: P: BEGIN promise 'promise_example_cf_8' of type "files" (pass 1) verbose: P: Promiser/affected object: '/tmp/mydata.json' verbose: P: Part of bundle: main verbose: P: Base context class: any verbose: P: Stack path: /default/main/files/'/tmp/mydata.json'[1] verbose: Using literal pathtype for '/tmp/mydata.json' verbose: No mode was set, choose plain file default 0600 info: Created file '/tmp/mydata.json', mode 0600
No further errors happen because now that the file exists it can be successfully parsed.
How can we suppress the errors?
You can guard the vars promise based on when there is a json file present, or
based on the json_copy
promise itself. But there are several things to
consider. What is right depends on the specifics of the behavior you are looking
for.
Considerations:
- Basing data load on file presence does not ensure the data will be fresh when the data is loaded.
- Basing data load on a copy promise being kept or repaired is a transient condition and a brittle state.
- A copy promise being kept or repaired nor the presence of a file on disk will tell you if the data is valid.
- It's not always worth checking all of the things. If the policy runs periodically convergence can help us avoid perseverating. Be careful of building in too much protective logic.
I tend to just base on the file presence, its the minimum necessary to suppress the errors:
|
|
If you guard based on the copy_from
promise being kept or repaired the
variable will only populate if the agent can successfully verify that the file
looks the same locally and remotely. Do you want to use stale data if you cant
reach the server?
|
|
Perhaps you only want the variable populated if the copy_from
promise has been
attempted (regardless of success or failure), and that there is data on the
disk, and that data is valid.
|
|