Your First Service
This page takes about five minutes and needs nothing but the agent installed on one machine. No shared storage, no second node, no cluster. At the end you will have created a service, started it, proven it is serving, and stopped it.
We will wrap a plain HTTP server, because it is the shortest thing whose running you can prove rather than take on trust.
The API tabs assume the
$TOKENand the listener endpoint set up in Cluster API.hellois asvcof therootnamespace, so its path is/api/object/path/root/svc/hello. They are here to show that nothing on this page is command line only: a reader following along has the agent installed and no token yet, and does not need one.
Create it
An object is created from the command line, resource by resource. Here is a
single app resource, told how to start:
om hello create \
--kw app#1.type=simple \
--kw 'app#1.start=/usr/bin/python3 -m http.server 8099'
Creating an object through the api is posting its configuration file:
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/octet-stream" \
--data-binary $'[app#1]\ntype = simple\nstart = /usr/bin/python3 -m http.server 8099\n' \
"https://<node>:1215/api/object/path/root/svc/hello/config/file"
Nothing was started, and nothing outside /etc/opensvc was touched. The
command only wrote a configuration, which you can read back:
om hello config show
curl -s -H "Authorization: Bearer $TOKEN" \
"https://<node>:1215/api/object/path/root/svc/hello/config/file"
[DEFAULT]
id = 0e745444-6724-48f9-8167-e865b4f9ec94
[app#1]
type = simple
start = /usr/bin/python3 -m http.server 8099
[app#1] is a resource. app is its driver group, 1 its index, and
type = simple picks the driver that supervises a long-running process.
Start it
om hello instance start
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
"https://<node>:1215/api/node/name/<node>/instance/path/root/svc/hello/action/start"
The api answers the session_id and exec_id of the run it forked, where the
cli prints the run as it happens.
INF hello: >>> do start [om hello instance start] (origin user, sid 7b9772c8)
INF hello: app#1: run: om exec --pg /opensvc.slice/... -- /usr/bin/python3 -m http.server 8099
INF hello: <<< done start in 98.079925ms, instance status is now up
The agent tells you what it ran and what the instance status became.
Prove it
curl -o /dev/null -w "%{http_code}\n" http://localhost:8099/
200
Look at it
om hello instance status
curl -s -H "Authorization: Bearer $TOKEN" \
"https://<node>:1215/api/instance?path=root/svc/hello&node=<node>"
The api answers the configuration, status and monitor state of the instance as json, which the cli renders as the tree below.
hello
└ instances
└ node1 up no-monitor
└ resources
└ app#1 ...../.. up simple
The instance is up because its only resource is up. Had the resource
failed, both lines would say so. This is the command you will reach for most
often.
Stop it
om hello instance stop
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
"https://<node>:1215/api/node/name/<node>/instance/path/root/svc/hello/action/stop"
INF hello: app#1: send termination signal to process 2615892
INF hello: app#1: process 2615892 is now terminated
INF hello: <<< done stop in 86.862589ms, instance status is now down
The port is closed and the status agrees:
curl --max-time 3 http://localhost:8099/
om hello instance status
curl: (7) Failed to connect to localhost port 8099: Connection refused
hello
└ instances
└ node1 down no-monitor
└ resources
└ app#1 ...../.. down simple
Clean up
om hello delete
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
"https://<node>:1215/api/object/path/root/svc/hello/action/delete"
OBJECT ORCHESTRATION_ID STATUS
hello 068b4fb0-ba3f-4d62-81e7-92ed88039239 accepted
The configuration is gone, and with it the object.
Two ways to start
You used om hello instance start, which starts the instance on this node,
now, and prints each step as it happens.
Its cluster counterpart is om hello start, which does not act directly. It
asks the cluster to reach the started state, and answers with an
orchestration id:
OBJECT ORCHESTRATION_ID STATUS
hello 45c9de82-ed12-48df-bdb2-21a251fb039d accepted
The daemon then picks a node and starts the instance there, which is what you
want once the object runs on more than one node. Watch it happen with om mon.
Note that the matching om hello stop flags the instance stopped on purpose,
so the daemon does not immediately start it again. The next om hello start
clears the flag.
What you just did
You described a process in a configuration file, and the agent started it, tracked its state, and stopped it. Everything else the agent does is this same loop with more interesting resources: an ip that moves between nodes, a filesystem mounted from a shared disk, a container, a database volume.
Where to go next:
- Naming to place objects in namespaces before you have many of them.
- Create, Deploy for the other ways to create an object, including from a manifest.
- Cluster Configuration to add a second node, which is where failover starts to matter.