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

Last change on this file since 4753 was 4753, checked in by jrpelegrina, 2 years ago

Add new mode to lliurex-upgrade to add mirror and lliurex.net repositories

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