source: lliurex-up/trunk/fuentes/lliurex-up-cli/usr/sbin/lliurex-upgrade @ 4073

Last change on this file since 4073 was 4073, checked in by jrpelegrina, 3 years ago

WIP in improve lliurex-upgrade

  • Property svn:executable set to *
File size: 17.0 KB
Line 
1#!/usr/bin/env python
2
3from clint import arguments
4from clint.textui import puts, indent, colored
5import lliurex.lliurexup
6import os
7import subprocess
8import sys
9import commands
10import datetime
11import time
12import signal
13signal.signal(signal.SIGINT,signal.SIG_IGN)
14
15class LliurexUpCli(object):
16        def __init__(self):
17
18               
19                self.lliurexcore = lliurex.lliurexup.LliurexUpCore()
20                log_msg="------------------------------------------\n"+"LLIUREX-UP-CLI STARTING AT: " + datetime.datetime.today().strftime("%d/%m/%y %H:%M:%S") +"\n------------------------------------------"
21                self.log(log_msg)
22                signal.signal(signal.SIGINT,self.handler_signal)
23                self.checkInitialFlavour()
24       
25        #def __init__
26       
27        def checkInitialFlavour(self):
28
29                self.targetMetapackage=self.lliurexcore.checkInitialFlavour()
30                log_msg="Initial check metapackage. Metapackage to install: " + str(self.targetMetapackage)
31                self.log(log_msg)
32                log_msg="Get initial flavours: " + str(self.lliurexcore.previousFlavours)
33                self.log(log_msg)
34               
35        #def checkInitialFlavour       
36               
37
38        def canConnectToLliurexNet(self):
39
40                print("  [Lliurex-up]: Checking connection to lliurex.net")
41                can_connect=self.lliurexcore.canConnectToLliurexNet()
42                if can_connect:
43                                log_msg="Can connect to lliurex.net: True"
44                                self.log(log_msg)
45                                return True
46                else:
47                        log_msg="Can connect to lliurex.net: False"
48                        self.log(log_msg)
49
50                        if "lliurex-meta-server" == self.targetMetapackage or "server" in self.lliurexcore.previousFlavours:
51                                self.lliurexcore.cleanEnvironment()
52                                self.lliurexcore.cleanLliurexUpLock()
53                                return False
54                        else:
55                                return True
56                               
57        #def canConnectToLliurexNet                     
58                               
59        def clientCheckingMirrorIsRunning(self):
60               
61                is_mirror_running_inserver=self.lliurexcore.clientCheckingMirrorIsRunning()
62               
63                if is_mirror_running_inserver['ismirrorrunning'] ==None:
64                        log_msg="Checking if mirror in server is being updated. Error: " + str(is_mirror_running_inserver['exception'])
65                        self.log(log_msg)
66                else:
67                        if is_mirror_running_inserver['ismirrorrunning']:
68                                log_msg="Mirror is being udpated in server. Unable to update the system"
69                                self.log(log_msg)
70               
71                return is_mirror_running_inserver['ismirrorrunning']
72               
73                       
74        #def clientCheckingMirrorIsRunning             
75       
76        def initActionsScript(self,extra_args):
77
78                print("  [Lliurex-up]: Checking system")
79
80                if extra_args["unattendend_upgrade"]:
81                        command="DEBIAN_FRONTEND=noninteractive " + self.lliurexcore.initActionsScript(self.initActionsArg)
82               
83                else:
84                        command=self.lliurexcore.initActionsScript(self.initActionsArg)
85               
86                try:
87                        #os.system(command)
88                        p=subprocess.Popen(command,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
89                        poutput,perror=p.communicate()
90                        if len(perror)>0:
91                                log_msg="Exec Init-Actions. Error: " +str(error)
92                                print ("  [Lliurex-up]: Checking system.  Error: " + str(self.perror))
93                        else:
94                                log_msg="Exec Init-Actionss. OK"
95                                print ("  [Lliurex-up]: Checking system. OK")
96
97                        self.log(log_msg)
98                       
99                except Exception as e:
100                        log_msg="Exec Init-Actions.Error: " +str(e)
101                        self.log(log_msg)
102                        print e
103                       
104        #def initActionsScript
105       
106        def checkLliurexUp(self):
107
108                print("  [Lliurex-up]: Looking for new version of Lliurex Up")
109
110                is_lliurexup_updated=self.lliurexcore.isLliurexUpIsUpdated()
111
112
113                if not is_lliurexup_updated:
114                        print ("  [Lliurex-up]: Updating Lliurex Up")
115                        is_lliurexup_installed=self.lliurexcore.installLliurexUp()
116                        log_msg="Installing lliurex-up. Returncode: " + str(is_lliurexup_installed['returncode']) + ". Error: " + str(is_lliurexup_installed['stderrs'])
117                        self.log(log_msg)
118                        print ("  [Lliurex-up]: Lliurex Up is now udpate and will be reboot now" )
119                        time.sleep(3)
120                        self.lliurexcore.cleanLliurexUpLock()
121                        os.execv("/usr/sbin/lliurex-upgrade",sys.argv) 
122
123                else:
124                        log_msg="Checking lliurex-up. Is lliurex-up updated: "+ str(is_lliurexup_updated)
125                        self.log(log_msg)
126                        print ("  [Lliurex-up]: Lliurex Up is updated.Nothing to do")   
127                       
128        #def checkLliurexUp             
129
130        def checkMirror(self,extra_args=None):
131
132                print("  [Lliurex-up]: Checking if mirror is updated")
133
134                is_mirror_updated=self.lliurexcore.lliurexMirrorIsUpdated()
135
136                if is_mirror_updated !=None:
137                        is_mirror_running=self.lliurexcore.lliurexMirrorIsRunning()
138                        if is_mirror_running:
139                                print("  [Lliurex-up]: Updating mirror. Wait a moment please")
140                                command='lliurex-mirror update llx16'
141                                #os.system(command)
142                                subprocess.Popen(command,shell=True).communicate()
143
144                        else:
145                                if is_mirror_updated['action']=='update':
146                                        log_msg="Checking mirror. Is mirror update: False"
147                                        self.log(log_msg)
148                                        if not is_mirror_running:
149                                                if not extra_args["unattended_mirror"]:
150                                                        response=raw_input('  [LLiurex-up]: Do you want update mirror (yes/no): ').lower()
151                                                else:
152                                                        response="yes"
153
154                                                if response.startswith('y'):
155                                                        log_msg="Update lliurex-mirror: Yes"
156                                                        self.log(log_msg)
157                                                        print("  [Lliurex-up]: Updating mirror. Wait a moment please")
158                                                        command='lliurex-mirror update llx16'
159                                                        #os.system(command)
160                                                        subprocess.Popen(command,shell=True).communicate()
161
162                                                else:
163                                                        log_msg="Update lliurex-mirror: No"
164                                                        self.log(log_msg)
165                                                        print("  [Lliurex-up]: Mirror update.Nothing to do")           
166                else:
167                        log_msg="Checking mirror. Is mirror update: None"
168                        self.log(log_msg)
169                        print("  [Lliurex-up]: Nothing to do with mirror")
170                       
171        #def checkMirror               
172
173        def getLliurexVersionLocal(self):
174
175                print("  [Lliurex-up]: Looking for LliurexVersion from local repository")
176               
177                self.version_update=self.lliurexcore.getLliurexVersionLocal()
178                log_msg="Get LliurexVersion installed: " + str(self.version_update["installed"])
179                self.log(log_msg)
180                log_msg="Get LliurexVersion candidate from Local repository: " + str(self.version_update["candidate"])
181                self.log(log_msg)
182
183        #def getLliurexVersionLocal     
184       
185
186        def getLliurexVersionLliurexNet(self):
187       
188                print("  [Lliurex-up]: Looking for LliurexVersion from lliurex.net")
189
190                self.version_available=self.lliurexcore.getLliurexVersionLliurexNet()
191                log_msg="Get LliurexVersion candidate from Lliurex Net: " + str(self.version_available["candidate"])
192                self.log(log_msg)
193       
194        #def getLliurexVersionLliurexNet               
195
196        def checkingInitialFlavourToInstall(self):
197
198                print("  [Lliurex-up]: Checking if installation of metapackage is required")
199
200                self.returncode_initflavour=0
201
202                if self.targetMetapackage == None:
203                       
204                        print "  [Lliurex-up]: Installation of metapackage is not required"
205                       
206                else:
207                        print "  [Lliurex-up]: Installation of metapackage is required: " + str(self.targetMetapackage)
208                        is_flavour_installed=self.lliurexcore.installInitialFlavour(self.targetMetapackage)     
209                        self.returncode_initflavour=is_flavour_installed['returncode']
210                        error=is_flavour_installed['stderrs']
211                        log_msg="Install initial metapackage:" + self.targetMetapackage + ": Returncode: " + str(self.returncode_initflavour) + " Error: " + str(error)
212                        self.log(log_msg)
213                        print "  [Lliurex-up]: Metapackage is now installed: Returncode: " + str(self.returncode_initflavour) + " Error: " + str(error)
214                       
215        #def checkingInitialFlavourToInstall           
216       
217        def getPackagesToUpdate(self):
218
219                print("  [Lliurex-up]: Looking for new updates")
220                packages=self.lliurexcore.getPackagesToUpdate()
221                log_msg="Get packages to update. Number of packages: "+ str(len(packages))
222                self.log(log_msg)
223
224                self.newpackages=0
225                self.listpackages=""
226                if (len(packages))>0:
227                        for item in packages:
228                                if packages[item]["install"]==None:
229                                                self.newpackages=int(self.newpackages) + 1
230                                self.listpackages=str(self.listpackages) + item +" "           
231
232                return packages
233
234        #def getPackagesToUpdate               
235                       
236        def checkingIncorrectFlavours(self):
237               
238                incorrectFlavours=self.lliurexcore.checkIncorrectFlavours()
239                log_msg="Checking incorrect metapackages. Others metapackages detected: " + str(incorrectFlavours)
240                self.log(log_msg)
241
242                return incorrectFlavours
243       
244        #def checkingIncorrectFlavours         
245               
246        def checkPreviousUpgrade(self):
247               
248                error=False
249                if self.returncode_initflavour!=0:
250                        error=True
251
252                else:
253                        if self.version_update["candidate"]!=None:
254                                if self.version_update["installed"]!=self.version_update["candidate"]:
255                                        error=True
256                        else:
257                                if self.version_update["installed"]!=self.version_available["candidate"]:       
258                                        error=True
259
260                return error
261
262        #def checkPreviousUpgrade               
263
264        def preActionsScript(self,extra_args):
265
266                print("  [Lliurex-up]: Preparing system to update")
267
268                if extra_args["unattendend_upgrade"]:
269                        command="DEBIAN_FRONTEND=noninteractive " + self.lliurexcore.preActionsScript()
270                else:
271                        command=self.lliurexcore.preActionsScript()             
272               
273                try:
274                        #os.system(command)
275                        p=subprocess.Popen(command,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
276                        poutput,perror=p.communicate()
277                        if len(perror)>0:
278                                log_msg="Exec Pre-Actions. Error: " +str(error)
279                                print ("  [Lliurex-up]: Preparing system to update.  Error: " + str(self.perror))
280                        else:
281                                log_msg="Exec Pre-Actions. OK"
282                                print ("  [Lliurex-up]: Preparing system to update. OK")
283
284                        self.log(log_msg)
285
286                except Exception as e:
287                        log_msg="Exec Pre-Actions. Error " +str(e)
288                        self.log(log_msg)
289                        print e
290
291        #def preActionsScript                   
292
293        def distUpgrade(self,extra_args):
294
295                print("  [Lliurex-up]: Downloading and installing packages")
296
297                if extra_args["unattendend_upgrade"]:
298                        command="DEBIAN_FRONTEND=noninteractive " + self.lliurexcore.distUpgradeProcess()
299                else:
300                        command=self.lliurexcore.distUpgradeProcess()
301
302                try:
303                        #os.system(command)
304                        p=subprocess.Popen(command,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
305                        poutput,perror=p.communicate()
306                        if len(perror)>0:
307                                log_msg="Exec Dist-uggrade. Error: " +str(error)
308                                print ("  [Lliurex-up]: Downloading and installing packages.  Error: " + str(self.perror))
309                        else:
310                                log_msg="Exec Dist-uggrade. OK"
311                                print ("  [Lliurex-up]: Downloading and installing packages. OK")
312
313                        self.log(log_mg)       
314                       
315               
316                except Exception as e:
317                        log_msg="Exec Dist-uggrade.Error : " +str(e)
318                        self.log(log_msg)
319                        print e
320                       
321        #def distUpgrade               
322
323        def postActionsScript(self,extra_args):
324
325                self.postActionsError=False
326                print("  [Lliurex-up]: Ending the update")
327
328                if extra_args["unattendend_upgrade"]:
329                        command="DEBIAN_FRONTEND=noninteractive " + self.lliurexcore.postActionsScript()
330                else:
331                        command=self.lliurexcore.postActionsScript()
332       
333                try:
334                        p=subprocess.Popen(command,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
335                        poutput,perror=p.communicate()
336                        if len(perror)>0:
337                                self.postActionsError=True
338                                log_msg="Exec Post-Actions. Error: " + str(perror)
339                                print ("  [Lliurex-up]: Metapackage installation. Error: " + str(self.perror))
340                        else:
341                                log_msg="Exec Post-Actions. OK" 
342                                print ("  [Lliurex-up]: Metapackage installation. OK")
343
344                        #os.system(command)
345                        #log_msg="Exec Post-Actions"
346                        self.log(log_msg)
347
348                except Exception as e:
349                        print e
350
351        #def postActionsScript                 
352
353
354        def checkingFinalFlavourToInstall(self):
355               
356                self.finalFlavourError=False
357                print("  [Lliurex-up]: Checking final metapackage")
358
359                #self.flavourToInstall=self.lliurexcore.checkFinalFlavour()
360                self.flavourToInstall=self.lliurexcore.checkFlavour()
361
362                log_msg="Final check metapackage. Metapackage to install: " + str(self.flavourToInstall)
363                self.log(log_msg)
364               
365                if self.flavourToInstall!=None:
366                        print ("  [Lliurex-up]: Install of metapackage is required: " + str(self.flavourToInstall))
367                       
368                        if extra_args["unattendend_upgrade"]:
369                                command="DEBIAN_FRONTEND=noninteractive " +command=self.lliurexcore.installFinalFlavour(self.flavourToInstall)
370                        else:
371                                command=self.lliurexcore.installFinalFlavour(self.flavourToInstall)
372
373                        p=subprocess.Popen(command,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
374                        poutput,perror=p.communicate()
375
376                        if len(perror)>0:
377                                self.finalFlavourError=True
378                                log_msg=" Metapackage installation. Error: " + str(self.perror)
379                                print ("  [Lliurex-up]: Metapackage installation. Error: " + str(self.perror))
380                        else:
381                                log_msg=" Metapackage installation. OK"
382                                print ("  [Lliurex-up]: Metapackage installation. OK")
383
384                        self.log(log_msg)       
385                                       
386                else:
387                        print ("  [Lliurex-up]: Metapackage is correct. Nothing to do")
388                       
389        #def checkingFinalFlavourToInstall             
390                                       
391        def checkFinalUpgrade(self):
392
393                print("  [Lliurex-up]: Checking Dist-upgrade ")
394                error=self.lliurexcore.checkErrorDistUpgrade()
395
396                if error or self.postActionsError or self.finalFlavourError:
397                        print("  [Lliurex-up]: The updated process is endend with errors")
398                        log_msg="Dist-upgrade process ending with errors"
399               
400                else:                                   
401                        print("  [Lliurex-up]: The system is now update")       
402                        log_msg="Dist-upgrade process ending OK"
403               
404                self.log(log_msg)
405               
406        #def checkFinalUpgrade 
407
408        def handler_signal(self,signal,frame):
409               
410                print("\n  [Lliurex-up]: Cancel process with Ctr+c signal")
411                log_msg="Cancel process with Ctr+c signal"
412                self.log(log_msg)
413                self.lliurexcore.cleanEnvironment()
414                self.lliurexcore.cleanLliurexUpLock()
415                sys.exit(1)
416       
417        #def handler_signal
418
419        def log(self,msg):
420               
421                log_file="/var/log/lliurex-up.log"
422                f=open(log_file,"a+")
423                f.write(msg + '\n')
424                f.close()       
425       
426        #def log
427
428       
429        def main(self,mode,extra_args=None):
430
431                if mode=="sai":
432                        self.initActionsArg="initActionsSai"
433                       
434                else:
435                        mode="normal"
436                        self.initActionsArg="initActions"       
437
438                log_msg="Mode of execution: " + str(mode)
439                self.log(log_msg)
440                log_msg="Extra args: " + str(extra_args)
441                self.log(log_msg)
442                       
443                if not self.canConnectToLliurexNet():
444                        print("  [Lliurex-up]: Unable to connect to lliurex.net")
445                        self.lliurexcore.cleanEnvironment()
446                        self.lliurexcore.cleanLliurexUpLock()
447                        return 1
448                       
449                clientCheckingMirror=self.clientCheckingMirrorIsRunning()
450                if clientCheckingMirror!=False:
451                        if clientCheckingMirror:
452                                print("  [Lliurex-up]: Mirror is being udpated in server. Unable to update the system")
453                        else:
454                                print("  [Lliurex-up]: Unable to connect with server")
455
456                        self.lliurexcore.cleanEnvironment()
457                        self.lliurexcore.cleanLliurexUpLock()
458                        return 1
459                       
460                self.initActionsScript(extra_args)
461                self.checkLliurexUp()
462
463                if extra_args["mirror"]:
464                        self.checkMirror(extra_args)
465
466                self.getLliurexVersionLocal()
467                self.getLliurexVersionLliurexNet()
468                self.checkingInitialFlavourToInstall()
469                self.packages=self.getPackagesToUpdate()
470
471                if len(self.packages)>0:
472                        if not self.checkingIncorrectFlavours():
473                                print self.listpackages
474                                print("  [Lliurex-up]: Number of packages to update: " +  str(len(self.packages)) + " (" + str(self.newpackages) + " news)" )
475                                if not extra_args["unattendend_upgrade"]:
476                                        response=raw_input('  [LLiurex-up]: Do you want to update the system (yes/no)): ').lower()
477                                else:
478                                        response="yes"
479
480                                if response.startswith('y'):
481                                        self.preActionsScript(extra_args)
482                                        self.distUpgrade(extra_args)
483                                        self.postActionsScript(extra_args)
484                                        self.checkingFinalFlavourToInstall()   
485                                        self.checkFinalUpgrade()
486                                        self.lliurexcore.cleanEnvironment()
487                                        self.lliurexcore.cleanLliurexUpLock()
488
489
490                                else:
491                                        log_msg="Cancel the update"
492                                        self.log(log_msg)
493                                        print("  [Lliurex-up]: Cancel the update")
494                                        self.lliurexcore.cleanEnvironment()
495                                        self.lliurexcore.cleanLliurexUpLock()
496
497                                        return 0
498                        else:
499                                print("[Lliurex-up]: Updated abort for incorrect flavours detected in new update")
500                                self.lliurexcore.cleanEnvironment()
501                                self.lliurexcore.cleanLliurexUpLock()
502
503                                return 1                       
504                else:
505                        if not self.checkPreviousUpgrade():
506                                print("  [Lliurex-up]: Your system is updated. Nothing to do")
507                                self.lliurexcore.cleanEnvironment()
508                                self.lliurexcore.cleanLliurexUpLock()
509
510                                return 0
511                        else:
512                                print("  [Lliurex-up]: Updated abort. An error occurred checking new updates")
513                                self.lliurexcore.cleanEnvironment()
514                                self.lliurexcore.cleanLliurexUpLock()
515
516                                return 1
517        #def main                       
518                                       
519
520def     usage():
521        puts("Usage")
522        with indent(4):
523                puts("lliurex-upgrade [FLAGS...]")
524                puts("Flags")
525                with indent(4):
526                        puts("-h --help:                Show help")
527                        puts("-s --sai:         Update the system without pinning")     
528                        puts("-u --unattended:  Update the system in unattended mode. Does not require confirmation to update mirror and system")
529                        puts("-n --no-mirror:           Update the system without checking mirror")
530
531        sys.exit(1)             
532
533#def usage
534
535def free_space_check():
536               
537        if ((os.statvfs("/").f_bfree * os.statvfs("/").f_bsize) / (1024*1024*1024)) < 2: #less than 2GB available?
538                print "  [Lliurex-up]: There's not enough space on disk to upgrade (2 GB needed)"
539                       
540                sys.exit(1)
541
542#def free_space_check           
543
544def islliurexup_running():
545
546        if os.path.exists('/var/run/lliurexUp.lock'):
547                print "  [Lliurex-up]: Lliurex Up is now running "
548                sys.exit(1)
549
550#def isllliurexup_running
551
552
553if __name__ == '__main__':
554        if os.geteuid() != 0:
555                print "  [Lliurex-up]: You need be root!"
556                sys.exit(1)
557
558        islliurexup_running()
559        free_space_check()     
560        mode=None
561        options=0       
562        extra_args={}
563        extra_args["mirror"]=True
564        extra_args["unattended_mirror"]=False
565        extra_args["unattendend_upgrade"]=False
566
567        args=arguments.Args().copy
568       
569        if args.contains(["-h", "--help"]):
570                usage()
571       
572        if args.contains(["-s", "--sai"]):
573                mode="sai"
574                options=1
575
576        if args.contains(["-u", "--unattended"]):
577                extra_args["unattendend_upgrade"]=True
578                extra_args["unattended_mirror"]=True
579                options=1
580       
581        if args.contains(["-n", "--no-mirror"]):
582                extra_args["mirror"]=False
583                options=1
584        else:
585                if len(args)>0 and options==0:
586                        usage() 
587       
588        lliurexupcli = LliurexUpCli()   
589        sys.exit(lliurexupcli.main(mode,extra_args))
Note: See TracBrowser for help on using the repository browser.