blob: 9fa54ac6eba24791ae5069c4cb1fc20803d3c0bd [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
Norman James3d6a06f2016-01-30 13:03:45 -06007import shutil
8import tarfile
Norman James8a65a542016-02-03 19:04:44 -06009import os
Brad Bishop84e73b52016-05-12 15:57:52 -040010from obmc.dbuslib.bindings import get_dbus, DbusProperties, DbusObjectManager
Norman James3d6a06f2016-01-30 13:03:45 -060011
12DBUS_NAME = 'org.openbmc.control.BmcFlash'
13OBJ_NAME = '/org/openbmc/control/flash/bmc'
14FLASH_INTF = 'org.openbmc.Flash'
15DOWNLOAD_INTF = 'org.openbmc.managers.Download'
16
17UPDATE_PATH = '/run/initramfs'
18
19
20def doExtract(members,files):
21 for tarinfo in members:
22 if files.has_key(tarinfo.name) == True:
23 yield tarinfo
24
25
Brad Bishop84e73b52016-05-12 15:57:52 -040026class BmcFlashControl(DbusProperties,DbusObjectManager):
Norman James3d6a06f2016-01-30 13:03:45 -060027 def __init__(self,bus,name):
28 self.dbus_objects = { }
Brad Bishop84e73b52016-05-12 15:57:52 -040029 DbusProperties.__init__(self)
30 DbusObjectManager.__init__(self)
Norman James3d6a06f2016-01-30 13:03:45 -060031 dbus.service.Object.__init__(self,bus,name)
32
33 self.Set(DBUS_NAME,"status","Idle")
34 self.Set(DBUS_NAME,"filename","")
35 self.Set(DBUS_NAME,"preserve_network_settings",False)
36 self.Set(DBUS_NAME,"restore_application_defaults",False)
Norman James8a65a542016-02-03 19:04:44 -060037 self.Set(DBUS_NAME,"update_kernel_and_apps",False)
38 self.Set(DBUS_NAME,"clear_persistent_files",False)
Norman James3d6a06f2016-01-30 13:03:45 -060039
40 bus.add_signal_receiver(self.download_error_handler,signal_name = "DownloadError")
41 bus.add_signal_receiver(self.download_complete_handler,signal_name = "DownloadComplete")
42
43 self.InterfacesAdded(name,self.properties)
44
45
46 @dbus.service.method(DBUS_NAME,
47 in_signature='ss', out_signature='')
48 def updateViaTftp(self,ip,filename):
49 self.TftpDownload(ip,filename)
50 self.Set(DBUS_NAME,"status","Downloading")
51
Chris Austenea5b4012016-05-20 16:41:40 -050052 @dbus.service.method(DBUS_NAME,
53 in_signature='s', out_signature='')
54 def update(self,filename):
55 self.Set(DBUS_NAME,"filename",filename)
56 self.download_complete_handler(filename, filename)
57
Norman James3d6a06f2016-01-30 13:03:45 -060058 @dbus.service.signal(DOWNLOAD_INTF,signature='ss')
59 def TftpDownload(self,ip,filename):
60 self.Set(DBUS_NAME,"filename",filename)
61 pass
62
63
64 ## Signal handler
65 def download_error_handler(self,filename):
66 if (filename == self.Get(DBUS_NAME,"filename")):
67 self.Set(DBUS_NAME,"status","Download Error")
68
69 def download_complete_handler(self,outfile,filename):
70 ## do update
71 if (filename != self.Get(DBUS_NAME,"filename")):
72 return
73
74 print "Download complete. Updating..."
75
76 self.Set(DBUS_NAME,"status","Download Complete")
77 copy_files = {}
78
79 ## determine needed files
Norman James8a65a542016-02-03 19:04:44 -060080 if (self.Get(DBUS_NAME,"update_kernel_and_apps") == False):
Norman James3d6a06f2016-01-30 13:03:45 -060081 copy_files["image-bmc"] = True
82 else:
83 copy_files["image-kernel"] = True
84 copy_files["image-initramfs"] = True
85 copy_files["image-rofs"] = True
86
87 if (self.Get(DBUS_NAME,"restore_application_defaults") == True):
Norman James8a65a542016-02-03 19:04:44 -060088 copy_files["image-rwfs"] = True
Norman James3d6a06f2016-01-30 13:03:45 -060089
90
91 ## make sure files exist in archive
92 try:
93 tar = tarfile.open(outfile,"r")
94 files = {}
95 for f in tar.getnames():
96 files[f] = True
97 tar.close()
98 for f in copy_files.keys():
99 if (files.has_key(f) == False):
100 raise Exception("ERROR: File not found in update archive: "+f)
101
102 except Exception as e:
103 print e
104 self.Set(DBUS_NAME,"status","Update Error")
105 return
106
107 try:
108 tar = tarfile.open(outfile,"r")
109 tar.extractall(UPDATE_PATH,members=doExtract(tar,copy_files))
110 tar.close()
Norman James8a65a542016-02-03 19:04:44 -0600111
Adi Gangidi4d27c1b2016-05-11 18:27:43 -0500112 if (self.Get(DBUS_NAME,"clear_persistent_files") == True):
Norman James8a65a542016-02-03 19:04:44 -0600113 print "Removing persistent files"
114 os.unlink(UPDATE_PATH+"/whitelist")
Norman James3d6a06f2016-01-30 13:03:45 -0600115 if (self.Get(DBUS_NAME,"preserve_network_settings") == True):
Norman James8a65a542016-02-03 19:04:44 -0600116 print "Preserving network settings"
Adi Gangidi0850b872016-05-11 18:19:06 -0500117 shutil.copy2("/dev/mtd2",UPDATE_PATH+"/image-u-boot-env")
Norman James3d6a06f2016-01-30 13:03:45 -0600118
119 except Exception as e:
120 print e
121 self.Set(DBUS_NAME,"status","Update Error")
122
123
124
125 self.Set(DBUS_NAME,"status","Update Success. Please reboot.")
126
127
128if __name__ == '__main__':
129 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
130
Brad Bishop84e73b52016-05-12 15:57:52 -0400131 bus = get_dbus()
Norman James3d6a06f2016-01-30 13:03:45 -0600132 name = dbus.service.BusName(DBUS_NAME, bus)
133 obj = BmcFlashControl(bus, OBJ_NAME)
134 mainloop = gobject.MainLoop()
135
136 print "Running Bmc Flash Control"
137 mainloop.run()
138