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

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

Add unattended mode

  • Property svn:executable set to *
File size: 12.3 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                self.lliurexcore = lliurex.lliurexup.LliurexUpCore()
19                log_msg="------------------------------------------\n"+"LLIUREX-UP-CLI STARTING AT: " + datetime.datetime.today().strftime("%d/%m/%y %H:%M:%S") +"\n------------------------------------------"
20                self.log(log_msg)
21                self.checkInitialFlavour()
22
23       
24        def checkInitialFlavour(self):
25
26                self.targetMetapackage=self.lliurexcore.checkInitialFlavour()
27                log_msg="Initial check metapackage. Metapackage to install: " + str(self.targetMetapackage)
28                self.log(log_msg)
29                log_msg="Get initial flavours: " + str(self.lliurexcore.previousFlavours)
30                self.log(log_msg)
31               
32
33        def canConnectToLliurexNet(self):
34
35                print("  [Lliurex-up]: Checking connection to lliurex.net")
36                can_connect=self.lliurexcore.canConnectToLliurexNet()
37                if can_connect:
38                                log_msg="Can connect to lliurex.net: True"
39                                self.log(log_msg)
40                                return True
41                else:
42                        log_msg="Can connect to lliurex.net: False"
43                        self.log(log_msg)
44
45                        if "lliurex-meta-server" == self.targetMetapackage or "server" in self.lliurexcore.previousFlavours:
46                                self.lliurexcore.cleanEnvironment()
47                                return False
48                        else:
49                                return True
50
51        def initActionsScript(self):
52
53                print("  [Lliurex-up]: Checking system")
54               
55                command=self.lliurexcore.initActionsScript(self.initActionsArg)
56               
57                try:
58                        #os.system(command)
59                        subprocess.Popen(command,shell=True).communicate()
60                        log_msg="Exec Init-Actions"
61                        self.log(log_msg)       
62                except Exception as e:
63                        log_msg="Exec Init-Actions.Error: " +str(e)
64                        self.log(log_msg)
65                        print e         
66
67        def checkLliurexUp(self):
68
69                print("  [Lliurex-up]: Looking for new version of Lliurex-up")
70
71                is_lliurexup_updated=self.lliurexcore.isLliurexUpIsUpdated()
72
73
74                if not is_lliurexup_updated:
75                        print ("  [Lliurex-up]: Updating Lliurex-up")
76                        is_lliurexup_installed=self.lliurexcore.installLliurexUp()
77                        log_msg="Installing lliurex-up. Returncode: " + str(is_lliurexup_installed['returncode']) + ". Error: " + str(is_lliurexup_installed['stderrs'])
78                        self.log(log_msg)
79                        print ("  [Lliurex-up]: Lliurex-up is now udpate and will be reboot now" )
80                        time.sleep(3)
81                        os.execv("/usr/sbin/lliurex-upgrade",sys.argv) 
82
83                else:
84                        log_msg="Checking lliurex-up. Is lliurex-up updated: "+ str(is_lliurexup_updated)
85                        self.log(log_msg)
86                        print ("  [Lliurex-up]: Lliurex-up is updated.Nothing to do")   
87
88
89        def checkMirror(self,extra_args=None):
90
91                print("  [Lliurex-up]: Checking if mirror is updated")
92
93                is_mirror_updated=self.lliurexcore.lliurexMirrorIsUpdated()
94
95                if is_mirror_updated !=None:
96                        is_mirror_running=self.lliurexcore.lliurexMirrorIsRunning()
97                        if is_mirror_running:
98                                print("  [Lliurex-up]: Updating mirror. Wait a moment please")
99                                command='lliurex-mirror update llx16'
100                                #os.system(command)
101                                subprocess.Popen(command,shell=True).communicate()
102
103                        else:
104                                if is_mirror_updated['action']=='update':
105                                        log_msg="Checking mirror. Is mirror update: False"
106                                        self.log(log_msg)
107                                        if not is_mirror_running:
108                                                if not extra_args["unattended_mirror"]:
109                                                        response=raw_input('  [LLiurex-up]: Do you want update mirror (yes/no): ').lower()
110                                                else:
111                                                        response="yes"
112
113                                                if response.startswith('y'):
114                                                        log_msg="Update lliurex-mirror: Yes"
115                                                        self.log(log_msg)
116                                                        print("  [Lliurex-up]: Updating mirror. Wait a moment please")
117                                                        command='lliurex-mirror update llx16'
118                                                        #os.system(command)
119                                                        subprocess.Popen(command,shell=True).communicate()
120
121                                                else:
122                                                        log_msg="Update lliurex-mirror: No"
123                                                        self.log(log_msg)
124                                                        print("  [Lliurex-up]: Mirror update.Nothing to do")           
125                else:
126                        log_msg="Checking mirror. Is mirror update: None"
127                        self.log(log_msg)
128                        print("  [Lliurex-up]: Nothing to do with mirror")
129
130        def getLliurexVersionLocal(self):
131
132                print("  [Lliurex-up]: Looking for LliurexVersion from local repository")
133               
134                self.version_update=self.lliurexcore.getLliurexVersionLocal()
135                log_msg="Get LliurexVersion installed: " + str(self.version_update["installed"])
136                self.log(log_msg)
137                log_msg="Get LliurexVersion candidate from Local repository: " + str(self.version_update["candidate"])
138                self.log(log_msg)               
139       
140
141        def getLliurexVersionLliurexNet(self):
142       
143                print("  [Lliurex-up]: Looking for LliurexVersion from lliurex.net")
144
145                self.version_available=self.lliurexcore.getLliurexVersionLliurexNet()
146                log_msg="Get LliurexVersion candidate from Lliurex Net: " + str(self.version_available["candidate"])
147                self.log(log_msg)
148
149        def checkingInitialFlavourToInstall(self):
150
151                print("  [Lliurex-up]: Checking if installation of metapackage is required")
152
153                self.returncode_initflavour=0
154
155                if self.targetMetapackage == None:
156                       
157                        print "  [Lliurex-up]: Installation of metapackage is not required"
158                       
159                else:
160                        print "  [Lliurex-up]: Installation of metapackage is required: " + str(self.targetMetapackage)
161                        is_flavour_installed=self.lliurexcore.installInitialFlavour(self.targetMetapackage)     
162                        self.returncode_initflavour=is_flavour_installed['returncode']
163                        error=is_flavour_installed['stderrs']
164                        log_msg="Install initial metapackage:" + self.targetMetapackage + ": Returncode: " + str(self.returncode_initflavour) + " Error: " + str(error)
165                        self.log(log_msg)
166                        print "  [Lliurex-up]: Metapackage is now installed: " + str(self.returncode_initflavour) + " Error: " + str(error)
167
168       
169        def getPackagesToUpdate(self):
170
171                print("  [Lliurex-up]: Looking for new updates")
172                packages=self.lliurexcore.getPackagesToUpdate()
173                log_msg="Get packages to update. Number of packages: "+ str(len(packages))
174                self.log(log_msg)
175
176                self.newpackages=0
177                self.listpackages=""
178                if (len(packages))>0:
179                        for item in packages:
180                                if packages[item]["install"]==None:
181                                                self.newpackages=int(self.newpackages) + 1
182                                self.listpackages=str(self.listpackages) + item +" "           
183
184                return packages
185                       
186        def checkingIncorrectFlavours(self):
187               
188                incorrectFlavours=self.lliurexcore.checkIncorrectFlavours()
189                log_msg="Checking incorrect metapackages. Others metapackages detected: " + str(incorrectFlavours)
190                self.log(log_msg)
191
192                return incorrectFlavours
193               
194
195        def checkPreviousUpgrade(self):
196               
197                error=False
198                if self.returncode_initflavour!=0:
199                        error=True
200
201                else:
202                        if self.version_update["candidate"]!=None:
203                                if self.version_update["installed"]!=self.version_update["candidate"]:
204                                        error=True
205                        else:
206                                if self.version_update["installed"]!=self.version_available["candidate"]:       
207                                        error=True
208
209                return error                   
210
211        def preActionsScript(self):
212
213                print("  [Lliurex-up]: Preparing system to update")
214
215                command=self.lliurexcore.preActionsScript()
216                try:
217                        #os.system(command)
218                        subprocess.Popen(command,shell=True).communicate()
219                        log_msg="Exec Pre-Actions"
220                        self.log(log_msg)
221
222                except Exception as e:
223                        log_msg="Exec Pre-Actions. Error " +str(e)
224                        self.log(log_msg)
225                        print e
226
227        def distUpgrade(self):
228
229                print("  [Lliurex-up]: Downloading and installing packages")
230
231                command=self.lliurexcore.distUpgradeProcess()
232                try:
233                        #os.system(command)
234                        subprocess.Popen(command,shell=True).communicate()
235                        log_msg="Exec Dist-uggrade"
236                        self.log(log_msg)
237                except Exception as e:
238                        log_msg="Exec Dist-uggrade.Error : " +str(e)
239                        self.log(log_msg)
240                        print e
241
242        def postActionsScript(self):
243
244                print("  [Lliurex-up]: Ending the update")
245                command=self.lliurexcore.postActionsScript()+'| tee ' + self.lliurexcore.errorpostaction_token
246                try:
247                        subprocess.Popen(command,shell=True).communicate()
248                        #os.system(command)
249                        log_msg="Exec Post-Actions"
250                        self.log(log_msg)
251                except Exception as e:
252                        print e                         
253
254
255        def checkingFinalFlavourToInstall(self):
256               
257                print("  [Lliurex-up]: Checking final metapackage")
258
259                #self.flavourToInstall=self.lliurexcore.checkFinalFlavour()
260                self.flavourToInstall=self.lliurexcore.checkFlavour()
261
262                log_msg="Final check metapackage. Metapackage to install: " + str(self.flavourToInstall)
263                self.log(log_msg)
264               
265                if self.flavourToInstall!=None:
266                        print ("  [Lliurex-up]: Install of metapackage is required: " + str(self.flavourToInstall))
267                       
268                        command=self.lliurexcore.installFinalFlavour(self.flavourToInstall)
269                        try:
270                                #os.system(command)
271                                subprocess.Popen(command,shell=True).communicate()
272
273                        except Exception as e:
274                                print e
275                else:
276                        print ("  [Lliurex-up]: Metapackage is correct. Nothing to do")
277                                       
278        def checkFinalUpgrade(self):
279
280                print("  [Lliurex-up]: Checking Dist-upgrade ")
281                error=self.lliurexcore.checkErrorDistUpgrade()
282
283                if error:
284                        print("  [Lliurex-up]: The updated process is endend with errors")
285                        log_msg="Dist-upgrade process ending with errors"
286               
287                else:                                   
288                        print("  [Lliurex-up]: The system is now update")       
289                        log_msg="Dist-upgrade process ending OK"
290               
291                self.log(log_msg)
292
293        def log(self,msg):
294               
295                log_file="/var/log/lliurex-up.log"
296                f=open(log_file,"a+")
297                f.write(msg + '\n')
298                f.close()       
299
300       
301        def main(self,mode,extra_args=None):
302
303                if mode=="sai":
304                        self.initActionsArg="initActionsSai"
305                       
306                else:
307                        mode="nomal"
308                        self.initActionsArg="initActions"       
309
310                log_msg="Mode of execution: " + str(mode)
311                self.log(log_msg)
312                log_msg="Extra args: " + str(extra_args)
313                self.log(log_msg)
314                       
315                if not self.canConnectToLliurexNet():
316                        print("  [Lliurex-up]: Unable to connect to lliurex.net")
317                        return 1
318
319                self.initActionsScript()
320                self.checkLliurexUp()
321
322                if extra_args["mirror"]:
323                        self.checkMirror(extra_args)
324
325                self.getLliurexVersionLocal()
326                self.getLliurexVersionLliurexNet()
327                self.checkingInitialFlavourToInstall()
328                self.packages=self.getPackagesToUpdate()
329
330                if len(self.packages)>0:
331                        if not self.checkingIncorrectFlavours():
332                                print self.listpackages
333                                print("  [Lliurex-up]: Number of packages to update: " +  str(len(self.packages)) + " (" + str(self.newpackages) + " news)" )
334                                if not extra_args["unattendend_upgrade"]:
335                                        response=raw_input('  [LLiurex-up]: Do you want to update the system (yes/no)): ').lower()
336                                else:
337                                        response="yes"
338
339                                if response.startswith('y'):
340                                        self.preActionsScript()
341                                        self.distUpgrade()
342                                        self.postActionsScript()
343                                        self.checkingFinalFlavourToInstall()   
344                                        self.checkFinalUpgrade()
345                                        self.lliurexcore.cleanEnvironment()
346
347                                else:
348                                        log_msg="Cancel the update"
349                                        self.log(log_msg)
350                                        print("  [Lliurex-up]: Cancel the update")
351                                        self.lliurexcore.cleanEnvironment()
352                                        return 0
353                        else:
354                                print("[Lliurex-up]: Updated abort for incorrect flavours detected in new update")
355                                self.lliurexcore.cleanEnvironment()
356                                return 1                       
357                else:
358                        if not self.checkPreviousUpgrade():
359                                print("  [Lliurex-up]: Your systems is updated. Nothing to do")
360                                self.lliurexcore.cleanEnvironment()
361                                return 0
362                        else:
363                                print("  [Lliurex-up]: Updated abort. An error occurred checking new updates")
364                                self.lliurexcore.cleanEnvironment()
365                                return 1
366                                       
367
368def     usage():
369        puts("Usage")
370        with indent(4):
371                puts("lliurex-upgrade [FLAGS...]")
372                puts("Flags")
373                with indent(4):
374                        puts("<without Flags> : Update the system in attended mode. Requires confirmation to update mirror and system")
375                        puts("-h --help: Show help")
376                        puts("-s --sai: Update the system without pinning")     
377                        puts("-u --unattended: Update the system in unattended mode. Does not require confirmation to update mirror and system")
378                        puts("-n --no-mirror: Update the system without checking mirror")
379
380        sys.exit(1)             
381
382
383def free_space_check():
384               
385                if ((os.statvfs("/").f_bfree * os.statvfs("/").f_bsize) / (1024*1024*1024)) < 2: #less than 2GB available?
386                        print "  [Lliurex-up]: There's not enough space on disk to upgrade (2 GB needed)"
387                       
388                        sys.exit(1)
389
390if __name__ == '__main__':
391        if os.geteuid() != 0:
392                print "  [Lliurex-up]: You need be root!"
393                sys.exit(1)
394
395        free_space_check()     
396        mode=None
397        options=0       
398        extra_args={}
399        extra_args["mirror"]=True
400        extra_args["unattended_mirror"]=False
401        extra_args["unattendend_upgrade"]=False
402
403        args=arguments.Args().copy
404       
405        if args.contains(["-h", "--help"]):
406                usage()
407       
408        if args.contains(["-s", "--sai"]):
409                mode="sai"
410                options=1
411
412        if args.contains(["-u", "--unattended"]):
413                extra_args["unattendend_upgrade"]=True
414                extra_args["unattended_mirror"]=True
415                options=1
416       
417        if args.contains(["-n", "--no-mirror"]):
418                extra_args["mirror"]=False
419                options=1
420        else:
421                if len(args)>0 and options==0:
422                        usage() 
423       
424        lliurexupcli = LliurexUpCli()   
425        sys.exit(lliurexupcli.main(mode,extra_args))
Note: See TracBrowser for help on using the repository browser.