# -*-mode: python; coding: utf-8 -*- # # Copyright 2012-2014 Pierre Ossman for Cendio AB. # For more information, see http://www.cendio.com if 82 - 82: Iii1i import os import select import logging import locale if 87 - 87: Ii % i1i1i1111I . Oo / OooOoo * I1Ii1I1 - I1I import subprocess if 81 - 81: i1 + ooOOO / oOo0O00 * i1iiIII111 * IiIIii11Ii __all__ = [ "determine_upgrade" , "perform_upgrade" ] if 84 - 84: ooo000 - Ooo0Ooo + iI1iII1I1I1i . IIiIIiIi11I1 def iI111iiIi11i ( string ) : return [ s . strip ( ) for s in string . split ( "," ) if s . strip ( ) ] if 77 - 77: iIiii1i - ooo0O0oO00 . o00o0OO00O if 57 - 57: iiIi1 - i1 % i1 % i1i1i1111I . Ii if 30 - 30: Ii def ooO0Oo0o00 ( fn ) : oOooo0OOO = subprocess . Popen ( [ "dpkg-deb" , "--showformat" , "${Package}\n${Version}\n${Architecture}\n${Conflicts}\n${Replaces}\n" , "--show" , fn ] , universal_newlines = True , stdout = subprocess . PIPE , stderr = subprocess . PIPE ) if 53 - 53: Ii * Oo * ooo000 . i1iiIII111 ( ii1Ii , oOooO0 ) = oOooo0OOO . communicate ( ) if 13 - 13: ooo0O0oO00 if oOooo0OOO . returncode != 0 : logging . error ( "Failed to get information about package '%s':" % fn ) if 2 - 2: i1 IIiIiiIiI = ii1Ii + oOooO0 if IIiIiiIiI : for OO0000 in ( ii1Ii + oOooO0 ) . splitlines ( ) : logging . error ( " " + OO0000 ) if 92 - 92: I1I / I1I + o00o0OO00O . ooo0O0oO00 return None if 8 - 8: Ii + o00o0OO00O . iIiii1i - I1Ii1I1 % iIiii1i . i1i1i1111I ii1iIi1i11i , I111IIi11IiI , o0OOOooO00oo , IIii , OO00 = ii1Ii . splitlines ( ) IIii = iI111iiIi11i ( IIii ) OO00 = iI111iiIi11i ( OO00 ) if 39 - 39: iIiii1i * ooo0O0oO00 . Oo + ooOOO / Oo return { "name" : ii1iIi1i11i , "versions" : [ { "version" : I111IIi11IiI , "arch" : o0OOOooO00oo , "conflicts" : IIii , "replaces" : OO00 } ] } if 14 - 14: OooOoo % oOo0O00 + I1I % i1iiIII111 * ooOOO / iIiii1i def OoOo ( name ) : oOooo0OOO = subprocess . Popen ( [ "dpkg-query" , "--showformat" , "${Package}\n${Version}\n${Architecture}\n${Status}" , "--show" , name ] , universal_newlines = True , stdout = subprocess . PIPE , stderr = subprocess . PIPE ) if 43 - 43: ooOOO * I1Ii1I1 ( ii1Ii , oOooO0 ) = oOooo0OOO . communicate ( ) if 95 - 95: Ooo0Ooo % Iii1i % i1i1i1111I . OooOoo if oOooo0OOO . returncode != 0 : if 70 - 70: IiIIii11Ii logging . debug ( "Failed to get information about package '%s'" % name ) if 75 - 75: Ooo0Ooo / Ii / IiIIii11Ii + IiIIii11Ii . I1I IIiIiiIiI = ii1Ii + oOooO0 if IIiIiiIiI : for OO0000 in ( ii1Ii + oOooO0 ) . splitlines ( ) : logging . debug ( " " + OO0000 ) if 88 - 88: Oo * IiIIii11Ii return { "name" : name , "versions" : [ ] } if 100 - 100: iiIi1 - OooOoo * I1Ii1I1 / Ooo0Ooo / Iii1i name , I111IIi11IiI , o0OOOooO00oo , I11iIi1i = ii1Ii . splitlines ( ) if 49 - 49: IIiIIiIi11I1 iIIiii1iI , OOO , I11iIi1i = I11iIi1i . split ( " " ) if 83 - 83: ooo0O0oO00 - Iii1i + ooOOO . o00o0OO00O / ooOOO if 5 - 5: iiIi1 if OOO != "ok" : logging . error ( "Existing package '%s' is in a broken state" % name ) return None if 56 - 56: i1iiIII111 * iiIi1 - iIiii1i if 15 - 15: I1I % Ii + Ooo0Ooo * Iii1i if 67 - 67: I1I * Ooo0Ooo + i1iiIII111 . i1iiIII111 % Oo if 93 - 93: oOo0O00 % Ooo0Ooo * i1iiIII111 if 52 - 52: ooo0O0oO00 + I1I / ooo000 - I1Ii1I1 * o00o0OO00O % oOo0O00 if 52 - 52: oOo0O00 . I1I + o00o0OO00O - i1iiIII111 % iI1iII1I1I1i if 57 - 57: I1I * IIiIIiIi11I1 % I1Ii1I1 * i1i1i1111I if 37 - 37: iiIi1 * i1i1i1111I + oOo0O00 / I1I / OooOoo if 4 - 4: i1 if I11iIi1i == "not-installed" or I11iIi1i == "config-files" : return { "name" : name , "versions" : [ ] } if 61 - 61: iI1iII1I1I1i . o00o0OO00O - ooo000 / ooo000 - i1 if 19 - 19: Iii1i * Ooo0Ooo . I1Ii1I1 / iIiii1i * Ii - ooo0O0oO00 if I11iIi1i != "installed" : logging . error ( "Existing package '%s' is in an invalid state '%s'" % ( name , I11iIi1i ) ) return None if 32 - 32: iI1iII1I1I1i return { "name" : name , "versions" : [ { "version" : I111IIi11IiI , "arch" : o0OOOooO00oo } ] } if 18 - 18: iIiii1i * iiIi1 % iI1iII1I1I1i + iiIi1 def O0OO ( pkgs ) : if 34 - 34: ooOOO * iIiii1i logging . error ( "Package removal not supported" ) return False if 63 - 63: ooOOO / i1i1i1111I - oOo0O00 * ooOOO / i1iiIII111 + ooo0O0oO00 def iiI1 ( pkgs , progress_cb = None ) : logging . info ( "Installing package(s): %s" % ", " . join ( map ( os . path . basename , pkgs ) ) ) if 20 - 20: i1i1i1111I / Ooo0Ooo - ooo0O0oO00 + Ooo0Ooo - I1I . Ooo0Ooo oOOoOOOO000 , IIIIi = os . pipe ( ) if 50 - 50: ooo000 * I1Ii1I1 * iI1iII1I1I1i i111ii1I = [ "dpkg" , "--install" ] if 18 - 18: Ii / ooo000 + I1I + iI1iII1I1I1i if 42 - 42: ooOOO - ooOOO - i1i1i1111I if 61 - 61: ooo0O0oO00 i111ii1I += [ "--force-confmiss" , "--force-confold" ] if 7 - 7: i1i1i1111I / Ii * Iii1i if 32 - 32: iiIi1 . OooOoo if 31 - 31: Oo - o00o0OO00O i111ii1I += [ "--force-overwrite" ] if 28 - 28: ooOOO * I1Ii1I1 + iiIi1 % Oo i111ii1I += [ "--status-fd" , str ( IIIIi ) ] i111ii1I += pkgs if 100 - 100: Oo + o00o0OO00O if 4 - 4: ooo000 % I1I - i1i1i1111I with subprocess . Popen ( i111ii1I , stdin = subprocess . DEVNULL , stdout = subprocess . PIPE , stderr = subprocess . PIPE , pass_fds = [ IIIIi ] ) as oOooo0OOO : if 76 - 76: i1 * oOo0O00 . iiIi1 * o00o0OO00O . IiIIii11Ii . ooo0O0oO00 if progress_cb is not None : progress_cb ( 0 ) if 55 - 55: i1i1i1111I + i1iiIII111 % Ooo0Ooo . Oo - IiIIii11Ii - iI1iII1I1I1i if 91 - 91: I1Ii1I1 - iIiii1i OO00OOooO = oOooo0OOO . stdout . fileno ( ) o000OOoOO = oOooo0OOO . stderr . fileno ( ) if 24 - 24: IiIIii11Ii / i1iiIII111 + iiIi1 + ooOOO if 72 - 72: iIiii1i i1II1 = { } if 98 - 98: IIiIIiIi11I1 * IIiIIiIi11I1 ii1Ii = b"" oOooO0 = b"" oOo = b"" while True : try : ( o00OO0 , O0OO0OOOOoo0o , o00ooo0OO0000 ) = select . select ( [ OO00OOooO , o000OOoOO , oOOoOOOO000 ] , [ ] , [ ] ) except : break if 37 - 37: I1I if oOOoOOOO000 in o00OO0 : oOo += os . read ( oOOoOOOO000 , 8192 ) if 38 - 38: I1Ii1I1 + oOo0O00 while b"\n" in oOo : ( OO0000 , oOo ) = oOo . split ( b"\n" , 1 ) OO0000 = OO0000 . decode ( locale . getpreferredencoding ( False ) ) if 2 - 2: OooOoo % Ii + ooo0O0oO00 . OooOoo + IIiIIiIi11I1 * Oo if OO0000 . startswith ( "processing:" ) : ( IIIIiiIIi , Ii111iii1 , ii1iIi1i11i ) = OO0000 . split ( ":" , 2 ) Ii111iii1 = Ii111iii1 . strip ( ) ii1iIi1i11i = ii1iIi1i11i . strip ( ": " ) if 39 - 39: i1 if Ii111iii1 == "install" or Ii111iii1 == "upgrade" : if 16 - 16: iiIi1 - iiIi1 % iIiii1i / iI1iII1I1I1i - iI1iII1I1I1i if ii1iIi1i11i in i1II1 : logging . warning ( "Warning: package '%s' " "mentioned multiple times" % ii1iIi1i11i ) if 39 - 39: oOo0O00 - iiIi1 % iiIi1 . Oo * I1I if 81 - 81: i1i1i1111I + I1Ii1I1 i1II1 [ ii1iIi1i11i ] = { "state" : "" , "mode" : Ii111iii1 } elif OO0000 . startswith ( "status:" ) : iiiiII11II = OO0000 . split ( ":" , 3 ) ii1iIi1i11i = iiiiII11II [ 1 ] . strip ( ) I11iIi1i = iiiiII11II [ 2 ] . strip ( ) if 5 - 5: oOo0O00 + iI1iII1I1I1i if I11iIi1i == "error" : logging . warning ( "Warning during installation of" " '%s': %s" % ( ii1iIi1i11i , repr ( iiiiII11II [ 3 ] ) ) ) if 10 - 10: ooOOO / o00o0OO00O * I1I * Oo - i1 % OooOoo else : if ii1iIi1i11i in i1II1 : i1II1 [ ii1iIi1i11i ] [ "state" ] = I11iIi1i if 35 - 35: Ii . I1Ii1I1 OoO0O0OO0 = 0 for I11iIi1i in i1II1 . values ( ) : O0o = 0 if 56 - 56: iiIi1 + Iii1i + i1 . o00o0OO00O * Iii1i % ooOOO if I11iIi1i [ "mode" ] == "install" : if I11iIi1i [ "state" ] == "half-installed" : O0o = 25 elif I11iIi1i [ "state" ] == "unpacked" : O0o = 50 elif I11iIi1i [ "state" ] == "half-configured" : O0o = 75 elif I11iIi1i [ "state" ] == "installed" : O0o = 100 elif I11iIi1i [ "mode" ] == "upgrade" : if I11iIi1i [ "state" ] == "half-configured" : O0o = 17 elif I11iIi1i [ "state" ] == "unpacked" : O0o = 33 elif I11iIi1i [ "state" ] == "half-installed" : O0o = 50 I11iIi1i [ "mode" ] = "replace" elif I11iIi1i [ "mode" ] == "replace" : if I11iIi1i [ "state" ] == "half-installed" : O0o = 50 elif I11iIi1i [ "state" ] == "unpacked" : O0o = 67 elif I11iIi1i [ "state" ] == "half-configured" : O0o = 83 elif I11iIi1i [ "state" ] == "installed" : O0o = 100 if 74 - 74: I1Ii1I1 OoO0O0OO0 += O0o / len ( pkgs ) if 61 - 61: iI1iII1I1I1i * I1Ii1I1 + Ooo0Ooo % IIiIIiIi11I1 * i1i1i1111I if progress_cb is not None : progress_cb ( OoO0O0OO0 ) if 61 - 61: i1iiIII111 - Oo + I1Ii1I1 if OO00OOooO in o00OO0 : ii1Ii += os . read ( OO00OOooO , 8192 ) if o000OOoOO in o00OO0 : oOooO0 += os . read ( o000OOoOO , 8192 ) if 43 - 43: IIiIIiIi11I1 * ooo000 + Ii % iI1iII1I1I1i oOooo0OOO . poll ( ) if oOooo0OOO . returncode is not None : break if 12 - 12: i1iiIII111 + ooo000 . iIiii1i if progress_cb is not None : progress_cb ( 100 ) if 1 - 1: iI1iII1I1I1i % Ii - iIiii1i / iiIi1 + iI1iII1I1I1i - Ii if 27 - 27: OooOoo % iI1iII1I1I1i + IIiIIiIi11I1 if 16 - 16: iiIi1 if 31 - 31: oOo0O00 / Iii1i % Ooo0Ooo % i1 . iI1iII1I1I1i . Oo if 83 - 83: oOo0O00 - iIiii1i if 91 - 91: IIiIIiIi11I1 - i1 - iI1iII1I1I1i if 71 - 71: I1I - iiIi1 OOO = True if len ( i1II1 ) != len ( pkgs ) : OOO = False else : for I11iIi1i in i1II1 . values ( ) : if I11iIi1i [ "state" ] != "installed" : OOO = False break if 66 - 66: i1i1i1111I / Ooo0Ooo + iIiii1i + Iii1i + oOo0O00 + o00o0OO00O if not OOO : logging . error ( "Installation of packages failed:" ) if 75 - 75: OooOoo - ooo0O0oO00 - IiIIii11Ii - ooo0O0oO00 + ooo000 % iI1iII1I1I1i IIiIiiIiI = ii1Ii + oOooO0 if IIiIiiIiI : for OO0000 in ( ii1Ii + oOooO0 ) . splitlines ( ) : OO0000 = OO0000 . decode ( locale . getpreferredencoding ( False ) , errors = 'replace' ) logging . error ( " " + OO0000 ) if 42 - 42: i1 * o00o0OO00O return False if 50 - 50: Ii - i1iiIII111 return True if 96 - 96: ooo000 * OooOoo - Ii - OooOoo def oo0Oo0oO0 ( a , b ) : iII11I1iI = subprocess . call ( [ "dpkg" , "--compare-versions" , a , "lt" , b ] ) if iII11I1iI == 0 : return - 1 if 87 - 87: i1iiIII111 - IIiIIiIi11I1 * Ii % i1i1i1111I % i1 ooOo00oOo0Ooo = subprocess . call ( [ "dpkg" , "--compare-versions" , a , "gt" , b ] ) if ooOo00oOo0Ooo == 0 : return 1 if 42 - 42: oOo0O00 return 0 if 46 - 46: OooOoo - iIiii1i / Ooo0Ooo def determine_upgrade ( fns ) : logging . info ( "Analyzing upgrade path..." ) if 73 - 73: I1Ii1I1 / i1i1i1111I / ooo000 % i1 % o00o0OO00O - OooOoo IIII1iII11ii = [ ] OO0O0OOOoOO = [ ] i1I1I1Ii = [ ] O0 = [ ] Ii1Ii1 = [ ] if 25 - 25: OooOoo + Oo * Ii * iI1iII1I1I1i + Ii for oOO in fns : logging . debug ( "Checking '%s'..." % os . path . basename ( oOO ) ) if 96 - 96: I1I / ooo0O0oO00 / iIiii1i + iIiii1i oOO0Oo = ooO0Oo0o00 ( oOO ) if oOO0Oo is None : return None if 60 - 60: OooOoo IIiIiI1iII = OoOo ( oOO0Oo [ "name" ] ) if IIiIiI1iII is None : return None if 87 - 87: ooOOO * ooo000 % IiIIii11Ii * i1 . Iii1i - iiIi1 if 72 - 72: i1 % i1i1i1111I * iI1iII1I1I1i IIii = oOO0Oo [ "versions" ] [ 0 ] [ "conflicts" ] IIii = set ( [ spec . split ( " " , 1 ) [ 0 ] for spec in IIii ] ) OO00 = oOO0Oo [ "versions" ] [ 0 ] [ "replaces" ] OO00 = set ( [ spec . split ( " " , 1 ) [ 0 ] for spec in OO00 ] ) if 90 - 90: Ooo0Ooo * OooOoo . Ii Iiii1iIII = IIii & OO00 for o0oO0OOo in Iiii1iIII : oOoOo0O00 = OoOo ( o0oO0OOo ) if oOoOo0O00 is None : return None if len ( oOoOo0O00 [ "versions" ] ) > 0 : Ii1Ii1 . append ( o0oO0OOo ) if 46 - 46: ooo000 oOoiI = "%s_%s" % ( oOO0Oo [ "versions" ] [ 0 ] [ "version" ] , oOO0Oo [ "versions" ] [ 0 ] [ "arch" ] ) if len ( IIiIiI1iII [ "versions" ] ) == 0 : iii1i1iiIi1 = "" else : iii1i1iiIi1 = "%s_%s" % ( IIiIiI1iII [ "versions" ] [ 0 ] [ "version" ] , IIiIiI1iII [ "versions" ] [ 0 ] [ "arch" ] ) if 1 - 1: OooOoo / ooOOO % I1Ii1I1 logging . debug ( "Version to install: %s" % oOoiI ) logging . debug ( "Current version(s): %s" % iii1i1iiIi1 ) if 15 - 15: OooOoo . IiIIii11Ii . o00o0OO00O / Iii1i + ooOOO / Ii if len ( IIiIiI1iII [ "versions" ] ) == 0 : OO0O0OOOoOO . append ( oOO ) else : Ii1iIII11i = oo0Oo0oO0 ( oOO0Oo [ "versions" ] [ 0 ] [ "version" ] , IIiIiI1iII [ "versions" ] [ 0 ] [ "version" ] ) if Ii1iIII11i <= 0 : O0 . append ( oOO ) else : i1I1I1Ii . append ( oOO ) if 58 - 58: iiIi1 / iIiii1i . iI1iII1I1I1i + Iii1i * Ii return { "remove" : IIII1iII11ii , "install" : OO0O0OOOoOO , "upgrade" : i1I1I1Ii , "ignore" : O0 , "obsolete" : Ii1Ii1 } if 62 - 62: Oo - iI1iII1I1I1i - i1i1i1111I . i1iiIII111 def perform_upgrade ( actions , progress_cb = None , output_cb = None ) : iI11 = 0 iI11 += len ( actions [ "remove" ] ) iI11 += len ( actions [ "install" ] ) iI11 += len ( actions [ "upgrade" ] ) if 75 - 75: i1iiIII111 * iiIi1 - oOo0O00 % iIiii1i - iiIi1 if progress_cb is not None : progress_cb ( 0 ) if 56 - 56: Oo IiIIIII1i = 0 if 41 - 41: ooOOO + OooOoo + IIiIIiIi11I1 * i1i1i1111I if 12 - 12: i1i1i1111I if len ( actions [ "remove" ] ) > 0 : if 56 - 56: IiIIii11Ii logging . error ( "Package removal not supported" ) return False if 17 - 17: o00o0OO00O . ooo0O0oO00 % Oo + IiIIii11Ii - Ooo0Ooo if 93 - 93: oOo0O00 if progress_cb is not None : O00 = lambda oOooo0OOO : progress_cb ( 100 * IiIIIII1i / iI11 + oOooo0OOO * ( iI11 - IiIIIII1i ) / iI11 ) else : O00 = None if 28 - 28: IIiIIiIi11I1 * i1 OOO = iiI1 ( actions [ "install" ] + actions [ "upgrade" ] , progress_cb = O00 ) if not OOO : return False if 14 - 14: IiIIii11Ii % ooOOO . o00o0OO00O if progress_cb is not None : progress_cb ( 100 ) if 29 - 29: iiIi1 % ooo0O0oO00 % iiIi1 . ooOOO return True # dd678faae9ac167bc83abf78e5cb2f3f0688d3a3