-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdevices.py
342 lines (320 loc) · 13.4 KB
/
devices.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
"""
Part of update set for Resin used by 30MHz
All functions related to managing devices settings. Serving the functions:
- Get device list (UUID): devicelist()
- Check device details (UUID): printdetails()
- Update one device: setbuildinteractive()
- Update an entire application (One by one): updateallinteractive()
A: Fokko
D: 20 Dec 2017
"""
from os import system # for clear
from readchar import readkey # to get a keypress
import operator # for sorting
# Loading Resin Python SDK
from resin import Resin
resin = Resin()
# Helper function to return complete device list from available for this user
def get():
devices = resin.models.device.get_all()
return devices
def get_by_application_id(ID):
try:
devices = resin.models.device.get_all_by_application_id(ID)
except:
print ("Application not found.")
devices = None
return devices
# Helper function to get devices list and sort it on alphabetical order.
def devlist():
devices = get()
devices_uuid = {}
devices_names = {}
for items in devices:
devices_uuid[items["uuid"]] = items
devices_names[items["name"]] = items["uuid"]
devices_names = sorted(devices_names.items(), key=operator.itemgetter(0))
return devices_names
# Helper function to actually print the device list
def printlist(devices_names):
for items in devices_names:
print [items][0][0]
return
# Helper function to actually update a device
def update(UUID, BuildID):
status = resin.models.device.set_to_build('UUID', 'BuildID')
return status
# Helper function to retreive applications name in device details list.
def getApplicationDetails(applicationid):
return resin.models.application.get_by_id(applicationid)["app_name"]
# Helper function to show build details in device details list.
def getBuildDetails(buildid):
if buildid is None:
return "None"
data = resin.models.build.get(buildid["__id"])
details = "\n\n\tBuild ID: \t%s \n\tBuild hash: \t%s \n\tDate: \t\t%s" % (buildid["__id"], data["d"][0]["commit_hash"], data["d"][0]["push_timestamp"])
return details
# Helper function that prints the actual device details
def details(uuid):
data = resin.models.device.get(uuid)
print ("Device name: %s" % data["name"])
print ("ID: %s" % data["id"])
print ("UUID: %s" % data["uuid"])
print
print ("Is online: %s" % data["is_online"])
print ("Last seen: %s" % data["last_connectivity_event"])
print ("Location: %s" % data["location"])
print
print ("Local IP: %s" % data["ip_address"])
print ("Public IP: %s" % data["public_address"])
print
print ("Application: %s" % getApplicationDetails(data["application"]["__id"]))
print ("Build set: %s" % getBuildDetails(data["build"]))
print
print ("Commit: %s" % data["commit"])
print ("OS: %s" % data["os_version"])
print ("Supervisor: %s" % data["supervisor_version"])
print
print ("Created on: %s" % data["created_at"])
return data["application"]["__id"]
# Function 'Get device list (UUID)' that prints all devices in alphabetical order.
def devicelist():
system("clear") # Linux - OSX only :(
for items in devlist():
print ("%s\t%s" % (items[1],items[0]))
raw_input ("Press enter to continue")
# Function 'Check device details (UUID)' that prints device details.
def printdetails():
system("clear") # Linux - OSX only :(
print ("Check device UUID on dashboard or go one step back and select \"Get device list\"")
UUID = raw_input("Input your device UUID: ")
system("clear") # Linux - OSX only :(
try:
details(UUID)
print
print
print "Press a key to continue"
readkey()
except:
print("UUID not corect or device not found. Press a key to continue.")
readkey()
# Helper fucntion to get the application id from a UUID
def getapplicationid(UUID):
return resin.models.device.get(UUID)["application"]["__id"]
# Helper function that shows the print while setting a specific build
def setbuildUI(UUID, BuildHash):
print
print "Setting build:"
print "Device UUID %s" % UUID
appID = getapplicationid(UUID)
print "In application %s" % appID
print "To build hash %s" % BuildHash
try:
from build import getBuildID
BuildID = getBuildID(appID, BuildHash)
print "That is buildnumber %s" % BuildID
setbuild(UUID, BuildID)
print "Setting value: Done"
print
details(UUID)
except:
print "Setting value: failed"
print
print
print "Press a key to continue"
return
# Helper function that actually sets the specific build
def setbuild(UUID, BuildID):
print resin.models.device.set_to_build(UUID, BuildID)
return
# function 'Update one device:' to update one device at a time
def setbuildinteractive():
system("clear") # Linux - OSX only :(
UUID = raw_input("Enter device UUID to update: ")
system("clear") # Linux - OSX only :(
try:
applicationid = details(UUID)
except:
print "Device not found. Press a key to continue."
readkey()
return
print
from build import listAvailableBuilds
listAvailableBuilds(applicationid)
print
COMMIT = raw_input("Enter hash to set: ")
setbuildUI(UUID, COMMIT)
readkey()
# Helper function to fix current software function in build parameter
def setCurrentFixed(UUID):
device = resin.models.device.get(UUID)
from build import getBuildID
buildID = getBuildID(device['application']['__id'],device['commit'])
setbuild(UUID, buildID)
return device['commit']
# u'application': {u'__deferred': {u'uri': u'/resin/application(328080)'}, u'__id': 328080}
# function 'Update an entire application (One by one):' interactively asking to update each device in a application
def updateallinteractive():
from yesorno import query_yes_no
from application import selectapplication, check
ID = selectapplication()
system("clear")
print
if check(ID) == None:
return
print
from build import listAvailableBuilds,getBuildID,getAllBuildHash
listAvailableBuilds(ID)
print
BuildHash = raw_input("Enter build Hash: ")
try:
BuildID = getBuildID(ID, BuildHash)
except:
print "Build not found."
return
devices = get_by_application_id(ID)
system("clear")
print ("Application: %s" % ID)
print ("Build: %s" % BuildID)
print ("Hash: %s" % BuildHash)
# print devices
print "Devices found: {0}".format(len(devices))
print
allcommits = getAllBuildHash(ID)
def printdevices():
print "Commit\t\t\t\t\t\tOnline\tCommit"
for device in devices:
# print device
try:
commit = allcommits[device['build']['__id']]['commit_hash']
except:
commit = "None\t\t\t\t\t"
print "{2}\t{1}\t{0}".format(device['name'], device['is_online'], commit)
printdevices()
print
for device in devices:
# print device
if device['is_online'] == True and device['build'] != None:
# print BuildHash
if BuildHash != None and device['build']['__id'] == BuildID:
print "[{1}]\nSkipping device, it is already at commit {0}".format(BuildHash, device['name'])
else:
# ask user if she wants to update it
if query_yes_no("\n[{0}]\nDo you want to update the device?".format(device['name']),"no"):
setbuild(device['uuid'], BuildID)
# Old call but still handy :)
resin.models.supervisor.update(device['uuid'], device['application']['__id'], force=True)
print
elif device['is_online'] == True and device['build'] == None:
print ("\n[{0}] is online but no build is set. ".format(device['name']))
if query_yes_no("Set current software version as fixed build?","no"):
try:
commit = setCurrentFixed(device['uuid'])
print "Device now set to commit {0}".format(commit)
except:
print "Error fixing current commit! Maybe device switched applications."
else:
print ("\n[{0}] is offline. ".format(device['name']))
if device['build'] == None:
if query_yes_no("And there is not build set. Set current software version as fixed build?","no"):
try:
commit = setCurrentFixed(device['uuid'])
print "Device now set to commit {0}".format(commit)
except:
print "Error fixing current commit! Maybe device switched applications."
else:
print "Skipping device"
print "\n\nDone!"
print "\n\nPress a key to continue."
readkey()
def updateallinteractiveplusvariable():
from yesorno import query_yes_no
from application import selectapplication, check
ID = selectapplication()
system("clear")
print
if check(ID) == None:
return
print
from build import listAvailableBuilds,getBuildID,getAllBuildHash
listAvailableBuilds(ID)
print
BuildHash = raw_input("Enter build Hash: ")
try:
BuildID = getBuildID(ID, BuildHash)
except:
print "Build not found."
return
VariableToSet = raw_input("Enter variable to set: ")
ValueToSet = raw_input("Enter variable value to set: ")
devices = get_by_application_id(ID)
system("clear")
print ("Application: %s" % ID)
print ("Build: %s" % BuildID)
print ("Hash: %s" % BuildHash)
# print devices
print "Devices found: {0}".format(len(devices))
print
allcommits = getAllBuildHash(ID)
def printdevices():
print "Commit\t\t\t\t\t\tOnline\tCommit"
for device in devices:
# print device
try:
commit = allcommits[device['build']['__id']]['commit_hash']
except:
commit = "None\t\t\t\t\t"
print "{2}\t{1}\t{0}".format(device['name'], device['is_online'], commit)
printdevices()
print
for device in devices:
# print device
if device['is_online'] == True and device['build'] != None:
# print BuildHash
if BuildHash != None and device['build']['__id'] == BuildID:
print "[{1}]\nSkipping device, it is already at commit {0}".format(BuildHash, device['name'])
else:
# ask user if she wants to update it
if query_yes_no("\n[{0}]\nDo you want to update the device?".format(device['name']),"no"):
setbuild(device['uuid'], BuildID)
CurrentVariables = resin.models.environment_variables.device.get_all(device['uuid'])
CurrentVariablesNames = {}
for items in CurrentVariables:
CurrentVariablesNames[items['env_var_name']] = items
if VariableToSet in CurrentVariablesNames:
VariableExists = True
print ("Current value of %s = %s" %(VariableToSet, CurrentVariablesNames[VariableToSet]['value']))
else:
VariableExists = False
print ("%s is not set on this device." % VariableToSet)
if query_yes_no("Do you want to set/update this variable?","no"):
if VariableExists:
resin.models.environment_variables.device.update(CurrentVariablesNames[VariableToSet]['id'], ValueToSet)
else:
resin.models.environment_variables.device.create(device['uuid'], VariableToSet, ValueToSet)
# Old call but still handy :)
resin.models.supervisor.update(device['uuid'], device['application']['__id'], force=True)
print
elif device['is_online'] == True and device['build'] == None:
print ("\n[{0}] is online but no build is set. ".format(device['name']))
if query_yes_no("Set current software version as fixed build?","no"):
try:
commit = setCurrentFixed(device['uuid'])
print "Device now set to commit {0}".format(commit)
except:
print "Error fixing current commit! Maybe device switched applications."
else:
print ("\n[{0}] is offline. ".format(device['name']))
if device['build'] == None:
if query_yes_no("And there is not build set. Set current software version as fixed build?","no"):
try:
commit = setCurrentFixed(device['uuid'])
print "Device now set to commit {0}".format(commit)
except:
print "Error fixing current commit! Maybe device switched applications."
else:
print "Skipping device"
print "\n\nDone!"
print "\n\nPress a key to continue."
readkey()