- auto restart and system service launch
- config on the platform
- tui for agent state monitoring
- key based auth
- autonomous config update
- Manually download latest release of agent for your system
- Make agent executable
chmod +x robot-agent-...
- Run agent with
api-key
(run only with -k parameter if do not need platform)
./robot-agent-... -a <API_KEY> -r http://robots.merklebot.com:8888 -k <BASE_64_OF_ED25519>
Use easy to run script:
curl -s https://app.merklebot.com/install.sh | bash -s <API_KEY>
The copy of script could be found at this repository
To stop agent
systemctl disable merklebot
The agent consists of 4 main modules:
- Platform module
- Docker module
- Libp2p interaction module
- Unix Socket Interface
First of all, robot-agent can be connected to merklebot's platform (app.merklebot.com) to get jobs from the cloud.
For authentication, agent needs api-key
which is available on a platform after your robot instance is created.
Note In next version of agent
api-key
will be changed forkey
(check libp2p section)
All the jobs sent from platform are splitted to 2 categories:
- Execution of container wrapper code
- Direct access to the terminal (of containerized environment)
Via port forwarding and docker volumes system it could be extended to manipulation of the whole host system.
It is also possible to store some data after job execution in bucket on merklebot's platform.
Libp2p protocol is used for advanced discovery of other agents (via mDNS) and messaging between agents.
For usage of this module, you'll need a key
- base64 encoded key.
Interface for applications and containers on devices. It creates a merklebot.socket
file which provides JSON API for interactions with an agent.
With platform or via API some code wrapped in docker container could be executed as job.
- Docker Image
Insert link for a container wrapped code. It should be stored in some publicly accessible container register (in other words docker pull LINK
should work)
- Docker Container Name
Name container to your liking, but with standard docker naming limitations
- Environmental variables
Add all the variables you think you'll need (like API keys, super secrets and other cool things)
-
Network mode: Switch between closed
default
network or allowhost
one -
Privileged mode
Run container with admin privileges. It could be used, if devices or specific host system volumes are needed in use.
- Port binding
Share ports between container and host system
- Volumes
Share folders or devices between container and host system
To store data after job is executed:
- Create bucket at app.merklebot.com
- Assign the bucket to the robot
- Turn on
Store data
in job configuration - Place required files in
/merklebot/job_data/
folder
After the code execution, files would be loaded to your bucket and accessible in job result screen
To access terminal of container via web-interface, add sh
to your custom tty
filed of job config.
The terminal could be reached in job status screen (OPEN TERMINAL).
Note To end job, don't forget to send
exit
.
You can use CLI tool to interact with your agents. Currently, it is in development. Two functions are supported:
- Get robot states
- Send docker jobs
Detailed information could be obtained here.
To connect different to devices (with different agents on them), you should create a device group config and spread it around devices. With the usage of this config, agent can match PeerId's and return IP addresses of devices in local network.
It could be used to avoid static IP for your group of devices.
To get devices, send JSON {"action": "/local_robots"}
to merklebot.socket
Example of config.json
:
{
"robots": [
{
"robot_id": "device-0",
"robot_peer_id": "12D3KooWKnY2J5CFny3Ef8abndmg9U4gAkndUDPM4oMP7yVbftBK",
"name": "spot",
"tags": [],
"interfaces": []
},
{
"robot_id": "device-1",
"robot_peer_id": "12D3KooWK8ogtRq7DXD21ji9nwkTgCfuz6AYU9dys8GrH7weC2AC",
"name": "jetson",
"tags": [],
"interfaces": []
}
]
}
Example of python code:
import socket
import os
import json
import pprint
socket_path = "FOLDER_WITH_AGENT/merklebot.socket"
def local_robots():
client = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
client.connect(os.path.realpath(socket_path))
message = {"action": "/local_robots"}
client.sendall(json.dumps(message).encode())
response = client.recv(1024).decode()
client.close()
return json.loads(response)
pprint.pprint(local_robots()) # prints json with found devices
Agents can exchange data using libp2p messaging protocol. Therefore, you won't need to worry about addressing between your robots. To use it, you'll need a robot group config like in previous section.
To send message, send JSON {"action": "/send_message", "content": "TEXT_OF_MESSAGE"}
to merklebot.socket
To receive one, subscribe with JSON {"action": "/subscribe_messages"}
Python code example:
import socket
import os
import json
import pprint
import time
socket_path = "FOLDER_WITH_AGENT/merklebot.socket"
def send_message(message_content):
client = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
client.connect(os.path.realpath(socket_path))
message = {"action": "/send_message"}
message["content"] = message_content
client.sendall(json.dumps(message).encode())
response = client.recv(1024).decode()
client.close()
return json.loads(response)
def subscribe_messages():
with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as client:
client.connect(os.path.realpath(socket_path))
client.sendall(json.dumps({"action": "/subscribe_messages"}).encode())
while True:
time.sleep(0.1)
response = client.recv(1024).decode()
if response:
print(response)