0

Currently I fail to run an azure CLI command from Groovy because of the JSON Part in the Command.

There is an azure command to run custom scripts on a virtual machine. The CommandToExecute on the Machine is passes as JSON.

WORKING Example:

REQUEST-CALL in Console:az vm extension set -g demo --vm-name demo-cfg01 --name CustomScript --publisher Microsoft.Azure.Extensions --settings '{"commandToExecute":"ls"}'

RESPONSE: {
  "autoUpgradeMinorVersion": true,
  "forceUpdateTag": null,
  "id": "/subscriptions/xxxxxxxxxx-xxxxxx-xxxx-xxxx-xxxxxxxxxxxxx/resourceGroups/demo/providers/Microsoft.Compute/virtualMachines/demo-cfg01/extensions/CustomScript",
  "instanceView": null,
  "location": "germanycentral",
  "name": "CustomScript",
  "protectedSettings": null,
  "provisioningState": "Succeeded",
  "publisher": "Microsoft.Azure.Extensions",
  "resourceGroup": "demo",
  "settings": {
    "commandToExecute": "ls"
  },
  "tags": null,
  "type": "Microsoft.Compute/virtualMachines/extensions",
  "typeHandlerVersion": "2.0",
  "virtualMachineExtensionType": "CustomScript"
}

This script works fine.

"Same" Command executed with Groovy leads to following:

def process
        StopWatch.withTimeRecording("EXECUTING COMMAND '" + cargs + "'",_logger, Level.ALL) {
            process = (cargs).execute(null,null);
            process.waitForProcessOutput(sout, serr)
        }

Please notice the StopWatch which logs the StringArray containing the params:

EXECUTING COMMAND '[az, vm, extension, set, -g, demo, --vm-name, demo-cfg01, --name, CustomScript, --publisher, Microsoft.Azure.Extensions, --settings, '{"commandToExecute":"ls"}']'

The Params looks the same as in the console

The Response from Azure is:

VM has reported a failure when processing extension 'CustomScript'. Error message: "Enable failed: failed to get configuration: error reading extension configuration: error parsing settings file: error parsing json: json: cannot unmarshal string into Go value of type map[string]interface {}

I think groovy somehow escapes the characters before execution, i cannot figure out what went wrong. Any suggestion?

3 Answers 3

0

when you call execute on array groovy (actually java) doublequotes each parameter.

just build your command line as you need in a string

string in groovy has the same execute method as an array...

def cmd = """az vm extension set -g demo --vm-name demo-cfg01 --name CustomScript --publisher Microsoft.Azure.Extensions --settings '{"commandToExecute":"ls"}' """
def process = cmd.execute()

when you use execute on string groovy will execute the exact command you've provided

Sign up to request clarification or add additional context in comments.

4 Comments

sadly that does not solve the issue - the same result
For the love of your sanity, don't use "string".execute() (ever) - rewrite it so you do ["az","vm","..."].execute() and don't quote your params for a shell that is never involved. If you need shellisms, then use ["sh","-c","am vm ..."].execute()
@cfrick, i'm not agree. jut look at ProcessImpl constructor with array of strings (line 151), that is finally called when you use [].execute(). It builds the single string command line and quotes some of array elements. in some cases especially in ms tools you don't need those quotes...
@daggett It does not in jdk8 and even it still does, this is not your problem. If you quote and the JDK quotes, then it's wrong again. Groovy splits a string with .execute() on whitespace and whatever quoting you do, it wont prevent it.
0

Found a "workaround". The az command also accept an *.json file as settings parameter. Therefor i first create the command in a temporary json file and passes the json file as parameter. Works!

Comments

0

You are quoting for an .execute() call. You dont need to quote there, because no shell or command parser is involved here.

Your command there gets '{"commandToExecute":"ls"}', which is a valid JSON String (no Map) and this is also what the error message states:

error parsing json: json: cannot unmarshal string into Go value of type map[string]interface

Just use {"commandToExecute": "ls"} (no surrounding ') as argument there.

2 Comments

The Parsing issue is from Azure. if i leave the ' the command fails on client side because of the Json which is not recognized as correct parameter...
Then this tool is borked and you should create a ticket there. And if they claim it is not bugged, i whish them good luck with making unix users make sense of behaviour like this ;P

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.