incremental
[platform/upstream/swup.git] / swup.py
1 #!/usr/bin/python
2
3 import ConfigParser
4 from optparse import OptionParser
5 import urllib2
6 from lxml import etree
7 from BeautifulSoup import *
8 import hashlib
9 import os
10 import tempfile
11 import shutil
12
13 update_repo="file:///home/nashif/system-updates/repo"
14 update_cache="/tmp/updates"
15
16
17
18 class FakeSecHead(object):
19     def __init__(self, fp):
20         self.fp = fp
21         self.sechead = '[os-release]\n'
22     def readline(self):
23         if self.sechead:
24             try: return self.sechead
25             finally: self.sechead = None
26         else: return self.fp.readline()
27
28 def get_current_version():
29     config = ConfigParser.SafeConfigParser()
30     config.readfp(FakeSecHead(open('/etc/os-release')))
31     return dict(config.items('os-release'))
32
33  
34 def checksum(fileName, checksum_type="sha256", excludeLine="", includeLine=""):
35     """Compute sha256 hash of the specified file"""
36     m = hashlib.sha256()
37     if checksum_type == "md5":
38         m = hashlib.md5()
39
40     try:
41         fd = open(fileName,"rb")
42     except IOError:
43         print "Unable to open the file in readmode:", filename
44         return
45     content = fd.readlines()
46     fd.close()
47     for eachLine in content:
48         if excludeLine and eachLine.startswith(excludeLine):
49             continue
50         m.update(eachLine)
51     m.update(includeLine)
52     return m.hexdigest()
53
54
55 def probe_updates():
56     print "Checking for new updates..."
57     response = urllib2.urlopen("%s/data/updatemd.xml" % update_repo )
58     updatemd = response.read()
59     if not os.path.exists("%s/data" %update_cache):
60         os.mkdir("%s/data" %update_cache)
61
62     fp = open("%s/data/updatemd.xml" % update_cache , "w")
63     fp.write(updatemd)
64     fp.close()
65
66     updatemd_local = open("%s/data/updatemd.xml" % update_cache )
67     root = etree.XML(updatemd_local.read())
68     data = root.xpath("//data[@type='update']")[0]
69     loc = data.xpath("location")[0]
70     href = loc.attrib['href']
71     chksum = data.xpath("checksum")[0]
72     chksum_type = chksum.attrib['type']
73     
74     if os.path.exists("%s/data/updates.xml" % update_cache):
75         cur_sum = checksum("%s/data/updates.xml" % update_cache, checksum_type=chksum_type) 
76         if cur_sum ==  chksum.text:
77             print "Using file from cache, no new updates on server."
78         else:
79             print "Fetching new updates..."
80             get_new_update_list(href)
81     else:
82         get_new_update_list(href)
83
84     
85
86 def get_new_update_list(location):
87     up = urllib2.urlopen("%s/%s" % (update_repo, location) )
88     update_raw = up.read()
89     fp = open("%s/data/updates.xml" % update_cache , "w")
90     fp.write(update_raw)
91     fp.close()
92
93
94 def list_updates():
95     fp = open("%s/data/updates.xml" % update_cache , "r")
96     updates_root = etree.XML(fp.read())
97     updates = updates_root.xpath("//update")
98     for update in updates:
99         attr = update.attrib
100         print "  %s:" %attr['id']
101         print "       %s" %update.xpath("title")[0].text
102
103
104
105
106 parser = OptionParser()
107 parser.add_option("-V", "--os-version", action="store_true", dest="osver", default=False,
108                   help="Current OS Version")
109 parser.add_option("-l", "--list-updates", action="store_true", dest="listupdates", default=False,
110                   help="List updates")
111 parser.add_option("-d", "--download-only", action="store_true", dest="downloadonly", default=False,
112                   help="Download only")
113 parser.add_option("-i", "--install",  dest="install", metavar="LABEL",
114                   help="Install update")
115 parser.add_option("-r", "--recommended",  dest="recommended", action="store_true", default=False,
116                   help="Install recommended updates only")
117 parser.add_option("-q", "--quiet",
118                   action="store_false", dest="verbose", default=True,
119                   help="don't print status messages to stdout")
120
121 (options, args) = parser.parse_args()
122
123 if options.osver:
124     os_release = get_current_version()
125     print os_release['version_id'].strip('"')
126
127 if options.listupdates:
128     probe_updates()
129     list_updates()