source: lliurex-up/trunk/fuentes/LliurexUpCore.py @ 3139

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

WIP in new gui. Add init Actions

File size: 9.8 KB
Line 
1import xmlrpclib 
2import os
3import shutil
4import subprocess
5import socket
6import distutils.dir_util
7
8class LliurexUpCore(object):
9        """docstring for LliurexUpCore"""
10        def __init__(self):
11                super(LliurexUpCore, self).__init__()
12                self.defaultMirror = 'llx16'
13                self.defaultVersion = 'xenial'
14                self.processPath = '/var/run/lliurex-up'
15                self.changelogsPath = os.path.join(self.processPath,'changelogs')
16                self.processSourceslist = os.path.join(self.processPath,'sourceslist')
17                self.targetMetapackagePath=os.path.join(self.processPath,"targetMetapackage")
18                self.previousflavourspath = os.path.join(self.processPath,'previousflavours')
19                self.initActionsPath='/usr/share/lliurex-up/initActions'
20                self.preActionsPath = '/usr/share/lliurex-up/preActions'
21                self.postActionsPath = '/usr/share/lliurex-up/postActions'
22
23                self.n4d = xmlrpclib.ServerProxy('https://localhost:9779')
24                self.haveLliurexMirror = False
25                self.metapackageRef=[]
26                self.previuosFlavours = []
27                self.getTargetMetapackage()
28                self.flavours = []
29                self.getPreviuosFlavours()
30                if len(self.n4d.get_methods('MirrorManager')) > 0:
31                        self.haveLliurexMirror = True
32                self.prepareEnvironment()
33
34        def getPreviuosFlavours(self):
35               
36                if os.path.exists(self.previousflavourspath):
37                        aux = open(self.previousflavourspath,'r')
38                        lines = aux.readlines()
39                        for x in lines:
40                                self.previuosFlavours.append(x.strip())
41                        aux.close()
42
43
44        def getTargetMetapackage(self):
45
46                if os.path.exists(self.targetMetapackagePath):
47                        aux = open(self.targetMetapackagePath,'r')
48                        lines = aux.readlines()
49                        for x in lines:
50                                self.metapackageRef.append(x.strip())
51                        aux.close()             
52
53        def saveTargetMetapackage(self,targetMetapackage):
54
55                aux=open(self.targetMetapackagePath,'w')
56                x=targetMetapackage.split("-")[2]
57                aux.write(x+"\n")
58                x="edu"
59                aux.write(x+"\n")
60                aux.close()
61               
62
63        def updateFlavoursList(self):
64                self.flavours = [ x.strip() for x in self.n4d.lliurex_version('','LliurexVersion','-v')[1].split(',') ]
65                if len(self.flavours) > 0:
66                        aux = open(self.previousflavourspath,'w')
67                        for x in self.flavours:
68                                aux.write(x+"\n")
69                        aux.close()
70
71        def writeDefaultSourceslist(self):
72                f = open(os.path.join(self.processSourceslist,'default'),'w')
73                f.write('deb http://lliurex.net/{version} {version} main\n'.format(version=self.defaultVersion))
74                f.write('deb http://lliurex.net/{version} {version}-updates main\n'.format(version=self.defaultVersion))
75                f.write('deb http://lliurex.net/{version} {version}-security main\n'.format(version=self.defaultVersion))
76                f.close()
77
78        def prepareEnvironment(self):
79                '''
80                        This funcion delete all environment and rebuild environment
81                '''
82                if not os.path.exists(self.processPath):
83                        os.mkdir(self.processPath)
84                if not os.path.exists(self.processSourceslist):
85                        os.mkdir(self.processSourceslist)
86                if not os.path.exists(self.changelogsPath):
87                        os.mkdir(self.changelogsPath)
88                self.writeDefaultSourceslist()
89
90        def cleanEnvironment(self):
91                if os.path.exists(self.processPath):
92                        shutil.rmtree(os.path.join(self.processPath))
93
94
95        def updateCacheApt(self,options=""):
96                command = "LANG=C apt-get update {options}".format(options=options)
97                subprocess.Popen(command,shell=True).communicate()
98
99
100        def getPackageVersionAvailable(self,package,options=""):
101                '''
102                        Args :
103                                package String
104                                options String
105
106                        return dictionary => result
107                        result : {'installed':String,'candidate':String}
108
109                        Options are Apt options
110                '''
111                command = "LANG=C apt-cache policy {package} {options}".format(package=package,options=options)
112                p = subprocess.Popen(command,shell=True,stdout=subprocess.PIPE)
113                installed = None
114                candidate = None
115                for line in iter(p.stdout.readline,""):
116                        stripedline = line.strip()
117                        if stripedline.startswith("Installed"):
118                                installed = stripedline.replace("Installed: ","")
119                        if stripedline.startswith("Candidate"):
120                                candidate = stripedline.replace("Candidate: ","")
121                return {"installed":installed,"candidate":candidate}
122
123        def isLliurexUpIsUpdated(self):
124                '''
125                        return Boolean
126                '''
127                sourceslistDefaultPath = os.path.join(self.processSourceslist,'default')
128                options = ""
129                if self.canConnectToLliurexNet():
130                        options = "-o Dir::Etc::sourcelist={sourceslistOnlyLliurex} -o Dir::Etc::sourceparts=/dev/null".format(sourceslistOnlyLliurex=sourceslistDefaultPath)
131               
132                self.updateCacheApt(options)
133                result = self.getPackageVersionAvailable('lliurex-up',options)
134
135                if result['installed'] != result['candidate']:
136                        return False
137                return True
138
139        def installLliurexUp(self,options=""):
140                '''
141                        Args :
142                                options String
143                        return dictionary => result
144                        result : {'returncode':Int,'stdout':String,'stderr':String}
145
146                        options are Apt options
147                       
148
149                        This function install lliurex-up
150                '''
151                command = "LANG=C apt-get install lliurex-up {options}".format(options=options)
152                p = subprocess.Popen(command,shell=True,stdout=subprocess.PIPE)
153                poutput,perror = p.communicate()
154                return {'returncode':p.returncode,'stdout':poutput,'stderrs':perror}
155
156        def lliurexMirrorIsUpdated(self):
157                '''
158                        return None | dictionary => result
159                        result : {'status':Boolean,'msg':String,'action':String}
160                        result.msg : message of status
161                        result.action : Action to launch
162                '''
163                if self.haveLliurexMirror and 'server' in self.flavours :
164                        result = self.n4d.is_update_available('','MirrorManager',self.defaultMirror)
165                        return result
166                return None
167
168        def lliurexMirrorIsRunning(self):
169                '''
170                        return Boolean
171                '''
172                if self.haveLliurexMirror and 'server' in self.flavours :
173                        result = self.n4d.is_alive('','MirrorManager')
174                        return result['status']
175                return False
176
177        def getPercentageLliurexMirror(self):
178                '''
179                        return int | None
180                '''
181                if self.haveLliurexMirror and 'server' in self.flavours:
182                        result = self.n4d.get_percentage('','MirrorManager',self.defaultMirror)
183                        if result['status']:
184                                return result['msg']
185                return None
186       
187        def checkFlavour(self):
188                '''
189                        return None|String
190                        If metapackages has been uninstalled, this function return
191                        package to must install. If return None, you are ok and don't need
192                        install anything.
193                '''
194                self.updateFlavoursList()
195                targetMetapackage = None
196                if 'None' in self.flavours:
197                        # get last flavour
198                        result = self.n4d.lliurex_version('','LliurexVersion','--history')
199                        if result[0]:
200                                history = [ x.strip().split('\t')[0].strip() for x in result[1].split('\n') ]
201                                history = [ x for x in history if not 'lliurex-meta-live' in x ]
202                                for x in reversed(history):
203                                        if x.startswith('-'):
204                                                targetMetapackage = x[2:]
205                                                break
206
207                if targetMetapackage !=None:
208                        self.saveTargetMetapackage(targetMetapackage)                           
209                return targetMetapackage
210
211        def canConnectToLliurexNet(self):
212                '''
213                        return Boolean
214                '''
215                s =  socket.socket(socket.AF_INET, socket.SOCK_STREAM)
216                host = socket.gethostbyname('lliurex.net')
217                result = s.connect_ex((host, 80))
218                s.close()
219                if result:
220                        return False
221                return True
222
223        def getLliurexVersionLliurexNet(self):
224                '''
225                        return dictionary => result
226                        result : {'installed':String,'candidate':String}
227                '''
228                sourceslistDefaultPath = os.path.join(self.processSourceslist,'default')
229                options = ""
230                if self.canConnectToLliurexNet():
231                        options = "-o Dir::Etc::sourcelist={sourceslistOnlyLliurex} -o Dir::Etc::sourceparts=/dev/null".format(sourceslistOnlyLliurex=sourceslistDefaultPath)
232                self.updateCacheApt(options)
233                return self.getPackageVersionAvailable('lliurex-version-timestamp',options)
234
235        def getLliurexVersionLocal(self):
236                self.updateCacheApt('')
237                return self.getPackageVersionAvailable('lliurex-version-timestamp','')         
238
239        def initActionsScript(self):
240                return 'run-parts --arg="initActions" ' + self.initActionsPath
241
242        def preActionsScript(self):
243                return 'run-parts --arg="preActions" ' + self.preActionsPath
244
245        def postActionsScript(self):
246                return 'run-parts --arg="postActions" ' + self.postActionsPath
247
248
249        def installInitialFlavour(self,flavourToInstall,options=""):
250                '''
251                        Args :
252                                flavourToInstall String
253                                options String
254                        return dictionary => result
255                        result : {'returncode':Int,'stdout':String,'stderr':String}
256
257                        options are Apt options
258                       
259
260                        This function install lliurex-up
261                '''
262                command = "LANG=C apt-get install " + flavourToInstall + "{options} ".format(options=options)
263                p = subprocess.Popen(command,shell=True,stdout=subprocess.PIPE)
264                poutput,perror = p.communicate()
265                return {'returncode':p.returncode,'stdout':poutput,'stderrs':perror}   
266
267        def getPackagesToUpdate(self):
268                '''
269                        packageInfo definition
270                        {
271                                'PACKAGENAME' : {
272                                                'install' : 'INSTALLEDVERSION',
273                                                'candidate' : 'CANDIDATEVERSION',
274                                                'icon' : 'ICONNAME',
275                                                'changelog' : 'CHANGELOGTEXT'
276                                }
277                        }
278                '''
279                packageInfo = {}
280                self.updateCacheApt("")
281                psimulate = subprocess.Popen('LANG=C apt-get dist-upgrade -sV',shell=True,stdout=subprocess.PIPE)
282                rawoutputpsimulate = psimulate.stdout.readlines()
283                rawpackagestoinstall = [ aux.strip() for aux in rawoutputpsimulate if aux.startswith('Inst') ]
284                r = [ aux.replace('Inst ','') for aux in rawpackagestoinstall ]
285                for allinfo in r :
286                        packageInfo[allinfo.split(' ')[0]] = {}
287                        packageInfo[allinfo.split(' ')[0]]['raw'] = ' '.join(allinfo.split(' ')[1:])
288
289                for package in packageInfo:
290                        raw = packageInfo[package]['raw'].split(' ')
291                        if raw[0].startswith('['):
292                                packageInfo[package]['install'] = raw[0][1:-1]
293                                packageInfo[package]['candidate'] = raw[1][1:]
294                        elif raw[0].startswith('('):
295                                packageInfo[package]['install'] = None
296                                packageInfo[package]['candidate'] = raw[0][1:]
297                        packageInfo[package].pop('raw')
298                        packageInfo[package]['changelog'] = os.path.join(self.changelogsPath,package)
299                        os.system('LANG=C apt-get changelog %s > %s%s'%(package,self.changelogsPath,package))
300                        packageInfo[package]['icon'] = 
301                return packageInfo
302
303
304        def distUpgradeProcess(self):
305       
306                return 'apt-get dist-upgrade --yes --force-yes'
307
308
309        def installFinalFlavour(self,flavourToInstall):
310
311                return 'apt-get install ' + flavourToInstall + ' --yes --force-yes'
312               
313       
314
315if __name__ == '__main__':
316        x = LliurexUpCore()
Note: See TracBrowser for help on using the repository browser.