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
|
# MetaRelease.py
#
# Copyright (c) 2004,2005 Canonical
#
# Author: Michael Vogt <michael.vogt@ubuntu.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
import thread
import urllib2
import os
import string
import apt_pkg
import time
import sys
import rfc822
from subprocess import Popen,PIPE
class Dist(object):
def __init__(self, name, version, date, supported):
self.name = name
self.version = version
self.date = date
self.supported = supported
self.releaseNotesURI = None
self.upgradeTool = None
self.upgradeToolSig = None
class MetaReleaseCore(object):
# some constants
METARELEASE_URI = "http://changelogs.ubuntu.com/meta-release"
METARELEASE_URI_UNSTABLE = "http://changelogs.ubuntu.com/meta-release-development"
METARELEASE_URI_PROPOSED = "http://changelogs.ubuntu.com/meta-release-proposed"
METARELEASE_FILE = "/var/lib/update-manager/meta-release"
def __init__(self, useDevelopmentRelease=False, useProposed=False):
# check what uri to use
if useDevelopmentRelease:
self.METARELEASE_URI = self.METARELEASE_URI_UNSTABLE
elif useProposed:
self.METARELEASE_URI = self.METARELEASE_URI_PROPOSED
# check if we can write to the global location, if not,
# write to homedir
try:
open(self.METARELEASE_FILE,"a")
except IOError, e:
path = os.path.expanduser("~/.update-manager-core/")
if not os.path.exists(path):
os.mkdir(path)
self.METARELEASE_FILE = os.path.join(path,"meta-release")
self.metarelease_information = None
self.downloading = True
# information about the available dists
self.new_dist = None
self.no_longer_supported = None
# we start the download thread here and we have a timeout
t=thread.start_new_thread(self.download, ())
#t=thread.start_new_thread(self.check, ())
def dist_no_longer_supported(self, dist):
""" virtual function that is called when the distro is no longer
supported
"""
self.no_longer_supported = dist
def new_dist_available(self, dist):
""" virtual function that is called when a new distro release
is available
"""
self.new_dist = dist
def get_dist(self):
" return the codename of the current runing distro "
p = Popen(["lsb_release","-c","-s"],stdout=PIPE)
res = p.wait()
if res != 0:
sys.stderr.write("lsb_release returned exitcode: %i\n" % res)
return "unknown distribution"
dist = string.strip(p.stdout.readline())
return dist
def parse(self):
#print "parse"
current_dist_name = self.get_dist()
current_dist = None
dists = []
# parse the metarelease_information file
index_tag = apt_pkg.ParseTagFile(self.metarelease_information)
step_result = index_tag.Step()
while step_result:
if index_tag.Section.has_key("Dist"):
name = index_tag.Section["Dist"]
#print name
rawdate = index_tag.Section["Date"]
date = time.mktime(rfc822.parsedate(rawdate))
supported = bool(index_tag.Section["Supported"])
version = index_tag.Section["Version"]
# add the information to a new date object
dist = Dist(name, version, date,supported)
if index_tag.Section.has_key("ReleaseNotes"):
dist.releaseNotesURI = index_tag.Section["ReleaseNotes"]
if index_tag.Section.has_key("UpgradeTool"):
dist.upgradeTool = index_tag.Section["UpgradeTool"]
if index_tag.Section.has_key("UpgradeToolSignature"):
dist.upgradeToolSig = index_tag.Section["UpgradeToolSignature"]
dists.append(dist)
if name == current_dist_name:
current_dist = dist
step_result = index_tag.Step()
# first check if the current runing distro is in the meta-release
# information. if not, we assume that we run on something not
# supported and silently return
if current_dist == None:
print "current dist not found in meta-release file"
return False
# then see what we can upgrade to (only upgrade to supported dists)
upgradable_to = ""
for dist in dists:
if dist.date > current_dist.date and dist.supported == True:
upgradable_to = dist
#print "new dist: %s" % upgradable_to
break
# only warn if unsupported and a new dist is available (because
# the development version is also unsupported)
if upgradable_to != "" and not current_dist.supported:
self.dist_no_longer_supported(upgradabl_to)
elif upgradable_to != "":
self.new_dist_available(upgradable_to)
# parsing done and sucessfully
return True
# the network thread that tries to fetch the meta-index file
# can't touch the gui, runs as a thread
def download(self):
#print "download"
lastmodified = 0
req = urllib2.Request(self.METARELEASE_URI)
# make sure that we always get the latest file (#107716)
req.add_header("Cache-Control", "No-Cache")
req.add_header("Pragma", "no-cache")
if os.access(self.METARELEASE_FILE, os.W_OK):
lastmodified = os.stat(self.METARELEASE_FILE).st_mtime
if lastmodified > 0:
req.add_header("If-Modified-Since", time.asctime(time.gmtime(lastmodified)))
try:
uri=urllib2.urlopen(req)
# sometime there is a root owned meta-relase file
# there, try to remove it so that we get it
# with proper permissions
if (os.path.exists(self.METARELEASE_FILE) and
not os.access(self.METARELEASE_FILE,os.W_OK)):
try:
os.unlink(self.METARELEASE_FILE)
except OSError,e:
print "Can't unlink '%s' (%s)" % (self.METARELEASE_FILE,e)
f=open(self.METARELEASE_FILE,"w+")
for line in uri.readlines():
f.write(line)
f.flush()
f.seek(0,0)
self.metarelease_information=f
uri.close()
except urllib2.URLError:
if os.path.exists(self.METARELEASE_FILE):
self.metarelease_information=open(self.METARELEASE_FILE,"r")
# now check the information we have
if self.metarelease_information != None:
self.parse()
self.downloading = False
|