Azure / simdem

Tool for Simulating Demo's, delivering Tutorials and using documentation as tests.
MIT License
34 stars 17 forks source link

SimDem 2 Feature: Wait for output to match #95

Open lastcoolnameleft opened 6 years ago

lastcoolnameleft commented 6 years ago

There are some commands which need to wait until the output matches a different output.

Should we implement a standardized way to say "continue running until the result matches X"?

Take for example this document for exposing a K8S service where type=LoadBalancer.

kubectl get service my-nginx

Results:

NAME       TYPE           CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
my-nginx   LoadBalancer   10.0.206.82   <pending>     80:32226/TCP   2m

After about 3-5 minutes, if you run the command again, you should get something like this:

NAME       TYPE           CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
my-nginx   LoadBalancer   10.0.206.82   52.151.63.4   80:32226/TCP   3m

Once the external-ip is available, we can proceed:

SERVICE_IP=$(kubectl get service my-nginx -o json | jq '.status.loadBalancer.ingress[0].ip' -r)
echo $SERVICE_IP
curl -v $SERVICE_IP
lastcoolnameleft commented 6 years ago

An alternative is to not bake into SimDem and use:

until [ $SERVICE_IP ]; do SERVICE_IP=$(kubectl get service my-nginx -o json | jq '.status.loadBalancer.ingress[0].ip' -r); sleep 5; done

However, this make documenting and testing trickier.

SorraTheOrc commented 6 years ago

I've used approaches such as your alternative solution up until now. It works, and serves the purpose of communicating well to the reader how they would achieve this in their own scripts. However, it does make documentation harder to read.

An approach I considered was to have SimDem provide helper functions that would make the documentation more readable. I started implementing this.

In the current version of SimDem we can intercept commands and replace them with other commands. For example, if you have a xdg-open (opens the browser on Linux desktops) but are running in headless mode it replaces it with an appropriate curl command. More appropriate to this specific problem is how I worked around the need to provide credentials when working with cloud providers such as Azure in an automated test environment. You can see an example of this in https://github.com/Azure/simdem/blob/master/cli.py#L308, az login will fail in an automated environment so I intercept it and assume there is a service principle available in the environment (which there is in the CI solution).

We could reimplement/reuse this approach to provide helper functions as I think there will be a relatively small number of cases like this. Something like:

waitFor SERVICE_IP=$(kubectl get service my-nginx -o json | jq '.status.loadBalancer.ingress[0].ip' -r)

Or even:

## Wait For [free text description]

SERVICE_IP=$(kubectl get service my-nginx -o json | jq '.status.loadBalancer.ingress[0].ip' -r)

However, I don't see either of these as ideal. Nor do I see the need for documentation workarounds such as thos in your last comment as a blocker.

lastcoolnameleft commented 6 years ago

I like the idea of having waitFor or some other functions that are built in that imply looping. It could then have better outputting because now the user sees nothing until the entire loop is complete.

For now, I'll leave the shell syntax until I get some time to implement and test waitFor and/or other helper functions.