Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Complete the Recipes Section of Docs #68

Closed
icebourg opened this Issue Jan 23, 2013 · 10 comments

Comments

Projects
None yet
6 participants

We've got a pretty significant deploy of collins going, and it's been a great tool. We've started to get to the point where we really want to start expanding collins via callbacks, and have a tentative idea for what we want to do, but the docs are kind of sparse. The recipes section doesn't have anything listed.

I think the best thing to document first would be the list of replacement variables that are available like the doc for the provision script does. One example <tag>, but are there others? For example, when asset_meta_value_create is called, is there a variable that tells us which value was created?

Without a replacement like that, we'll have to get the logs for that tag and operate anything we find there, but it would be nice to know if we have to do that, or if collins will give us the exact values for free if you just know how to ask. :)

I tried looking through the code but I'm not familiar enough with scala to be able to piece out the info I was looking for.

Collins has been a great tool. Thanks for releasing it.

AJ

Contributor

bmatheny commented Jan 26, 2013

I'm pasting below a few callbacks that we're using today at Tumblr. The reason the docs aren't up to date on these is that we have a major internal refactor coming up and were going to hold off. I'll keep the issue open until the update is done, but hopefully the stuff below is useful.

callbacks.registry {
  provisionVlan {
    on = "asset_update"
    when {
      previous.state = "isProvisioning"
      current.state = "isProvisioned"
    }
    action {
      type = exec
      command = "/opt/ruby-1.9.2/bin/visioner envision ewr_finish_provisioning --config=/usr/local/collins/config/production_ewr01.yaml --tag=<tag> --profile=discovery --trace --logfile=/tmp/<tag>-provision.log --app=/opt/visioner_apps/current/"
    }
  }

  hardwareProblem {
    on = "asset_update"

    when {
      previous.state = "!isMaintenance"
      current.state = "isMaintenance"
      current.states = [
        IPMI_PROBLEM,
        HARDWARE_PROBLEM,
        HARDWARE_UPGRADE,
        NETWORK_PROBLEM
      ]
    }

    action {
      type = exec
      command = "/opt/ruby-1.9.2/bin/visioner envision notify --config=/usr/local/collins/config/production_ewr01.yaml --tag=<tag> --recipient=jira-infra@tumblr.com --trace --logfile=/tmp/<tag>-maintenance.log --app=/opt/visioner_apps/current/"
    }
  }

}

The substitutions available are the methods on each object. If you subscribe to an asset_meta_value_create you have access to all the values on the AssetMetaValue case class. The most useful one is probably <value>, if more are needed (<assetTag> seems useful, it's trivial to add).

Blake,

That's indeed very helpful and a great pointer for me as I start to mess around with callbacks. Thanks!!

AJ

Contributor

cburroughs commented Apr 10, 2013

Refactor of the callback mechanism in collins, or of visioner and the other things using it?

Contributor

bmatheny commented Apr 10, 2013

The callback mechanism (there's a PR for it), although the change is backwards compatible. Visioner we intend on open sourcing at some point (not much magic, just helpers for dealing with lots of different systems).

Contributor

axlroden commented Apr 28, 2015

I have written callbacks, but they don't seem to trigger, let me show you my callback config:

callbacks.registry {
  provision {
    on = "asset_update"
    when {
      previous.state = "!Provisioning"
      current.state = "Provisioning"
      current.states = [ ISPROVISIONING ]
    }
    action {
      type = exec
      command = "echo WTF > /opt/wtf.txt"
    }
  }
}

Replaced my command with an obvious one :)

And then I try and trigger it with:

curl --basic -u apiuser:yes -d status=Provisioning -d reason='test' -d state=ISPROVISIONING http://172.16.1.10:8080/api/asset/00-25-90-68-c7-66
{"status":"success:ok","data":{"SUCCESS":true}}

I see no log info on a successful trigger anywhere :\

Collaborator

byxorna commented Apr 28, 2015

@axlroden drop the current.states = [ ...]. You already are specifying the previous and current state you want to trigger on. This should work:

callbacks.registry {
  provisionVlan {
    on = "asset_update"
    when {
      previous.state = "isProvisioning"
      current.state = "isProvisioned"
    }
    action {
      type = exec
      command = "/usr/bin/do_something --tag=<tag> "
    }
  }
}

However, I suspect you probably want to use the actual provisioner plugin instead:

provisioner {
  enabled=true
  profiles="/etc/collins/profiles.yaml"
  checkCommand = "/usr/local/bin/can_asset_provision --tag=<tag> --opts=tag=<tag>,profile=<profile-id>,suffix=<suffix>,notify=<notify>,noop=true"
  command = "/usr/local/bin/provision_asset_yo --tag=<tag> --opts=tag=<tag>,profile=<profile-id>,suffix=<suffix>,notify=<notify>,set-vlan=PROVISIONING"
}
Contributor

axlroden commented Apr 29, 2015

@byxorna thanks, I have tried without my current.states as well without it triggering, but yeah.. provisioner seems a much better fit for what I'm trying at the moment.

I'll try that out.

Contributor

axlroden commented Apr 29, 2015

@byxorna success on provisioner, works great.

I would really love to get callbacks working for some of my other states though :) is there any way to see debug info on why its not triggering?

Collaborator

byxorna commented Apr 29, 2015

@axlroden best way is to just play with it. We have lots of state transitions that trigger all kinds of things. Here are some examples:

callbacks.registry {
  runProvisionedCallback {
    on = "asset_update"
    when {
      previous.state = "isProvisioning"
      current.state = "isProvisioned"
    }
    action {
      type = exec
      command = "/usr/bin/do_something_to_newly_provisioned_asset --tag=<tag> "
    }
  }
  provisioningProblem {
    on = "asset_update"
    when {
      previous.state = "!isMaintenance"
      current.state = "isMaintenance"
      current.states = [
        PROVISIONING_PROBLEM
      ]
    }
    action {
      type = exec
      command = "/usr/bin/echo fire a ticket because provisioning failed"
    }
  }

  hardwareProblem {
    on = "asset_update"
    when {
      previous.state = "!isMaintenance"
      current.state = "isMaintenance"
      current.states = [
        IPMI_PROBLEM,
        HARDWARE_PROBLEM,
        HARDWARE_UPGRADE,
        NETWORK_PROBLEM
      ]
    }
    action {
      type = exec
      command = "/usr/bin/echo fire a ticket because the machine needs some help"
    }
  }
Contributor

axlroden commented Apr 29, 2015

thanks, and sorry for hijacking this issue.

@maddalab maddalab closed this May 25, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment