Skip to content

Quickstart: Hello World

rmadsen edited this page Sep 6, 2014 · 23 revisions

EOS SDK Quick Start: a Hello World Agent

Introduction

This tutorial will walk you through building, installing, and running your first EOS SDK agent. By the end of this page, you will have created an agent that will say 'Hello' to a name configured via the CLI, and thereby redefining the term "Social Networking." This program, although simple, demonstrates the lifecycle of an agent along with various components of the SDK. We'll first walk you through creating the agent executable, then explain how to run your agent, and, finally, a walkthrough of the EOS SDK code. If you'd like to explore the code without setting running the switch, skip the Getting Started section.

The complete code for the agent can be found in the examples directory, at [HelloWorld.cpp](<<<<<) for the C++ version of the agent, and [HelloWorld.py](<<<<<) for the Python implementation. Note that you can easily access the raw versions of the example files (for easy wget or scp access) by clicking the 'Raw' link in the upper right of each file's GitHub page.

Getting Started

First, we'll need an EOS instance where we can run our new agent. That means we'll need either a vEOS virtual machine or a physical switch. We then need to install the EOS SDK RPM, which contains the binary implementation of the SDK. Follow the download an installation instructions for information on how to complete both of these steps.

Building your agent

If you want to use the Python version of the agent, there is no need to build anything. All you need to do is copy the script to the switch:

switch# copy https://raw.github.com/aristanetworks/EosSdk/blob/master/examples/HelloWorld.py/mnt/flash/HelloWorld.py

For the C++ version of the agent, you'll need a 32-bit Linux environment with the stubs tarball downloaded, unpacked, and built. See [Building your agent](<<<<) for more information on setting up your build environment. Then, copy the HelloWorld.cpp file to your build directory and run:

bash# g++ -std=gnu++0x -o HelloWorldBinary HelloWorld.cpp -leos

which will create an executable named HelloWorldBinary in your current directory. Copy that file to your switch's /mnt/flash/ directory.

Running your Agent

Now that we have a switch with the SDK installed along with an agent executable, let's run the agent!

bash# ssh admin@myAristaSwitch
switch> enable
switch# configure
switch(config)# daemon HelloWorldAgent
switch(config-daemon-HelloWorldAgent)# exec /mnt/flash/HelloWorld.py (or HelloWorldBinary for the C++ binary)
switch(config-daemon-HelloWorldAgent)# no shutdown

You can confirm that the program is running via the show daemon command:

switch(config-daemon-HelloWorldAgent)# show daemon
Agent: HelloWorldAgent (running)
No configuration options stored.

Status:
Data           Value
-------------- ---------------------------
greeting       Welcome! What is your name?

Looks like everything is up and running! Let's now tell our friendly agent our name:

switch(config-daemon-HelloWorldAgent)# option name value Robert Metcalfe
switch(config-daemon-HelloWorldAgent)# show daemon
Agent: HelloWorldAgent (running)
Configuration:
Option       Value
------------ ---------------
name         Robert Metcalfe

Status:
Data           Value
-------------- ----------------------
greeting       Hello Robert Metcalfe!

And, ta-da, our agent said instantly reacted to the name option and said "hi". Feel free to change your name via the option name value <new-name> command and remove your name via no option name, and observe how your newly created social network responds. When we're finished, we can stop our agent using the shutdown command:

switch(config-daemon-HelloWorldAgent)# shutdown
switch(config-daemon-HelloWorldAgent)# show daemon
Agent: HelloWorldAgent (shutdown)
Configuration:
Option       Value
------------ ---------------
name         Robert Metcalfe

Status:
Data           Value
-------------- ------
greeting       Adios!

Anatomy of the HelloWorld agent

In this section, we will explore the code behind the HelloWorld C++ agent. The same explanations hold for the Python variant.

In the beginning...

The agent executable first runs when you enter no shutdown via the CLI. At this point, ProcMgr starts up an instance of your agent, using the command stored in the exec CLI. As we game exec a path to our executable, ProcMgr will just directly run the agent, and thus, will first hit the main() function:

int main(int argc, char ** argv) {
   eos::sdk sdk;
   hello_world_agent agent(sdk);
   sdk.main_loop(argc, argv);
}

The set-up for this agent is simple. We first create an instance of the SDK, using eos::sdk's default constructor. We then construct the hello_world_agent class, which contains the meat of the program's logic. Let's see what happens there:

class hello_world_agent : public eos::agent_handler {
 public:
   eos::agent_mgr * agent_mgr;
   eos::tracer t;

   explicit hello_world_agent(eos::sdk & sdk)
         : eos::agent_handler(sdk.get_agent_mgr()),
           agent_mgr(sdk.get_agent_mgr()),
           t("HelloWorldCppAgent") {
      t.trace0("Agent constructed");
   }
   // ...
};

The first thing to notice is that the hello_world_agent inherits from eos::agent_handler. All agents should have at least one class that subclasses the agent_handler, as this handler provides agent-specific callbacks alerting you of startup, shutdown and configuration events. In many cases, your main class will inherit from several handlers, each providing specific on_xxx() callbacks that let you react to other network events. As our HelloWorld agent only cares about agent options, we only need to subclass from the agent_handler.

In the hello_world_agent constructor, we go ahead and initialize various elements:

  • our superclass, which takes an eos::agent_mgr...
  • ... which we also store in a class agent_mgr * instance variable
  • and finally a eos::tracer object, which lets our agent output debug trace statements to its log file when tracing is enabled

At this point, all of the relevant classes, data structures and logic are created, so, back in our main function, we begin the main_loop. This function never returns and instead creates the continuously running event loop, managed by the SDK.