Registration and Update deployment is a common use-case that might be useful for several scenarios, for such cases we created a script by using our REST API to register the device and deploy an update at the same time.
For example, If you would like to make sure that all devices registered to your fleet are automatically updated with the latest software, or, some kind of configuration that initiates after a successful factory reset.
Instead of registering the device via the installation command or a pre-made image, we will use a Python script on the device that will register and deploy an update to itself.
Copy import requests
import subprocess
import os
import json
import time
# ----------------------------#
# Needed to be edit per user before running
USER_TOKEN = ""
PROJECT_NAME = ""
UPDATE_FLOW_ID = ""
# ----------------------------#
# Don't touch - will be added automatically by the script
DEVICE_TOKEN = ""
DEVICE_UUID = ""
# Don't touch - static paths and URLs
INSTALLATION_URL = """su -c 'wget -O - https://connect.jfrog.io/v2/install_connect | sh -s {} {} '"""
CONNECT_AGENT_PATH = "/etc/connect/service/ConnectAgent"
AGENT_FLAG_TO_GET_DEVICE_TOKEN = "--print-token"
DEPLOY_UPDATE_API_URL = "https://api.connect.jfrog.io/v2/deploy_update"
GET_DEVICE_DETAILS_API_URL = "https://api.connect.jfrog.io/v1/devices_details"
def is_connect_agent_exist_on_device ():
return os . path . exists (CONNECT_AGENT_PATH)
def install_connect_agent ( user_token , project_name ):
final_installation_url = INSTALLATION_URL . format (user_token, project_name)
subprocess . check_output (final_installation_url, shell = True )
print ( "waiting 2 minutes before continuing the process..." )
time . sleep ( 120 )
def get_device_token ():
device_token = subprocess . check_output (CONNECT_AGENT_PATH + " " + AGENT_FLAG_TO_GET_DEVICE_TOKEN, shell = True )
return device_token . decode ( 'ascii' )
def get_device_uuid ( user_token , project_name , device_token ):
json_content = { 'project_name' : project_name ,
'group_name' : 'Production' ,
'user_token' : user_token ,
'device_token' : device_token }
call_request = requests . get (GET_DEVICE_DETAILS_API_URL, json = json_content)
call_response = json . loads (call_request.text)
return call_response [ "message" ] [ 0 ][ "device_uuid" ]
def deploy_update_flow ( update_flow_id , user_token , project_name , device_uuid ):
print ( "deploying update flow {} on device {} ...." . format (update_flow_id, device_uuid))
json_content = { 'user_token' : user_token ,
'metadata' : { 'comment' : 'deploy app v1' ,
'app' : { 'name' : 'app' , 'version' : 'v1' }},
'deployment_configuration' : {
'flow_id' : update_flow_id }
'devices_filter' : { 'project' : { 'name' : project_name },
'groups' : [ { 'name' : 'production' } ] ,
'filters' : [ { 'type' : 'specific_device' ,
'operand' : 'is' ,
'value' : device_uuid } ] }
}
call_request = requests . post (DEPLOY_UPDATE_API_URL, json = json_content)
call_response = json . loads (call_request.text)
if call_request . status_code == 200 :
print ( "process finished successfully" )
else :
if call_request . status_code == 429 :
error = "API limit reached"
else :
error = call_response [ "error_message" ]
print (error)
if __name__ == '__main__' :
if not is_connect_agent_exist_on_device ():
if USER_TOKEN and PROJECT_NAME and UPDATE_FLOW_ID :
install_connect_agent (USER_TOKEN, PROJECT_NAME)
else :
print (
"one or all of the required parameters - user token, project name and update flow id were not provided, make sure to edit the script before running again" )
exit ( 1 )
else :
print ( "JFrog Connect is already installed on device" )
if not DEVICE_TOKEN :
DEVICE_TOKEN = get_device_token ()
if not DEVICE_UUID :
DEVICE_UUID = get_device_uuid (USER_TOKEN, PROJECT_NAME, DEVICE_TOKEN)
deploy_update_flow (UPDATE_FLOW_ID, USER_TOKEN, PROJECT_NAME, DEVICE_UUID)
2. Copy the script to the device
3. Choose when the script would run, some prefer having it running after the next power-on, while others initiate it with their on-device application.