source: lliurex-mirror/trunk/fuentes/n4d-lliurex-mirror.install/usr/share/n4d/python-plugins/MirrorManager.py @ 2137

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

wip

File size: 11.3 KB
Line 
1from jinja2 import Environment
2from jinja2.loaders import FileSystemLoader
3from jinja2 import Template
4
5import tempfile
6
7import os
8import threading
9import datetime
10import pexpect
11import re
12import json
13
14import BaseHTTPServer
15from SimpleHTTPServer import SimpleHTTPRequestHandler
16from multiprocessing import Process
17import socket
18
19
20class MirrorManager:
21
22
23        def __init__(self):
24                #Default values
25                self.defaultpath = '/etc/lliurex-mirror/'
26                self.debmirrorconfpath = os.path.join(self.defaultpath,'debmirror')
27                self.configpath = os.path.join(self.defaultpath,'conf')
28                self.distro="llx16"
29                self.httpd = None
30                self.debmirrorprocess = None
31
32                self.tpl_env = Environment(loader=FileSystemLoader('/usr/share/n4d/templates/lliurex-mirror'))
33                self.update_thread=threading.Thread()
34                self.percentage=(0,None)
35                self.webserverprocess = None
36                self.defaultmirrorinfo = {"status_mirror":"New","last_mirror_date":None,"mirror_size":0,"progress":0}
37               
38        #def init
39       
40        def startup(self,options):
41                self.n4d_vars=objects["VariablesManager"]
42                self.variable=objects["VariablesManager"].get_variable("LLIUREXMIRROR")
43               
44               
45                if self.variable==None:
46                        try:
47                                self.n4d_vars.add_variable("LLIUREXMIRROR",{},"","Lliurex Mirror info variable","n4d-lliurex-mirror")
48                        except Exception as e:
49                                pass
50                       
51                if type(self.variable)!=type({}):
52                        self.variable={}
53               
54                try:
55                        for repo in self.get_available_mirrors()['msg']:
56                                if self.variable.has_key(repo) and self.variable[repo].has_key("status_mirror") and self.variable[repo]["status_mirror"] == "Working":
57                                        if not self.update_thread.isAlive():
58                                                self.variable[repo]["status_mirror"] = "Error"
59                                                self.n4d_vars.set_variable("LLIUREXMIRROR",self.variable)
60                                else:
61                                        if not self.variable.has_key(repo):
62                                                self.variable[repo] = self.defaultmirrorinfo
63                except Exception as e:
64                        pass
65        #def startup
66
67        def apt(self):
68                # executed after apt operations
69                pass
70               
71        #def apt
72       
73        # service test and backup functions #
74       
75        def test(self):
76
77                pass
78               
79        #def test
80       
81        def backup(self):
82
83                pass
84               
85        #def backup
86
87        def restore(self):
88                pass
89        #def restore
90
91        def set_cname(self):
92                #Get template
93                template = self.tpl_env.get_template("cname")
94                list_variables = {}
95               
96                list_variables = self.n4d_vars.get_variable_list(['INTERNAL_DOMAIN','HOSTNAME'])
97                for x in list_variables.keys():
98                        if list_variables[x] == None:
99                                return {'status':False,'msg':'Variable ' + x + ' not defined'}
100                       
101                #Encode vars to UTF-8
102                string_template = template.render(list_variables).encode('UTF-8')
103                #Open template file
104                fd, tmpfilepath = tempfile.mkstemp()
105                new_export_file = open(tmpfilepath,'w')
106                new_export_file.write(string_template)
107                new_export_file.close()
108                os.close(fd)
109                #Write template values
110                n4d_mv(tmpfilepath,'/var/lib/dnsmasq/config/cname-mirror',True,'root','root','0644',False )
111               
112                return {'status':True,'msg':'Set mirror cname'}
113        #def set_cname
114       
115        def update(self,distro=None):
116
117                if distro==None:
118                        distro=self.distro
119       
120                if self.update_thread.is_alive():
121                        return {'status':False,'msg':'Lliurex-mirror (n4d instance) is running'}
122               
123                self.percentage=(0,None)
124                self.update_thread=threading.Thread(target=self._update,args=(distro,))
125                self.update_thread.daemon=True
126                self.update_thread.start()
127               
128                return {'status':True,'msg':'running'}
129
130        #def update
131       
132        def _update(self,distro):
133                if not self.variable.has_key(distro):
134                        self.variable[distro]=self.defaultmirrorinfo
135                # link config debmirror to correct path with distro name
136                self.variable[distro]['status_mirror'] = "Working"
137                self.n4d_vars.set_variable("LLIUREXMIRROR",self.variable)
138                filelog = open('/var/log/lliurex-mirror.log','w')
139                self.build_debmirror_config(distro)
140                os.remove('/etc/debmirror.conf')
141                os.symlink(os.path.join(self.debmirrorconfpath,distro),'/etc/debmirror.conf')
142                self.debmirrorprocess=pexpect.spawn("/usr/bin/debmirror")
143                try:
144                        objects["ZCenterVariables"].add_pulsating_color("lliurexmirror")
145                except:
146                        pass
147                while True:
148                        try:
149                                self.debmirrorprocess.expect('\n')
150                                line =self.debmirrorprocess.before
151                                filelog.write(line)
152                                line1=line.strip("\n")
153                                if line1.startswith("[") and line1[5] == "]":
154                                        self.percentage=(int(line1[1:4].strip()),self.debmirrorprocess.exitstatus)
155                                        self.variable[distro]['progress'] = self.percentage[0]
156                                        self.n4d_vars.set_variable("LLIUREXMIRROR",self.variable)
157                        except pexpect.EOF:
158                                        line1 = self.debmirrorprocess.before
159                                        if line1 != "" and line1.startswith("[") and line1[5] == "]":
160                                                        self.percentage=(int(line1[1:4].strip()),self.debmirrorprocess.exitstatus)
161                                        filelog.write(line1)
162                                        self.debmirrorprocess.close()
163                                        status = self.debmirrorprocess.exitstatus
164                                        self.percentage=(self.percentage[0],status)
165                                        self.variable[distro]['progress'] = self.percentage[0]
166                                        self.variable[distro]['status_mirror'] = "Ok" if status == 0 else "Error"
167                                        self.n4d_vars.set_variable("LLIUREXMIRROR",self.variable)
168                                        break
169                        except Exception as e:
170                                self.variable[distro]['status_mirror'] = "Error"
171                                self.n4d_vars.set_variable("LLIUREXMIRROR",self.variable)
172                                break
173                filelog.close()
174                self.set_mirror_info(distro)
175
176                try:
177                        objects["ZCenterVariables"].remove_pulsating_color("lliurexmirror")
178                except:
179                        pass
180
181        #def _update
182       
183        def is_alive(self):
184                return {'status':self.update_thread.is_alive(),'msg':''}
185        #def is_alive
186
187        def set_mirror_info(self,distro=None):
188               
189                if distro!=None:
190                        distro=distro
191                else:
192                        distro=self.distro
193               
194                configpath = os.path.join(self.configpath, distro + ".json")
195                config = json.load(open(configpath,'r'))
196
197                mirrorpath = config["MIRRORPATH"]
198                #self.n4d_vars.set_variable("ZEROCENTERINTERNAL",self.internal_variable)
199               
200                MIRROR_DATE=datetime.date.today().strftime("%d/%m/%Y")
201                MIRROR_SIZE=self.get_size(mirrorpath)
202               
203                self.variable[distro]["last_mirror_date"]=MIRROR_DATE
204                self.variable[distro]["mirror_size"]=str(MIRROR_SIZE)
205                self.variable[distro]["progress"]=self.percentage[0]
206               
207                print self.n4d_vars.set_variable("LLIUREXMIRROR",self.variable)
208               
209                #set_custom_text(self,app,text):
210                txt="Updated on: " + str(MIRROR_DATE)
211                txt+=" # Size: %.2fGB"%MIRROR_SIZE
212                try:
213                        objects["ZCenterVariables"].set_custom_text("lliurexmirror",txt)
214                        abstract=open('/var/log/lliurex/lliurex-mirror.log','w')
215                        abstract.write(txt+"\n")
216                        abstract.close()
217                except Exception as e:
218                        pass
219
220        #def set_mirror_info(self):
221
222        def get_size(self,start_path = '.'):
223       
224                total_size = 0
225                try:
226                        for dirpath, dirnames, filenames in os.walk(start_path):
227                                for f in filenames:
228                                        fp = os.path.join(dirpath, f)
229                                        total_size += os.path.getsize(fp)
230                                       
231                        total_size/=1024*1024*1024.0
232                        return total_size
233                except:
234                        return 0
235       
236        #def get_size(start_path = '.'):
237       
238        def search_field(self,filepath,fieldname):
239                try:
240                        f = open(filepath,'r')
241                        needle = None
242                        lines = f.readlines()
243                        for x in lines:
244                                        if re.match('\s*'+fieldname,x):
245                                                        needle = x.strip()
246                        return needle
247                except:
248                        return None
249        # def search_field
250       
251        def get_mirror_architecture(self,distro):
252
253                configpath = os.path.join(self.configpath,distro + ".json")
254                config = json.load(open(configpath,'r'))
255                if not os.path.exists(configpath):
256                        return {'status':False,'msg':'not exists debmirror.conf to '+ distro }
257
258                if "ARCHITECTURES" in config.keys():
259                        return {'status':True,'msg':config["ARCHITECTURES"] }
260
261                return {'status':False,'msg':"debmirror.conf hasn't architecture variable" }
262        #def get_mirror_architecture
263       
264        def set_mirror_architecture(self,distro,archs):
265                configpath = os.path.join(self.configpath,distro + ".json")
266               
267                config = json.load(open(configpath,'r'))
268               
269                config['ARCHITECTURES'] = archs
270
271
272                f=open(configpath,"w")
273
274                data=unicode(json.dumps(config,indent=4,encoding="utf-8",ensure_ascii=False)).encode("utf-8")
275                f.write(data)
276                f.close()
277
278                self.build_debmirror_config(distro)
279                return {'status':True,'msg':'set architecture'}
280               
281        #def set_mirror_architecture
282       
283        def get_mirror_orig(self,distro):
284
285                configpath = os.path.join(self.configpath,distro + ".json")
286                config = json.load(open(configpath,'r'))
287                if not os.path.exists(configpath):
288                        return {'status':False,'msg':'not exists debmirror.conf to '+ distro }
289
290                if "URL" in config.keys():
291                        return {'status':True,'msg':config["URL"] }
292                       
293                return {'status':False,'msg':"debmirror.conf hasn't orig variable" }           
294        #def get_mirror_from
295
296        def set_mirror_orig(self,distro,url):
297                configpath = os.path.join(self.configpath, distro + ".json")
298                config = json.load(open(configpath,'r'))
299                config['URL'] = url
300
301                f=open(configpath,"w")
302                data=unicode(json.dumps(config,indent=4,encoding="utf-8",ensure_ascii=False)).encode("utf-8")
303                f.write(data)
304                f.close()
305
306                self.build_debmirror_config(distro)
307                return {'status':True,'msg':'set orig'}
308        #def set_mirror_architecture
309
310        def get_percentage(self,distro):
311                if self.variable.has_key(distro):
312                        return {'status':True,'msg':self.variable[distro]['progress']}
313                else:
314                        return {'status':False,'msg':'this repo nos has been configured'}
315
316        def build_debmirror_config(self,distro):
317                template = self.tpl_env.get_template('debmirror.conf')
318                configpath = os.path.join(self.configpath,distro + ".json")
319                config = json.load(open(configpath,'r'))
320                string_template = template.render(config).encode('utf-8')
321                f = open(os.path.join(self.debmirrorconfpath,distro),'w')
322                f.write(string_template)
323                f.close()
324        #def build_debmirror_config
325       
326        def enable_webserver_into_folder(self,path):
327                s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
328                s.bind(('localhost', 0))
329                addr, port = s.getsockname()
330                s.close()
331                self.webserverprocess = Process(target=self._enable_webserver_into_folder,args=(port,path,))
332                self.webserverprocess.start()
333                return {'status':True,'msg':port}
334        #enable_webserver_into_folder
335
336        def _enable_webserver_into_folder(self,port,path):
337                try:
338                        import os
339                        iface = '127.0.0.1'
340                        sock = (iface,port)
341                        proto = "HTTP/1.0"
342                        os.chdir(path)
343                        handler = SimpleHTTPRequestHandler
344                        handler.protocol_version = proto
345                        self.httpd = BaseHTTPServer.HTTPServer(sock,handler)
346                        self.httpd.serve_forever()
347                except Exception, e:
348                        return None
349        #_enable_webserver_into_folder
350
351        def stop_webserver(self):
352                if self.webserverprocess != None:
353                        self.webserverprocess.terminate()
354                return {'status':True,'msg':'Server stopped'}
355        #stop_webserver
356       
357        def set_checksum_validation(self,distro,status):
358                configpath = os.path.join(self.configpath, distro + ".json")
359                config = json.load(open(configpath,'r'))
360                config['CHK_MD5'] = status
361
362                f=open(configpath,"w")
363                data=unicode(json.dumps(config,indent=4,encoding="utf-8",ensure_ascii=False)).encode("utf-8")
364                f.write(data)
365                f.close()
366
367                self.build_debmirror_config(distro)
368                return {'status':True,'msg':'set checksum validation'}
369        #set_checksum_validation
370       
371        def get_checksum_validation(self,distro):
372
373                configpath = os.path.join(self.configpath,distro + ".json")
374                config = json.load(open(configpath,'r'))
375                if not os.path.exists(configpath):
376                        return {'status':False,'msg':'not exists debmirror.conf to '+ distro }
377                if "IGN_GPG" in config.keys():
378                        return {'status':True,'msg':config["CHK_MD5"] }
379
380                return {'status':False,'msg':"debmirror.conf hasn't orig variable" }
381        #get_checksum_validation
382       
383        def get_available_mirrors(self):
384                versions = os.listdir(self.configpath)
385                versions = [ version.replace('.json','') for version in versions if version.endswith('.json')]
386                return {'status':True,'msg':versions}
387
388        def stopupdate(self):
389                try:
390                        self.debmirrorprocess.terminate()
391                        return {'status':True,'msg':'debmirror stopped'}
392                except Exception as e:
393                        return {'status':False,'msg':str(e)}
394
Note: See TracBrowser for help on using the repository browser.