Brooke's World The life and ramblings of Brooke.

November 15, 2016

Salt Reactor : Having a minion ask another minion to execute a module with events and reactors

Filed under: Uncategorized — Brooke @ 3:38 pm

 

I needed to solve the task of having a minion execute a job on another minion and this is how I accomplished the task.  This stemmed from having a minion that runs a web applications which just needed to execute an execution module that already existed, but needed to run on a different minion.

My solution depends on Salt events and reactors to orchestrate the request from the web server minion to the worker minion and have the worker minion give a response of the work it completed back to the web server minion.

Salt version: salt 2016.3.4

Machines:

Host Salt Role Use Case
saltmast16 Salt Master Orchestrator
saltmina16 Salt Minion Where execution module will run
saltminb16 Salt Minion Web server that initiates work

 

 

/srv/salt/_modules/rhtest.py

The event.fire_master call sends the com/millamilla/test/event/finish event to the master

saltminb16

Web Server

 Web Server Files/ Code salmast16

Master

 Master Files/ Code saltmina16

Worker

Worker Files/ Code
Send an event from the web server to the master. Send event
com/millamilla/test/event/start
Python: send_event.py 

import salt.client
import uuid

caller = salt.client.Caller()
event_uuid = str(uuid.uuid1())

caller.sminion.functions['event.send'](
    'com/millamilla/test/event/start',
    {
      'target': "saltmina16",
      'site': "moodle",
      'user': "hedrickbt",
      'uuid': event_uuid,
    }
)
Receive event
com/millamilla/test/event/start
 /etc/salt/master.d/reactor.conf

reactor:
  # ...
  - 'com/millamilla/test/event/start':        
    - salt://reactor/rhtesteventstart.sls   
  # ...
#...
 >>>>>>>>>>>>>>>>>>>>   >>>>>>>>>>>>>>>>>>>>>>>>>>>>
 Master handles event and causes execuction module to run on worker minion Handle com/millamilla/test/event/start Event.  Call execution module on worker.  /srv/salt/reactor/rhtesteventstart.sls

run_it:
  local.rhtest.rhfunc:
    - tgt: {{ data['data']['target'] }}
    - arg:
      - {{ data['data']['site'] }}
      - {{ data['data']['user'] }}
      - {{ data['id'] }}
      - {{ data['data']['uuid'] }}

 

Execute module Created on master:
/srv/salt/_modules/rhtest.py
and sync’d to minions from master via:
salt ‘*’ saltutil.sync_all

import salt

__outputter__ = {
  'rhfunc': 'yaml'
}

def rhfunc(site, user, requesting_host, event_uuid):
  result = {
    "site":site,
    "user":user,
    "requesting_host":requesting_host,
    "uuid":event_uuid
  }

  __salt__['event.fire_master'](
    {
      "site":site,
      "user":user,
      "requesting_host":requesting_host,
      "uuid":event_uuid,
    },
    'com/millamilla/test/event/finish',
  )

  return result
 >>>>>>>>>>>>>>>>>>>  >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 After worker minion executes modules send event back to master Receive event
com/millamilla/test/event/finish
/etc/salt/master.d/reactor.conf

reactor:
  # ...
  - 'com/millamilla/test/event/finish':
    - salt://reactor/rhtesteventfinish.sls 
  # ...
<<<<<<<<<<<<<<<<<<< <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 Forward event Master received to the web minion. Receive/Handle Event

com/millamilla/test/event/finish

Python: receive_event.py

This needs to run just after sending the message so it can be listening.  You will want to add code that has a timeout in the for…print loop.  Otherwise, it could run forever.

You will also want to add code to look at the data[‘uuid’] to make sure it is the one you sent out.

Typically, you wouldn’t have a separate send/receive program, but you can.  I plant to create a single script that generates the uuid, sends the request, and waits for a message to return within a timeout period.  If the timeout is exceeded an error would be thrown.

import salt.config
import salt.utils.event
import socket
import os

# Import 3rd-party libs
import salt.ext.six as six

my_hostname = socket.gethostname()

#opts = salt.config.client_config('/etc/salt/minion')
opts = {}
opts['node'] = 'minion'
opts['sock_dir'] = '/var/run/salt'
opts['sock_dir'] = os.path.join(opts['sock_dir'], opts['node'])
opts['id'] = my_hostname
opts['transport'] = 'zeromq'

event = salt.utils.event.get_event(
        opts['node'],
        sock_dir=opts['sock_dir'],
        transport=opts['transport'],
        opts=opts)

for data in event.iter_events(tag='com/millamilla/test/event/finish'):
    print(data)
Handle Event

com/millamilla/test/event/finish

 /srv/salt/reactor/rhtesteventfinish.sls

notify_it:
  local.event.fire:
  - tgt: {{ data['data']['requesting_host'] }}
  - arg:
    - {{ data['data'] }}
    - com/millamilla/test/event/finish
 <<<<<<<<<<<<<<<<<<<  <<<<<<<<<<<<<<<<<<<

October 3, 2013

Using the tymkrs “Turn Me” with an Arduino

Filed under: Uncategorized — Tags: — Brooke @ 11:24 pm

Here is a quick write up on how to use the tymkrs “Turn Me” rotary encoder.  This supports the “push down” feature of the tymkrs kit.

RotaryEncoderDemo_bb     output_window

DSC_0249_for_web

Fritzing Rotary Encoder Part: Rotary Encoder with Knob bth.fzpz

Fritzing Project: RotaryEncoderDemo.fzz

Arduino (1.5) project: RotaryEncoderDemo.ino


 /* Read Quadrature Encoder
  * Connect Encoder to Pins encoder0PinA, encoder0PinB, and +5V.
  * http://playground.arduino.cc/Main/RotaryEncoders
  * Sketch by max wolf / www.meso.net
  * v. 0.1 - very basic functions - mw 20061220
  * Sketch updated by Brooke Hedrick / www.millamilla.com
  * v. 0.2 - Added the "S" pin for encoders with push-down support - bth 09292013
  *        - Put a limit of 255 and 0 in place.  It rolls over automatically at the limits - bth 09292013
  *
  */

 int val;
 int encoder0PinA = 3;
 int encoder0PinB = 4;
 int encoder0PinS = 5;
 int encoder0PosUp = 0;
 int encoder0PosDown = 0;
 int encoder0PinALast = LOW;
 int n = LOW;
 int encoder0UpDown = LOW;

 void setup() {
   pinMode(encoder0PinA,INPUT);
   pinMode(encoder0PinB,INPUT);
   pinMode(encoder0PinS,INPUT);
   Serial.begin (9600);
 }

 void loop() {
   encoder0UpDown = digitalRead(encoder0PinS);
   n = digitalRead(encoder0PinA);
   if ((encoder0PinALast == LOW) && (n == HIGH)) {
     //Serial.print("up down:");
     //Serial.println(encoder0UpDown);
     if (digitalRead(encoder0PinB) == LOW) {
       if (encoder0UpDown == LOW) {
         encoder0PosUp--;
         if (encoder0PosUp < 0) {
             encoder0PosUp = 255;
         }
       } else {
         encoder0PosDown--;
         if (encoder0PosDown < 0) {
             encoder0PosDown = 255;
         }
       }
     } else {
       if (encoder0UpDown == LOW) {
         encoder0PosUp++;
         if (encoder0PosUp > 255) {
           encoder0PosUp = 0;
         }
       } else {
         encoder0PosDown++;
         if (encoder0PosDown > 255) {
           encoder0PosDown = 0;
         }
       }
     }
     Serial.print(encoder0PosUp);
     Serial.print(" ");
     Serial.println(encoder0PosDown);
   }
   encoder0PinALast = n;
 }

September 28, 2013

Contextual Electronics : Session 1 : Module 3 : Unit 5 : Understanding The Relay Module : Task

Filed under: Uncategorized — Tags: — Brooke @ 12:12 am

Task

  • Create a block diagram for the relay driver circuit.

Module3Unit5_schematic

Git: https://github.com/hedrickbt/ContextualElectronics/tree/Module3Unit5/Session1/MyBenchBuddy/KiCad

September 25, 2013

Contextual Electronics : Session 1 : Module 4 : Unit 5 : Choosing Components For The Current/Fan Driver Module : Task

Filed under: Uncategorized — Tags: — Brooke @ 11:57 pm

Task

Find the following types of components

Recall the following design goals:

  • Swappable components with easy to solder packages.
  • Low cost.
  • SPI DAC part with 8- 10 bits.
  • MOSFET capable of carrying half an amp in a surface mount package.
  • Moderately accurate sense resistor.

September 24, 2013

Contextual Electronics : Session 1 : Module 3 : Unit 4 : Understanding The Current/Fan Driver Module : Task

Filed under: Uncategorized — Tags: — Brooke @ 11:44 pm

Task

  • Create a current source with a voltage input, using an op amp.
  • Add in an optional DAC to control the current source with voltage readback

Schematic

Module3Unit4_schematic

Git Repository: https://github.com/hedrickbt/ContextualElectronics/tree/Module3Unit4/Session1/MyBenchBuddy

September 22, 2013

Contextual Electronics : Session 1 : Module 4 : Unit 4 : Choosing Components For The Thermocouple Module : Task

Filed under: Uncategorized — Tags: — Brooke @ 8:45 pm

Task

Find the following types of components:

Recall the following design goals:

  • 16+ bit input
  • Low cost
  • 1 degree C accurate (aim for .5 C accurate)
  • Swappable components
  • Easy to solder components

September 21, 2013

Contextual Electronics : Session 1 : Module 3 : Unit 3 : Understanding the Thermocouple Module : Task

Filed under: Uncategorized — Tags: — Brooke @ 11:37 am

Task

  • Create a block diagram for the thermocouple measurement circuit in Kicad.

Module3Unit3_schematic

 

Github:  https://github.com/hedrickbt/ContextualElectronics/tree/Module3Unit3/Session1/MyBenchBuddy

September 12, 2013

Contextual Electronics : Session 1 : Module 2 : Unit 9 : Creating A Schematic Skeleton : Task

Filed under: Uncategorized — Tags: — Brooke @ 8:50 pm

Task

  1. Create a schematic with a heirarchical page for each block in the block diagram.
  2. Add some hierarchical labels within one of the sheets.
  3. Exit the sheet and import the heirarchical pin to the top level heirarchy symbol.

SheetWithHiearchicalSheets

Github:  https://github.com/hedrickbt/ContextualElectronics/tree/Module2Unit9/Session1/MyBenchBuddy

September 8, 2013

Contextual Electronics : Session 1 : Module 2 : Unit 11: Mechanical Constraints : Task

Filed under: Uncategorized — Tags: — Brooke @ 9:02 pm

Measure or look up the dimension of an Arduino Uno. Compare against other versions of Arduino.

Verify the pin pitch of the stackable connectors on the edge of the Arduino.

Enter the board outline of the Arduino into PCBnew for a rough 2D guideline.

BoardEdgeLayout

September 5, 2013

Contextual Electronics : Session 1 : Module 2 : Unit 4: Project Creation : Task

Filed under: Uncategorized — Tags: — Brooke @ 4:32 am

If you want to participate alongside, do the following (before watching the execution video):

Older Posts »

Powered by WordPress