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

Last change on this file since 2993 was 2993, checked in by kbut, 3 years ago

add lliurex-up-core folder

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