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

Last change on this file since 2388 was 2388, checked in by hectorgh, 3 years ago

renaming file variable

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