blob: e68dcf7c06b2bfc4853e81985d8700484e9bb2b1 [file] [log] [blame]
Norman James3d6a06f2016-01-30 13:03:45 -06001#!/usr/bin/python -u
2
3import gobject
4import dbus
5import dbus.service
6import dbus.mainloop.glib
7import Openbmc
8import shutil
9import tarfile
10
11DBUS_NAME = 'org.openbmc.control.BmcFlash'
12OBJ_NAME = '/org/openbmc/control/flash/bmc'
13FLASH_INTF = 'org.openbmc.Flash'
14DOWNLOAD_INTF = 'org.openbmc.managers.Download'
15
16UPDATE_PATH = '/run/initramfs'
17
18
19def doExtract(members,files):
20 for tarinfo in members:
21 if files.has_key(tarinfo.name) == True:
22 yield tarinfo
23
24
25class BmcFlashControl(Openbmc.DbusProperties,Openbmc.DbusObjectManager):
26 def __init__(self,bus,name):
27 self.dbus_objects = { }
28 Openbmc.DbusProperties.__init__(self)
29 Openbmc.DbusObjectManager.__init__(self)
30 dbus.service.Object.__init__(self,bus,name)
31
32 self.Set(DBUS_NAME,"status","Idle")
33 self.Set(DBUS_NAME,"filename","")
34 self.Set(DBUS_NAME,"preserve_network_settings",False)
35 self.Set(DBUS_NAME,"restore_application_defaults",False)
36 self.Set(DBUS_NAME,"update_kernel_and_apps_only",False)
37
38 bus.add_signal_receiver(self.download_error_handler,signal_name = "DownloadError")
39 bus.add_signal_receiver(self.download_complete_handler,signal_name = "DownloadComplete")
40
41 self.InterfacesAdded(name,self.properties)
42
43
44 @dbus.service.method(DBUS_NAME,
45 in_signature='ss', out_signature='')
46 def updateViaTftp(self,ip,filename):
47 self.TftpDownload(ip,filename)
48 self.Set(DBUS_NAME,"status","Downloading")
49
50 @dbus.service.signal(DOWNLOAD_INTF,signature='ss')
51 def TftpDownload(self,ip,filename):
52 self.Set(DBUS_NAME,"filename",filename)
53 pass
54
55
56 ## Signal handler
57 def download_error_handler(self,filename):
58 if (filename == self.Get(DBUS_NAME,"filename")):
59 self.Set(DBUS_NAME,"status","Download Error")
60
61 def download_complete_handler(self,outfile,filename):
62 ## do update
63 if (filename != self.Get(DBUS_NAME,"filename")):
64 return
65
66 print "Download complete. Updating..."
67
68 self.Set(DBUS_NAME,"status","Download Complete")
69 copy_files = {}
70
71 ## determine needed files
72 if (self.Get(DBUS_NAME,"update_kernel_and_apps_only") == False):
73 copy_files["image-bmc"] = True
74 else:
75 copy_files["image-kernel"] = True
76 copy_files["image-initramfs"] = True
77 copy_files["image-rofs"] = True
78
79 if (self.Get(DBUS_NAME,"restore_application_defaults") == True):
80 copy_files["image-rofs"] = True
81
82
83 ## make sure files exist in archive
84 try:
85 tar = tarfile.open(outfile,"r")
86 files = {}
87 for f in tar.getnames():
88 files[f] = True
89 tar.close()
90 for f in copy_files.keys():
91 if (files.has_key(f) == False):
92 raise Exception("ERROR: File not found in update archive: "+f)
93
94 except Exception as e:
95 print e
96 self.Set(DBUS_NAME,"status","Update Error")
97 return
98
99 try:
100 tar = tarfile.open(outfile,"r")
101 tar.extractall(UPDATE_PATH,members=doExtract(tar,copy_files))
102 tar.close()
103
104 if (self.Get(DBUS_NAME,"preserve_network_settings") == True):
105 shutil.copy2("/dev/mtd2",UPDATE_PATH+"image-u-boot-env")
106
107 except Exception as e:
108 print e
109 self.Set(DBUS_NAME,"status","Update Error")
110
111
112
113 self.Set(DBUS_NAME,"status","Update Success. Please reboot.")
114
115
116if __name__ == '__main__':
117 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
118
119 bus = Openbmc.getDBus()
120 name = dbus.service.BusName(DBUS_NAME, bus)
121 obj = BmcFlashControl(bus, OBJ_NAME)
122 mainloop = gobject.MainLoop()
123
124 print "Running Bmc Flash Control"
125 mainloop.run()
126