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

Last change on this file since 1960 was 1960, checked in by kbut, 4 years ago

add new function to list available mirrors

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