AnyRobot
  • Overview
  • Core Concepts
  • Getting Started
  • Portal
    • Portal API
    • Admin
  • Runner
    • Runner API
    • Admin
  • Developing Robots
  • Troubleshooting
Powered by GitBook
On this page
  • Installation guide
  • Install dependencies
  • Adding licenses to Runner
  • macOS System Access
  • Automatic updates
  • Runner behavior
  • Running file based jobs
  • Running project based jobs
  • Job result
  • Success - simple output
  • Failure - simple output
  • Success - with additional results
  • Firewall exceptions
  1. Runner

Admin

PreviousRunner APINextDeveloping Robots

Last updated 2 years ago

Installation guide

The installation process on the occasion of a fresh system is several steps which are listed below, in the case of steps that were previously performed on a particular computer, you can skip individual steps.

Install dependencies

The first step would be to install a package manager if you still don't have one, for Windows this would be choco, and for macOS homebrew.

To do this you need to paste the following command into Powershell or Terminal respectively.

Windows
macOS

If you have encountered any problems, it is recommended to check the program's documentation, which for Windows can be found and for macOS .

If you use Windows you will also need to install git, which you can do by running.

choco install git -Y

The next step will be to install Chrome and Chromedriver.

Windows
macOS

In the next step, we will install python.

Windows
macOS

If you encounter a problem with pip installation, you can use instead of command above:

In this step, we will take care of the installation of Ruby.

Windows
macOS

The final step will be to install imagemagic.

Windows
macOS

In addition, on Windows, you need to download msys2 and you can do this with the following command.

choco install msys2

After completing these steps, you may need to reboot the system

Adding licenses to Runner

to be released...

macOS System Access

On macOS, when you launch the application, the first screen you see will inform you of the current status of your granted permissions.

You need to click the buttons one by one which will open the appropriate tab in the settings and grant all the necessary access to the application.

After doing this, the window will close and you can proceed to the next step.

Automatic updates

Automatic updates work in a very simple way in which you won't even notice them. The important thing is that you don't have to worry about the update interrupting your work as this process doesn't start while the bot is running. After the update is finished the bot will turn itself on and connect to the portal so that it can continue working.

The only thing you need to check is whether you need to create an exception in the firewall to allow the bot to update itself. A list of hosts that the runner can reach can be found at Firewall exceptions.

Runner behavior

The following is a description of the path of how a runner that is ready to work behaves.

  1. We check the server to see if there is a new job for us (every 5 seconds).

  2. There is an empty answer - there is nothing to do, and we return to point 1.

  3. When we have something to do we execute a job.

  4. The result of the job is returned to the server.

  5. We return to point 1.

Running file based jobs

First, Runner creates a folder for himself with Job, at the following address: ~/.anyrobot/{job_id}

There you will find two folders and such files in such a structure:

  • input - input files directory.

    • script - the content of the downloaded task.

    • payload.json - that is the entire response from the server, example below.

  • output - output files directory

    • console.txt - what the console showed - with timestamps, logs etc.

    • result.txt - What the script showed on the console itself.

Example payload.json response:

{
  "secret": "d7dd76a0-b7a5-44d7-b98f-8712aa0e5707",
  "job_id": "bc55c654-94a6-11eb-a8b3-0242ac130003",
  "workflow_id": "c6d0fd24-94a6-11eb-a8b3-0242ac130003",
  "workflow_name": "Test workflow",
  "trigger_name": "schedule",
  "trigger_id": "2d11707c-96ce-11eb-a8b3-0242ac130003",
  "task": {
    "method": "download",
    "name": "task_dir/task_name",
    "download_url": "https://wwww.serwer/test.rb"
  }
  "assist_requests_url": "https://serwer.xxx.yyy.com/api/v1/jobs/123e4567-e89b-12d3-a456-426614174000/assist_requests",
  "results_url": "https://serwer.xxx.yyy.com/api/v1/jobs/123e4567-e89b-12d3-a456-426614174000/results",
  "parameters": {
    "hello": "world",
    "lorem": "ipsum"
  }
}

Script used as an example:

test.rb
#!/usr/bin/env ruby

require 'json'

# Load payload

file = File.read("input/payload.json")
payload = JSON.parse(file)

# Print ARGV + ENV

puts "Payload: #{payload.inspect}"
puts "Arguments: #{ARGV.inspect}"
puts "Environment: #{ENV.inspect}"

Note that the working directory is set to the job directory, not the input directory. This may affect the paths of loaded files like "payload.json" → "input/payload.json".

We already have everything downloaded, in the right folder, so the application executes this file (in case you need to give, for example, chmod +x on it, using the built-in console. The application is agnostic to the programming language used, so it is very important that the first line of the file is a shebang:

#!/usr/bin/env ruby
#!/usr/bin/env python
#!/usr/bin/env node
#!/usr/bin/env dart

Thanks to this Runner knows how to run such a file. The command contained in the shebang (ruby, python, node, etc...) can be changed at will and is passed as a script call command. For known types, additional environment configurations are put in place for the Activity Monitor to work seamlessly.

Running project based jobs

  1. As with a regular job, its folder is created.

  2. Then the Runner, based on the DownloadUrl from the Task from Job, checks if it has such a repository cloned on disk, and if it has anyrobot.yml.

    • If there is not then:

      1. Clones and changes the branch to a value with BranchName from Task from Job.

      2. Checks if the project anyrobot.yml file exists.

      3. Parses the anyrobot.yml.

      4. Executes install_command from anyrobot.yml.

      5. Executes after_install from anyrobot.yml.

      6. If something goes wrong it aborts the operation.

  3. It checks if there is a new version using git branch and determines possibly if it is detached, then git rev-parse HEAD and git ls-remote -q origin refs/heads?{branch}.

    • If there is a new version:

      1. Executes before_update from anyrobot.yml.

      2. Saves information about the last commit.

      3. Updates to a newer version: git reset --hard, then git switch {branchName} and git pull.

      4. Checks for anyrobot.yml and parses it.

      5. Executes after_update from anyrobot.yml.

      6. If the update procedure did not go as planned and something went wrong it performs a git reset --hard and checkout commit, which he saved for himself in point 2.

  4. Once everything is ok the following are launched in sequence:

    1. Executes before_runner from anyrobot.yml.

    2. Executes after_runner from anyrobot.yml.

  5. If nothing threw an exception or no bad execution code appeared in the terminal Job returns success. In any other case, if something goes wrong during any step a fail is returned (and a report to sentry).

Job result

There are two possibilities, the executed Job can be successful or failed, and accordingly, then different responses are sent.

Success - simple output

Let's assume that the executed script will display something like this:

Hello, I'm AnyRobot! 😀
Chromedriver is present ✅

Here there is no special tag, so the return to the server is quite simple afterwards:

# Request

POST /api/v1/jobs/94916326-9344-43f5-9187-1aea2931eac7/results
Authorization: Bearer 123e4567-e89b-12d3-a456-426614174000

{
  "genre": "success",
  "code": 0,
  "output": "Hello, I'm AnyRobot! 😀
Chromedriver is present ✅"
}

# Response

201 Created
404 job not found
422 bad format

Failure - simple output

Let's assume that the executed script will display something like this:

zsh: command not found: dart

Thus, to the server goes the information about the failure:

# Request

POST /api/v1/jobs/94916326-9344-43f5-9187-1aea2931eac7/results
Authorization: Bearer 123e4567-e89b-12d3-a456-426614174000

{
  "genre": "failure",
  "code": 127,
  "output": "zsh: command not found: dart"
}

# Response

201 Created
404 job not found
422 bad format

Success - with additional results

The script is responsible for preparing the files result.json and attachments.json in the output directory. If either file is created its contents will be attached to the corresponding key in the uploaded result: "result" for result.json and "attachments" for attachments.json. If no file is created, the key will not be added.

{
  "genre": "success",
  "code": 0,
  "output" : "My first output line... hello world!",
  "result": {
    "lorem": "ipsum"
  },
  "attachments": [
    {
      "genre": "html",
      "attachment_id": "123e4567-e89b-12d3-a456-426614174000",
      "name": "Lorem Ipsum",
      "code": "electrical_parameters_voltage",
      "body": "<!doctype html> <html lang=\"en\"> <head> <meta charset=\"utf-8\"> <title>The HTML5 Herald</title> <meta name=\"description\" content=\"The HTML5 Herald\"> <meta name=\"author\" content=\"SitePoint\"> <link rel=\"stylesheet\" href=\"css/styles.css?v=1.0\"> </head> <body> <script src=\"js/scripts.js\"></script> </body> </html>"
    },
    {
      "genre": "file",
      "attachment_id": "123e4567-e89b-12d3-a456-426614174000",
      "name": "test.png",
      "code": "electrical_parameters_voltage",
      "body": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="
   }
  ]
}

Output is always included because it is independent of the result and attachments files created by the script.

Firewall exceptions

Here is the list of hosts used by the applications:

  • your portal address

If you are using Windows before proceeding further you must first download .NET Runtime 5.X from .

For project-based Jobs, the principle is very similar to file-based. The biggest difference is the appearance of the anyrobot.yml file which is presented in more detail .

Executes runner_command from anyrobot.yml with passed parameters. For more detailed information about this step, see above.

More is explained in the chapter and .

sentry address - check out sentry docs

Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
choco install googlechrome -Y
brew install google-chrome
choco install chromedriver -Y
brew install chromedriver
choco install python -Y
brew install pyenv
python -m pip install -U pip
pyenv install $(pyenv install -l | grep -v - | tail -1)
pyenv global $(pyenv install -l | grep -v - | tail -1)
python -m ensurepip
eval "$(pyenv init -)"
pip install --upgrade setuptools pip
choco install ruby --version=3.0.0.1
brew install rbenv ruby-build
rbenv init
gem install bundler
rbenv install 3.0.0
rbenv global 3.0.0
choco install imagemagick
brew install imagemagick
brew install mono-libgdiplus
here
here
here
install.anyrobot.com
here
File-based jobs
here
Attachments
Job Results