4 from optparse import OptionParser
7 #from BeautifulSoup import *
15 import subprocess as sub
18 update_repo="http://www.planux.com/updates"
19 update_cache="/var/cache/updatemanager"
22 class FakeSecHead(object):
23 def __init__(self, fp):
25 self.sechead = '[os-release]\n'
28 try: return self.sechead
29 finally: self.sechead = None
30 else: return self.fp.readline()
32 def get_current_version():
33 config = ConfigParser.SafeConfigParser()
34 config.readfp(FakeSecHead(open('/etc/os-release')))
35 return dict(config.items('os-release'))
38 def checksum(fileName, checksum_type="sha256", excludeLine="", includeLine=""):
39 """Compute sha256 hash of the specified file"""
41 if checksum_type == "md5":
45 fd = open(fileName,"rb")
47 print "Unable to open the file in readmode:", filename
49 content = fd.readlines()
51 for eachLine in content:
52 if excludeLine and eachLine.startswith(excludeLine):
60 print "Checking for new updates..."
61 response = urllib2.urlopen("%s/data/updatemd.xml" % update_repo )
62 updatemd = response.read()
63 if not os.path.exists("%s/download/metadata" %update_cache):
64 os.mkdir("%s/download/metadata" %update_cache)
66 fp = open("%s/download/metadata/updatemd.xml" % update_cache , "w")
70 updatemd_local = open("%s/download/metadata/updatemd.xml" % update_cache )
71 root = etree.XML(updatemd_local.read())
72 data = root.xpath("//data[@type='updates']")[0]
73 loc = data.xpath("location")[0]
74 href = loc.attrib['href']
75 chksum = data.xpath("checksum")[0]
76 chksum_type = chksum.attrib['type']
78 if os.path.exists("%s/download/metadata/updates.xml" % update_cache):
79 cur_sum = checksum("%s/download/metadata/updates.xml" % update_cache, checksum_type=chksum_type)
80 if cur_sum == chksum.text:
81 print "Using file from cache, no new updates on server."
83 print "Fetching new updates..."
84 get_new_update_list(href)
86 get_new_update_list(href)
92 fp = open("%s/download/metadata/updates.xml" % update_cache , "r")
93 updates_root = etree.XML(fp.read())
94 updates_el = updates_root.xpath("//update")
95 for update in updates_el:
99 up['checksum'] = update.xpath("checksum")[0].text
100 up['title'] = update.xpath("title")[0].text
101 loc = update.xpath("location")[0]
102 up['location'] = "%s" % ( loc.attrib['href'])
104 updates[up['id']] = up
108 def download_update(update_data):
110 location = u['location']
111 if not os.path.exists("%s/download" % (update_cache)):
112 os.mkdir("%s/download" % (update_cache))
113 if not os.path.exists("%s/download/%s/download_done" % (update_cache, u['id'] )):
114 print "Downloading %s/%s" % (update_repo, location)
115 update_file = urllib2.urlopen("%s/%s" % (update_repo, location) )
116 location = os.path.basename(location)
117 announced_csum = u['checksum']
118 update_raw = update_file.read()
119 fp = open("%s/download/%s" % (update_cache,location) , "w")
122 downloaded_csum = checksum("%s/download/%s" % (update_cache,location), "sha256")
124 if downloaded_csum != announced_csum:
125 print "Error: Checksum mismatch"
126 os.remove("%s/download/%s" % (update_cache,location))
128 print "%s already downloaded" % location
130 def download_all_updates(update_label=None):
131 updates = parse_updates()
133 if update_label is not None:
134 u = updates[update_label]
137 for k in updates.keys():
142 def get_new_update_list(location):
143 up = urllib2.urlopen("%s/%s" % (update_repo, location) )
145 update_raw = up.read()
146 fp = open("%s/download/metadata/updates.xml.gz" % update_cache , "w")
149 f = gzip.open("%s/download/metadata/updates.xml.gz" % update_cache, 'rb')
150 file_content = f.read()
152 fp = open("%s/download/metadata/updates.xml" % update_cache , "w")
153 fp.write(file_content)
158 #distutils.archive_util.make_zipfile(base_name, base_dir[, verbose=0, dry_run=0])
162 from zipfile_infolist import print_info
166 compression = zipfile.ZIP_DEFLATED
168 compression = zipfile.ZIP_STORED
170 modes = { zipfile.ZIP_DEFLATED: 'deflated',
171 zipfile.ZIP_STORED: 'stored',
174 print 'creating update archive'
175 zf = zipfile.ZipFile('%s.zip' %target, mode='w')
177 print 'adding README.txt with compression mode', modes[compression]
178 zf.write('README.txt', compress_type=compression)
184 print_info('%s.zip' %target)
186 def unpack(location, update_id):
187 #os.mkdir("%s/download/%s" %(update_cache, update_id))
188 zfile = zipfile.ZipFile("%s/download/%s/%s" % (update_cache,update_id, location))
189 for name in zfile.namelist():
190 (dirname, filename) = os.path.split(name)
191 print "Decompressing " + filename + " on " + dirname
192 if not os.path.exists("%s/download/%s/%s" % (update_cache, update_id, dirname)):
193 os.mkdir("%s/download/%s/%s" % (update_cache, update_id, dirname))
195 fd = open("%s/download/%s/%s" % (update_cache, update_id, name),"w")
196 fd.write(zfile.read(name))
199 os.rename("%s/download/%s/%s" % (update_cache,update_id, update_id), "%s/download/%s/content" % (update_cache,update_id))
202 def prepare_update(update_data, download):
204 location = u['location']
207 if os.path.exists("%s/download/%s" % (update_cache,update_id)) and not os.path.exists("%s/download/%s/content" % (update_cache,update_id)):
208 print "Unpacking %s" %location
209 unpack(location, update_id)
211 print "Update %s already unpacked" % update_id
213 repodir = "%s/repos.d" %update_cache
214 repourl = "file://%s/download/%s/content" % (update_cache, update_id)
215 if not os.path.exists("%s/%s.repo" % (repourl, update_id)):
216 os.system("zypper --quiet --reposd-dir %s ar --no-gpgcheck --no-keep-packages %s %s" %(repodir, repourl, update_id))
218 os.system("zypper --quiet --non-interactive --reposd-dir %s patch --repo %s -d" % (repodir, update_id) )
220 def install_update(update_data):
222 location = u['location']
225 if not os.path.exists("%s/download/%s/content" % (update_cache,update_id)):
226 prepare_update(update_data, False)
228 repodir = "%s/repos.d" %update_cache
229 repourl = "file://%s/download/%s/content" % (update_cache, update_id)
230 if not os.path.exists("%s/%s.repo" % (repodir, update_id)):
231 os.system("zypper --quiet --reposd-dir %s ar --no-gpgcheck --no-keep-packages %s %s" %(repodir, repourl, update_id))
232 print "zypper -n --reposd-dir %s patch --with-interactive --repo %s " % (repodir, update_id)
233 os.system("zypper -n --reposd-dir %s patch --with-interactive --repo %s " % (repodir, update_id) )
234 if not os.path.exists("%s/installed" % (update_cache)):
235 os.mkdir("%s/installed" % (update_cache))
236 shutil.copyfile("%s/download/%s/content/%s" %(update_cache, update_id, update_id), "%s/installed/%s" % (update_cache, update_id))
238 print "Finished installing %s." % update_id
239 for line in fileinput.input("/etc/os-release", inplace=1):
240 print line.replace(current_version, u["version"]),
241 for line in fileinput.input("/etc/tizen-release", inplace=1):
242 print line.replace(current_version, u["version"]),
244 def apply_update(update_data):
248 updates = parse_updates()
249 for k in updates.keys():
251 installed = "%s/installed/%s" % (update_cache, u['id'])
252 if not os.path.exists(installed):
254 print " %s" %u['title']
257 parser = OptionParser()
258 parser.add_option("-V", "--os-version", action="store_true", dest="osver", default=False,
259 help="Current OS Version")
261 parser.add_option("-l", "--list-updates", action="store_true", dest="listupdates", default=False,
264 parser.add_option("-d", "--download-only", action="store_true", dest="downloadonly", default=False,
265 help="Download only")
267 parser.add_option("-i", "--install", dest="install", metavar="LABEL",
268 help="Install update")
270 parser.add_option("-p", "--prepare", dest="prepare", metavar="LABEL",
271 help="Prepare update")
273 parser.add_option("-a", "--install-all", dest="installall", action="store_true", default=False,
274 help="Install all updates")
276 parser.add_option("-P", "--prepare-all", dest="prepareall", action="store_true", default=False,
277 help="prepare update")
279 parser.add_option("-r", "--recommended", dest="recommended", action="store_true", default=False,
280 help="Install recommended updates only")
282 parser.add_option("-q", "--quiet",
283 action="store_false", dest="verbose", default=True,
284 help="don't print status messages to stdout")
286 (options, args) = parser.parse_args()
288 if not os.path.exists(update_cache):
289 os.mkdir("%s" % update_cache)
290 if not os.path.exists("%s/download" % update_cache):
291 os.mkdir("%s/download" % update_cache)
292 os.mkdir("%s/download/metadata" % update_cache)
294 if not os.path.exists("%s/repos.d" % update_cache):
295 os.mkdir("%s/repos.d" % update_cache)
298 os_release = get_current_version()
299 print os_release['version_id'].strip('"')
301 if options.listupdates:
305 if options.downloadonly:
307 download_all_updates()
309 if options.prepare is not None:
311 updates = parse_updates()
312 if not updates.has_key(options.prepare):
313 print "%s is not available for installation. Abort." %options.prepare
315 u = updates[options.prepare]
317 prepare_update(u, False)
319 if options.install is not None:
321 updates = parse_updates()
322 if not updates.has_key(options.install):
323 print "%s is not available for installation. Abort." %options.install
325 u = updates[options.install]