Configure new devices into Open Horizon nodes in the specified organization and exchange, with the specified pattern. This container may be run locally using Docker, pushed to a Docker registry, and published to any Open Horizon exchange.
org
-[email protected]
url
-com.github.dcmartin.open-horizon.hznsetup
version
-0.0.1
HZNSETUP_EXCHANGE_URL
- URL of exchange in which to setup device; default:${HZN_EXCHANGE_URL}
HZNSETUP_EXCHANGE_ORG
- organization in which to setup device; default${HZN_ORG_ID}
HZNSETUP_EXCHANGE_APIKEY
- IBM Cloud platform API key; default${HZN_EXCHANGE_APIKEY}
HZNSETUP_APPROVE
- default"auto"
; options: {auto
,serial
,mac
,both
}HZNSETUP_VENDOR
- default"any"
or value matching databasevendor
stringHZNSETUP_BASENAME
- string prepended when approve is"auto"
; default:""
HZNSETUP_PATTERN
- default pattern when non-specified; default:""
HZNSETUP_PORT
- port on which to listen for new devices; default:3093
(aka ƎDgƎ)HZNSETUP_PERIOD
- seconds between watchdog checks; default:30
LOGTO
- specify place to log; default:"/dev/stderr"
; use""
for"${TMPDIR}/${0##*/}.log"
LOG_LEVEL
- specify level of logging; defaultinfo
; options include (debug
andnone
; currently ignored)DEBUG
- default:false
emerg
- Emergencies - system is unusable.alert
- Action must be taken immediately.crit
- Critical Conditions.error
- Error conditions.warn
- Warning conditions.notice
- Normal but significant condition.info
- Informational.debug
- Debug-level messages
HZNMONITOR_EXCHANGE_URL
- URL of exchange in which to setup device; default:${HZN_EXCHANGE_URL}
HZNMONITOR_EXCHANGE_ORG
- organization in which to setup device; default${HZN_ORG_ID}
HZNMONITOR_EXCHANGE_APIKEY
- IBM Cloud platform API key; default${HZN_EXCHANGE_APIKEY}
This service listens for new node requests from devices over the network. Devices requesting node identification and tokens are booted from identitical media that has been creating using the standard IBM edge fabric installation instructions.
In addition, a short initialization script is added to enable the device to identify its hardware serial number, product identifier, and network connections, provide that information to this service, and -- if approved -- receive identification, authorization token, and any initial pattern; for example a client request:
{
"product": "jetson-nano",
"serial": "042111900396808083fb",
"mac": "00:04:4b:cc:4a:a6",
"inet": "192.168.1.87/24"
}
Devices are only candidates for approval as a new node based on the HZNSETUP_VENDOR
variable:
"any"
- approve new devices from any vendor product string"<string>"
- approve new devices matching database vendor product string
Candidate devices are approved based on the following settings for HZNSETUP_APPROVE
:
auto
- automatically approve any new device which provides a conforming serial # and MAC addressserial
- approve only devices which provide serial numbers found in the databasemac
- approve only devices which provide MAC address found in the databaseboth
- approve only devices which provide matching serial number and MAC address
Approved devices will receive a JSON payload with identifier and token; if approved, and and a pattern is specified, the device register for that pattern. Non-approved devices will receive JSON error payload.
- Start with supported vendor operating system distribution
- LINUX (Debian) on AMD64, ARM64, ARM(v6+), and PPC64 (little-endian)
- Suport for Docker community edition, version 18+
- Install pre-requisite & edge software
- LINUX utility:
lshw
- Docker installation documentation & script (get.docker.com)
- IBM Edge Fabric documentation
- Examples: Raspbian for RaspberryPi, JetPack™for nVidia Jetson Nano and TX2
- Add start-up script
- Copy script
/mkrequest.sh
to master device - Modify
/etc/rc.local
to invoke/mkrequest.sh
with specifiedhznsetup
server
- Remove media from master device
- Perform shutdown
- Power-off device
- Remove uSD card
- Duplicate uSD card
- Insert uSD into USB or SD card adapter
- Insert adapter into LINUX or macOS computer
- Copy from media to local file using
dd
- Safely eject adapter
- Create new media
- Insert new uSD card into adapter
- Copy file to device using
dd
Commercial duplication services will copy the master media to new media in lots of 100+ units; costs range from US$5 and up for a 16 Gbyte uSD card, depending on quantity and delivery.
The default approval method auto
provides a new identifier and token for any valid request; other approval methods depend on the contents of a valid request, notably the approval method serial
requires that the client request serial number be found in the device database.
The device database may be any CouchDB compliant database, e.g. IBM Cloudant. The database is specified with three userInput
variables:
HZNSETUP_DB
- the URL of the database server; default:""
(example:"https://<db>.cloudant.com"
)HZNSETUP_DB_USERNAME
- the username for access; default:""
HZNSETUP_DB_PASSWORD
- the password for access; default:""
These values should be specified in the userinput.json
file used to invoke this service as a pattern.
The database stores information about each device; a device record is defined by the following JSON structure:
{
"exchange": "http://exchange:3090/v1",
"org": "[email protected]",
"pattern": "none",
"device": {
"product": "jetson-nano",
"serial": "042111900396808083fb",
"mac": "00:04:4b:cc:4a:a6",
"inet": "192.168.1.87/24"
},
"node": {
"serial": "042111900396808083fb",
"device": "test-00044bcc4aa6",
"exchange": {
"token": "********",
"name": "test-00044bcc4aa6",
"owner": "[email protected]/[email protected]",
"pattern": "",
"registeredServices": [],
"msgEndPoint": "",
"softwareVersions": {},
"lastHeartbeat": "2019-04-27T00:40:58.904Z[UTC]",
"publicKey": "",
"id": "[email protected]/test-00044bcc4aa6"
},
"token": "e16b73d92d490df288fdfea68406d74935b90124"
},
"date": 1556325659
}
Clients request node status by submitting a JSON payload containing device details, for example:
curl 'localhost:3093' -X POST -H "Content-Type: application/json" --data-binary @client-request.json
The client-request.json
file contains the device specific details:
{
"product": "jetson-nano",
"serial": "042111900396808083fb",
"mac": "00:04:4b:cc:4a:a6",
"inet": "192.168.1.87/24"
}
There are multiple samples provides in the samples/
directory.
When the service registers the device, the service response (JSON) provides node information to the device:
{
"exchange": "http://exchange:3090/v1",
"org": "[email protected]",
"pattern": "",
"node": {
"serial": "042111900396808083fb",
"device": "test-00044bcc4aa6",
"exchange": {
"token": "********",
"name": "test-00044bcc4aa6",
"owner": "[email protected]/[email protected]",
"pattern": "",
"registeredServices": [],
"msgEndPoint": "",
"softwareVersions": {},
"lastHeartbeat": "2019-04-27T00:40:58.904Z[UTC]",
"publicKey": "",
"id": "[email protected]/test-00044bcc4aa6"
},
"token": "e16b73d92d490df288fdfea68406d74935b90124"
},
"date": 1556325659
}
If the pattern
is defined an additional attribute, input
, is defined with the requisite JSON.
Copy this repository, change to the repository directory (e.g. ~/gitdir
), and then the hznsetup
directory; then use the make command; see below:
% mkdir ~/gitdir
% cd ~/gitdir
% git clone https://github.com/dcmartin/open-horizon
% cd open-horizon
% make build
% cd hznsetup
% make start
Once the service is started, it's status can be checked by running the following commnd:
% make check
Which will produce a status result:
{
"hznsetup": {
"nodes": 56,
"date": 1556325635,
"pid": 52
},
"date": 1556325635,
"hzn": {
"agreementid": "175ac3b3a3bb6485f22486fda800ff772b5ac7cfdfb8d698f005d3185e6bcb5a",
"arch": "amd64",
"cpus": 1,
"device_id": "davidsimac.local",
"exchange_url": "http://exchange:3090/v1",
"host_ips": [
"127.0.0.1",
"192.168.1.27",
"192.168.1.26",
"9.80.94.82"
],
"organization": "[email protected]",
"ram": 1024,
"pattern": null
},
"config": {
"tmpdir": "/tmp",
"logto": "/dev/stderr",
"log_level": "info",
"debug": true,
"org": "[email protected]",
"exchange": "http://exchange:3090/v1",
"pattern": "",
"port": 3093,
"db": "https://515bed78-9ddc-408c-bf41-32502db2ddf8-bluemix.cloudant.com",
"username": "515bed78-9ddc-408c-bf41-32502db2ddf8-bluemix",
"pkg": {
"url": "http://pkg.bluehorizon.network/",
"key": "http://pkg.bluehorizon.network/bluehorizon.network-public.key"
},
"basename": "test-",
"approve": "auto",
"vendor": "any",
"services": null
},
"service": {
"label": "hznsetup",
"version": "0.0.1"
}
}
The hznsetup
service is also configured to be run as a pattern in conjunction with the hznmonitor
service, which provides both HTML and CGI interfaces to the exchange and the NoSQL database.
The pattern can only be published once both services have been built for all the supported architectures, pushed to Docker hub (or chosen registry) published to exchange. As these services are dependent on other service containers, notably base-alpine
and apache
, those containers must also be built.
To build and push all service containers for all supported architectures, run the following command (n.b. works on macOS computers that inherently support AMD, ARM, and ARM64 architectures):
% cd ~/gitdir/open-horizon
% make service-build
To publish the hznmonitor
service to the exchange -- and push to the container registry -- run the following commands:
% cd ~/gitdir/open-horizon/hznmonitor
% make service-publish
To publish the hznsetup
service, and push its container, as well as publish the pattern, run the following commands:
% cd ~/gitdir/open-horizon/hznsetup
% make service-publish
% make pattern-publish
With the services and pattern published, the pattern may be deployed to test nodes; note the default test node is the localhost
which requires the Horizon anax
agent to be running; on macOS run the horizon-container start
command); run the following command to create test node(s):
% make nodes
The Web service can be contacted at exposed port on the localhost, for example:
% open http://localhost:3094/
See the hzmonitor
service for more information.
Releases are based on Semantic Versioning, and use the format
of MAJOR.MINOR.PATCH
. In a nutshell, the version will be incremented
based on the following:
MAJOR
: Incompatible or major changes.MINOR
: Backwards-compatible new features and enhancements.PATCH
: Backwards-compatible bugfixes and package updates.