<s> import os <EOL> import sys <EOL> from conary . lib import log <EOL> from conary . local import database <EOL> from conary . conaryclient import cmdline <EOL> from conary . repository import changeset , filecontainer <EOL> def listRollbacks ( db , cfg ) : <EOL> return formatRollbacks ( cfg , db . getRollbackStack ( ) . iter ( ) , stream = sys . stdout ) <EOL> def versionFormat ( cfg , version , defaultLabel = None ) : <EOL> """<STR_LIT>""" <EOL> if cfg . fullVersions : <EOL> return str ( version ) <EOL> if cfg . showLabels : <EOL> ret = "<STR_LIT>" % ( version . branch ( ) . label ( ) , version . trailingRevision ( ) ) <EOL> return ret <EOL> if defaultLabel and ( version . branch ( ) . label ( ) == defaultLabel ) : <EOL> return str ( version . trailingRevision ( ) ) <EOL> ret = "<STR_LIT>" % ( version . branch ( ) . label ( ) , version . trailingRevision ( ) ) <EOL> return ret <EOL> def verStr ( cfg , version , flavor , defaultLabel = None ) : <EOL> if defaultLabel is None : <EOL> defaultLabel = cfg . installLabel <EOL> ret = versionFormat ( cfg , version , defaultLabel = defaultLabel ) <EOL> if cfg . fullFlavors : <EOL> return "<STR_LIT>" % ( ret , str ( flavor ) ) <EOL> return ret <EOL> def formatRollbacks ( cfg , rollbacks , stream = None ) : <EOL> if stream is None : <EOL> stream = sys . stdout <EOL> templ = "<STR_LIT>" <EOL> w_ = stream . write <EOL> for ( rollbackName , rb ) in rollbacks : <EOL> w_ ( "<STR_LIT>" % rollbackName ) <EOL> for cs in rb . iterChangeSets ( ) : <EOL> newList = [ ] <EOL> for pkg in cs . iterNewTroveList ( ) : <EOL> newList . append ( ( pkg . getName ( ) , <EOL> pkg . getOldVersion ( ) , pkg . getOldFlavor ( ) , <EOL> pkg . getNewVersion ( ) , pkg . getNewFlavor ( ) ) ) <EOL> oldList = [ x [ <NUM_LIT:0> : <NUM_LIT:3> ] for x in cs . getOldTroveList ( ) ] <EOL> newList . sort ( ) <EOL> compByPkg = { } <EOL> for info in newList : <EOL> name = info [ <NUM_LIT:0> ] <EOL> if '<STR_LIT::>' in name : <EOL> pkg , component = name . split ( '<STR_LIT::>' ) <EOL> pkgInfo = ( pkg , ) + info [ <NUM_LIT:1> : ] <EOL> else : <EOL> pkgInfo = info <EOL> component = None <EOL> l = compByPkg . setdefault ( pkgInfo , [ ] ) <EOL> l . append ( component ) <EOL> oldList . sort ( ) <EOL> for info in newList : <EOL> ( name , oldVersion , oldFlavor , newVersion , newFlavor ) = info <EOL> if '<STR_LIT::>' in name : <EOL> pkgInfo = ( name . split ( '<STR_LIT::>' ) [ <NUM_LIT:0> ] , ) + info [ <NUM_LIT:1> : ] <EOL> if None in compByPkg [ pkgInfo ] : <EOL> continue <EOL> if info in compByPkg : <EOL> comps = [ "<STR_LIT::>" + x for x in compByPkg [ info ] if x is not None ] <EOL> if comps : <EOL> name += '<STR_LIT>' % "<STR_LIT:U+0020>" . join ( comps ) <EOL> if newVersion . onLocalLabel ( ) : <EOL> continue <EOL> if not oldVersion : <EOL> w_ ( templ % ( '<STR_LIT>' , name , <EOL> verStr ( cfg , newVersion , newFlavor ) ) ) <EOL> else : <EOL> ov = oldVersion . trailingRevision ( ) <EOL> nv = newVersion . trailingRevision ( ) <EOL> if newVersion . onRollbackLabel ( ) and ov == nv : <EOL> continue <EOL> pn = "<STR_LIT>" % ( verStr ( cfg , newVersion , newFlavor ) , <EOL> verStr ( cfg , oldVersion , oldFlavor , <EOL> defaultLabel = <EOL> newVersion . branch ( ) . label ( ) ) ) <EOL> w_ ( templ % ( '<STR_LIT>' , name , pn ) ) <EOL> compByPkg = { } <EOL> for name , version , flavor in oldList : <EOL> if '<STR_LIT::>' in name : <EOL> pkg , component = name . split ( '<STR_LIT::>' ) <EOL> else : <EOL> pkg = name <EOL> component = None <EOL> l = compByPkg . setdefault ( ( pkg , version , flavor ) , [ ] ) <EOL> l . append ( component ) <EOL> for ( name , version , flavor ) in oldList : <EOL> if '<STR_LIT::>' in name : <EOL> pkgInfo = ( name . split ( '<STR_LIT::>' ) [ <NUM_LIT:0> ] , version , flavor ) <EOL> if None in compByPkg [ pkgInfo ] : <EOL> continue <EOL> if ( name , version , flavor ) in compByPkg : <EOL> comps = [ "<STR_LIT::>" + x <EOL> for x in compByPkg [ ( name , version , flavor ) ] <EOL> if x is not None ] <EOL> if comps : <EOL> name += '<STR_LIT>' % "<STR_LIT:U+0020>" . join ( comps ) <EOL> w_ ( templ % ( '<STR_LIT>' , name , verStr ( cfg , version , flavor ) ) ) <EOL> w_ ( '<STR_LIT:\n>' ) <EOL> def formatRollbacksAsUpdate ( cfg , rollbackList ) : <EOL> updateTempl = "<STR_LIT>" <EOL> templ = "<STR_LIT>" <EOL> print '<STR_LIT>' <EOL> for idx , rb in enumerate ( rollbackList ) : <EOL> print '<STR_LIT>' % ( idx + <NUM_LIT:1> , len ( rollbackList ) ) <EOL> newList = [ ] <EOL> oldList = [ ] <EOL> for cs in rb . iterChangeSets ( ) : <EOL> for pkg in cs . iterNewTroveList ( ) : <EOL> newList . append ( ( pkg . getName ( ) , <EOL> pkg . getOldVersion ( ) , pkg . getOldFlavor ( ) , <EOL> pkg . getNewVersion ( ) , pkg . getNewFlavor ( ) ) ) <EOL> oldList += [ x [ <NUM_LIT:0> : <NUM_LIT:3> ] for x in cs . getOldTroveList ( ) ] <EOL> newList . sort ( ) <EOL> compByPkg = { } <EOL> for info in newList : <EOL> name = info [ <NUM_LIT:0> ] <EOL> if '<STR_LIT::>' in name : <EOL> pkg , component = name . split ( '<STR_LIT::>' ) <EOL> pkgInfo = ( pkg , ) + info [ <NUM_LIT:1> : ] <EOL> else : <EOL> pkgInfo = info <EOL> component = None <EOL> l = compByPkg . setdefault ( pkgInfo , [ ] ) <EOL> l . append ( component ) <EOL> oldList . sort ( ) <EOL> for info in newList : <EOL> ( name , oldVersion , oldFlavor , newVersion , newFlavor ) = info <EOL> if '<STR_LIT::>' in name : <EOL> pkgInfo = ( name . split ( '<STR_LIT::>' ) [ <NUM_LIT:0> ] , ) + info [ <NUM_LIT:1> : ] <EOL> if None in compByPkg [ pkgInfo ] : <EOL> continue <EOL> if info in compByPkg : <EOL> comps = [ "<STR_LIT::>" + x for x in compByPkg [ info ] if x is not None ] <EOL> if comps : <EOL> name += '<STR_LIT>' % "<STR_LIT:U+0020>" . join ( comps ) <EOL> if newVersion . onLocalLabel ( ) : <EOL> continue <EOL> if not oldVersion : <EOL> print ( templ % ( '<STR_LIT>' , name , <EOL> verStr ( cfg , newVersion , newFlavor ) ) ) <EOL> else : <EOL> ov = oldVersion . trailingRevision ( ) <EOL> nv = newVersion . trailingRevision ( ) <EOL> if newVersion . onRollbackLabel ( ) and ov == nv : <EOL> continue <EOL> pn = "<STR_LIT>" % ( verStr ( cfg , oldVersion , newFlavor ) , <EOL> verStr ( cfg , newVersion , oldFlavor , <EOL> defaultLabel = <EOL> newVersion . branch ( ) . label ( ) ) ) <EOL> print ( updateTempl % ( '<STR_LIT>' , name , pn ) ) <EOL> compByPkg = { } <EOL> for name , version , flavor in oldList : <EOL> if '<STR_LIT::>' in name : <EOL> pkg , component = name . split ( '<STR_LIT::>' ) <EOL> else : <EOL> pkg = name <EOL> component = None <EOL> l = compByPkg . setdefault ( ( pkg , version , flavor ) , [ ] ) <EOL> l . append ( component ) <EOL> for ( name , version , flavor ) in oldList : <EOL> if '<STR_LIT::>' in name : <EOL> pkgInfo = ( name . split ( '<STR_LIT::>' ) [ <NUM_LIT:0> ] , version , flavor ) <EOL> if None in compByPkg [ pkgInfo ] : <EOL> continue <EOL> if ( name , version , flavor ) in compByPkg : <EOL> comps = [ "<STR_LIT::>" + x <EOL> for x in compByPkg [ ( name , version , flavor ) ] <EOL> if x is not None ] <EOL> if comps : <EOL> name += '<STR_LIT>' % "<STR_LIT:U+0020>" . join ( comps ) <EOL> print ( templ % ( '<STR_LIT>' , name , verStr ( cfg , version , flavor ) ) ) <EOL> return <NUM_LIT:0> <EOL> def applyRollback ( client , rollbackSpec , returnOnError = False , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> client . checkWriteableRoot ( ) <EOL> transactionCounter = client . db . getTransactionCounter ( ) <EOL> log . syslog . command ( ) <EOL> showInfoOnly = kwargs . pop ( '<STR_LIT>' , False ) <EOL> defaults = dict ( replaceFiles = False , <EOL> transactionCounter = transactionCounter , <EOL> lazyCache = client . lzCache ) <EOL> defaults . update ( kwargs ) <EOL> rollbackStack = client . db . getRollbackStack ( ) <EOL> rollbackList = rollbackStack . getList ( ) <EOL> if rollbackSpec . startswith ( '<STR_LIT>' ) : <EOL> try : <EOL> i = rollbackList . index ( rollbackSpec ) <EOL> except ValueError : <EOL> log . error ( "<STR_LIT>" % rollbackSpec ) <EOL> if returnOnError : <EOL> return <NUM_LIT:1> <EOL> raise database . RollbackDoesNotExist ( rollbackSpec ) <EOL> rollbacks = rollbackList [ i : ] <EOL> rollbacks . reverse ( ) <EOL> else : <EOL> try : <EOL> rollbackCount = int ( rollbackSpec ) <EOL> except ValueError : <EOL> log . error ( "<STR_LIT>" % <EOL> rollbackSpec ) <EOL> if returnOnError : <EOL> return <NUM_LIT:1> <EOL> raise database . RollbackDoesNotExist ( rollbackSpec ) <EOL> if rollbackCount < <NUM_LIT:1> : <EOL> log . error ( "<STR_LIT>" ) <EOL> if returnOnError : <EOL> return <NUM_LIT:1> <EOL> raise database . RollbackDoesNotExist ( rollbackSpec ) <EOL> elif rollbackCount > len ( rollbackList ) : <EOL> log . error ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> if returnOnError : <EOL> return <NUM_LIT:1> <EOL> raise database . RollbackDoesNotExist ( rollbackSpec ) <EOL> rollbacks = rollbackList [ - rollbackCount : ] <EOL> rollbacks . reverse ( ) <EOL> capsuleChangeSet = changeset . ReadOnlyChangeSet ( ) <EOL> for path in defaults . pop ( '<STR_LIT>' , [ ] ) : <EOL> if os . path . isdir ( path ) : <EOL> pathList = [ os . path . join ( path , x ) for x in os . listdir ( path ) ] <EOL> else : <EOL> pathList = [ path ] <EOL> for p in pathList : <EOL> if not os . path . isfile ( p ) : <EOL> continue <EOL> try : <EOL> cs = changeset . ChangeSetFromFile ( p ) <EOL> except filecontainer . BadContainer : <EOL> continue <EOL> capsuleChangeSet . merge ( cs ) <EOL> defaults [ '<STR_LIT>' ] = capsuleChangeSet <EOL> if showInfoOnly or client . cfg . interactive : <EOL> rollbackList = [ rollbackStack . getRollback ( x ) for x in rollbacks if rollbackStack . hasRollback ( x ) ] <EOL> formatRollbacksAsUpdate ( client . cfg , rollbackList ) <EOL> if showInfoOnly : <EOL> return <NUM_LIT:0> <EOL> if client . cfg . interactive : <EOL> okay = cmdline . askYn ( '<STR_LIT>' , default = False ) <EOL> if not okay : <EOL> return <NUM_LIT:1> <EOL> try : <EOL> client . db . applyRollbackList ( client . getRepos ( ) , rollbacks , ** defaults ) <EOL> except database . RollbackError , e : <EOL> log . error ( "<STR_LIT:%s>" , e ) <EOL> if returnOnError : <EOL> return <NUM_LIT:1> <EOL> raise <EOL> log . syslog . commandComplete ( ) <EOL> return <NUM_LIT:0> <EOL> def removeRollbacks ( db , rollbackSpec ) : <EOL> rollbackStack = db . getRollbackStack ( ) <EOL> rollbackList = rollbackStack . getList ( ) <EOL> if rollbackSpec . startswith ( '<STR_LIT>' ) : <EOL> try : <EOL> i = rollbackList . index ( rollbackSpec ) <EOL> except : <EOL> log . error ( "<STR_LIT>" % rollbackSpec ) <EOL> return <NUM_LIT:1> <EOL> rollbacks = rollbackList [ : i + <NUM_LIT:1> ] <EOL> else : <EOL> try : <EOL> rollbackCount = int ( rollbackSpec ) <EOL> except : <EOL> log . error ( "<STR_LIT>" % <EOL> rollbackSpec ) <EOL> return <NUM_LIT:1> <EOL> if rollbackCount < <NUM_LIT:1> : <EOL> log . error ( "<STR_LIT>" ) <EOL> return <NUM_LIT:1> <EOL> elif rollbackCount > len ( rollbackList ) : <EOL> log . error ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> return <NUM_LIT:1> <EOL> rollbacks = rollbackList [ : rollbackCount ] <EOL> for rb in rollbacks : <EOL> rollbackStack . remove ( rb ) <EOL> return <NUM_LIT:0> <EOL> class RollbackScriptsError ( Exception ) : <EOL> "<STR_LIT>" <EOL> class _RollbackScripts ( object ) : <EOL> _KEY_JOB = '<STR_LIT>' <EOL> _KEY_INDEX = '<STR_LIT:index>' <EOL> _KEY_OLD_COMPAT_CLASS = '<STR_LIT>' <EOL> _KEY_NEW_COMPAT_CLASS = '<STR_LIT>' <EOL> _KEYS = set ( [ _KEY_JOB , _KEY_INDEX , _KEY_OLD_COMPAT_CLASS , <EOL> _KEY_NEW_COMPAT_CLASS ] ) <EOL> _metaFileNameTemplate = '<STR_LIT>' <EOL> _scriptFileNameTemplate = '<STR_LIT>' <EOL> def __init__ ( self ) : <EOL> self . _items = [ ] <EOL> def add ( self , job , script , oldCompatClass , newCompatClass , index = None ) : <EOL> if index is None : <EOL> index = len ( self . _items ) <EOL> self . _items . append ( ( index , job , script , oldCompatClass , newCompatClass ) ) <EOL> return self <EOL> def __iter__ ( self ) : <EOL> return iter ( self . _items ) <EOL> def getCreatedFiles ( self , dir ) : <EOL> "<STR_LIT>" <EOL> ret = set ( ) <EOL> ret . add ( self . _getMDFileName ( dir ) ) <EOL> for idx , job , script , oldCompatClass , newCompatClass in self : <EOL> fname = self . _getScriptFileName ( dir , idx ) <EOL> ret . add ( fname ) <EOL> return ret <EOL> def save ( self , dir ) : <EOL> stream = self . _openFile ( self . _getMDFileName ( dir ) ) <EOL> self . saveMeta ( stream ) <EOL> stream . close ( ) <EOL> for idx , job , script , oldCompatClass , newCompatClass in self : <EOL> fname = self . _getScriptFileName ( dir , idx ) <EOL> self . _openFile ( fname ) . write ( script ) <EOL> def saveMeta ( self , stream ) : <EOL> for idx , job , script , oldCompatClass , newCompatClass in self : <EOL> if idx > <NUM_LIT:0> : <EOL> stream . write ( '<STR_LIT:\n>' ) <EOL> lines = self . _serializeMeta ( idx , job , oldCompatClass , <EOL> newCompatClass ) <EOL> for line in lines : <EOL> stream . write ( line ) <EOL> stream . write ( '<STR_LIT:\n>' ) <EOL> @ classmethod <EOL> def load ( cls , dir ) : <EOL> ret = cls ( ) <EOL> group = [ ] <EOL> try : <EOL> stream = file ( cls . _getMDFileName ( dir ) ) <EOL> except IOError , e : <EOL> raise RollbackScriptsError ( "<STR_LIT>" % <EOL> ( e . errno , e . filename , e . strerror ) ) <EOL> while <NUM_LIT:1> : <EOL> line = stream . readline ( ) <EOL> sline = line . strip ( ) <EOL> if not sline : <EOL> if group : <EOL> cls . _finalize ( dir , group , ret ) <EOL> if line : <EOL> continue <EOL> break <EOL> group . append ( sline ) <EOL> return ret <EOL> @ classmethod <EOL> def _finalize ( cls , dir , group , rbs ) : <EOL> idx , g = cls . _parseMeta ( group ) <EOL> del group [ : ] <EOL> if g is not None : <EOL> try : <EOL> scfile = file ( cls . _getScriptFileName ( dir , idx ) ) <EOL> except IOError : <EOL> return <EOL> rbs . add ( g [ <NUM_LIT:0> ] , scfile . read ( ) , g [ <NUM_LIT:1> ] , g [ <NUM_LIT:2> ] , index = idx ) <EOL> @ classmethod <EOL> def _serializeVF ( cls , version , flavor ) : <EOL> if version is None : <EOL> return '<STR_LIT>' <EOL> if flavor is None or not str ( flavor ) : <EOL> return str ( version ) <EOL> return "<STR_LIT>" % ( version , flavor ) <EOL> @ classmethod <EOL> def _serializeJob ( cls , job ) : <EOL> return "<STR_LIT>" % ( job [ <NUM_LIT:0> ] , <EOL> cls . _serializeVF ( * job [ <NUM_LIT:1> ] ) , <EOL> cls . _serializeVF ( * job [ <NUM_LIT:2> ] ) ) <EOL> @ classmethod <EOL> def _serializeMeta ( cls , idx , job , oldCompatClass , newCompatClass ) : <EOL> lines = [ ] <EOL> lines . append ( '<STR_LIT>' % ( cls . _KEY_INDEX , idx ) ) <EOL> lines . append ( '<STR_LIT>' % ( cls . _KEY_JOB , cls . _serializeJob ( job ) ) ) <EOL> lines . append ( '<STR_LIT>' % ( cls . _KEY_OLD_COMPAT_CLASS , oldCompatClass ) ) <EOL> lines . append ( '<STR_LIT>' % ( cls . _KEY_NEW_COMPAT_CLASS , newCompatClass ) ) <EOL> return lines <EOL> @ classmethod <EOL> def _parseMeta ( cls , lines ) : <EOL> ret = { } <EOL> for line in lines : <EOL> arr = line . split ( '<STR_LIT>' , <NUM_LIT:1> ) <EOL> if len ( arr ) != <NUM_LIT:2> : <EOL> continue <EOL> if arr [ <NUM_LIT:0> ] not in cls . _KEYS : <EOL> continue <EOL> ret [ arr [ <NUM_LIT:0> ] ] = arr [ <NUM_LIT:1> ] <EOL> if cls . _KEYS . difference ( ret . keys ( ) ) : <EOL> return None <EOL> job = cmdline . parseChangeList ( [ ret [ cls . _KEY_JOB ] ] ) [ <NUM_LIT:0> ] <EOL> oldCompatClass = cls . _toInt ( ret [ cls . _KEY_OLD_COMPAT_CLASS ] ) <EOL> newCompatClass = cls . _toInt ( ret [ cls . _KEY_NEW_COMPAT_CLASS ] ) <EOL> try : <EOL> idx = int ( ret [ cls . _KEY_INDEX ] ) <EOL> except ValueError : <EOL> return None <EOL> return idx , ( job , oldCompatClass , newCompatClass ) <EOL> @ classmethod <EOL> def _toInt ( cls , value ) : <EOL> if value == '<STR_LIT:None>' : <EOL> return None <EOL> try : <EOL> return int ( value ) <EOL> except ValueError : <EOL> return None <EOL> @ classmethod <EOL> def _openFile ( cls , fileName ) : <EOL> flags = os . O_WRONLY | os . O_CREAT <EOL> try : <EOL> fd = os . open ( fileName , flags , <NUM_LIT:0> <NUM_LIT> ) <EOL> except OSError , e : <EOL> raise RollbackScriptsError ( "<STR_LIT>" % <EOL> ( e . errno , e . filename , e . strerror ) ) <EOL> return os . fdopen ( fd , "<STR_LIT:w>" ) <EOL> @ classmethod <EOL> def _getMDFileName ( cls , dir ) : <EOL> return os . path . join ( dir , cls . _metaFileNameTemplate ) <EOL> @ classmethod <EOL> def _getScriptFileName ( cls , dir , idx ) : <EOL> return os . path . join ( dir , cls . _scriptFileNameTemplate % idx ) </s>
