source: lliurex-mirror/trunk/fuentes/MirrorManager.py @ 1947

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

wip

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