source: epi/trunk/fuentes/python3-epi/epimanager.py @ 6711

Last change on this file since 6711 was 6711, checked in by jrpelegrina, 20 months ago

Fix file

File size: 16.7 KB
Line 
1#!/usr/bin/env python3
2
3import os
4import subprocess
5import sys
6import json
7import platform
8#import socket
9import tempfile
10import time
11import datetime
12import urllib.request
13
14import lliurexstore.storeManager as StoreManager
15
16
17class EpiManager:
18       
19        def __init__(self):
20
21
22                self.storeManager=StoreManager.StoreManager()
23                self.reposPath="/etc/apt/sources.list.d/"
24                self.sources_list="epi.list"
25                self.epi_sources=os.path.join(self.reposPath,self.sources_list)
26                self.epi_keyring="/tmp/epi_keyring"
27                                               
28                self.order=0
29                self.epiFiles={}
30                self.arquitecture=False
31                self.update=False
32                self.zomando_name={}
33                self.epi_base={"repository":[],
34                                        "force32" : False,
35                                        "required_x" : False,
36                                        "script": {},
37                                        "depends":"",
38                                        "zomando":"",
39                                        "required_root":False
40                                        }
41
42                #self.read_conf(epi_file)
43       
44               
45        #def __init__   
46
47       
48        def check_connection(self):
49       
50                try:
51                        '''
52                        s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
53                        host=socket.gethostbyname('lliurex.net')
54                        result=s.connect_ex((host, 80))
55                        s.close()
56                        if result:
57                                return False
58                       
59                        return True
60                        '''
61                        #req=urllib.request("http://lliurex.net")
62                        res=urllib.request.urlopen("http://lliurex.net")
63                        return True
64                       
65                except:
66                        return False   
67
68        #def check_connection   
69
70        def read_conf(self,epi_file):
71
72
73                #file=os.path.join(CONF_FOLDER,conf_file)
74                #self.zomando_name[self.order]=os.path.splitext(conf_file)[0]
75               
76                if os.path.exists(epi_file):
77                        f=open(epi_file)
78                        epi_load=json.load(f)
79                        epi_conf=self.epi_base.copy()
80                        f.close()
81                        epi_conf.update(epi_load)
82                        self.epiFiles[self.order]=epi_conf
83                        self.zomando_name[self.order]=epi_conf["zomando"]
84                        try:
85                                if epi_conf["depends"]!="":
86                                        self.order=self.order+1
87                                        self.read_conf(epi_conf["depends"])
88                        except :
89                                pass           
90
91        #def read_conf         
92
93
94        def get_pkg_info(self):
95
96                pkg_list=[]
97                self.pkg_info={}
98                tmp_list=self.epiFiles.copy()
99
100                for item in tmp_list:
101                        pkg_list=[]
102                        #if tmp_list[item]["type"]!="file":
103                        pkg_list=tmp_list[item]["pkg_list"]
104                       
105                        '''
106                        else:
107                               
108                                element={}
109                                element["name"]=tmp_list[item]["name"]
110                                element["key_store"]=tmp_list[item]["key_store"]
111                                pkg_list.append(element)
112                        '''
113                        info=self.get_store_info(pkg_list,item)
114
115                        cont=0
116
117                        for element in pkg_list:
118                                name=element["name"]
119                                if info[name]["status"]=="installed":
120                                        cont=cont+1
121
122                        if cont==len(pkg_list):
123                                if item>0:
124                                        self.epiFiles.pop(item)
125                                        self.zomando_name.pop(item)
126                                else:
127                                        self.epiFiles[item]["status"]="installed"
128                                        self.pkg_info.update(info)
129                        else:
130                                self.epiFiles[item]["status"]="availabled"
131                                self.pkg_info.update(info)     
132
133        #def get_pkg_info                               
134                                                       
135
136        def get_store_info(self,pkg_list,order):                       
137
138                        pkg_info={}
139                        self.getStatus_byscript=False
140
141                        try:
142                                if self.epiFiles[order]["script"]["getStatus"]:
143                                        self.getStatus_byscript=True
144                        except:
145                                pass
146
147                       
148                        for item in pkg_list:
149                                app=item["name"]
150                                name=""
151                                summary=""
152                                status=""
153                                description=""
154                                icon=""
155                                debian_name=""
156                                component=""
157                                try:
158                                        pkg=item["key_store"]
159                                        action="info"
160                                        self.storeManager.execute_action(action,pkg)
161                                        while self.storeManager.is_action_running(action):
162                                                time.sleep(0.2)
163
164                                        ret=self.storeManager.get_status(action)
165
166                                        if ret["status"]==0:
167                                                data=self.storeManager.get_result(action)
168
169                                                if len(data)>0:
170
171                                                        if not self.getStatus_byscript:
172                                                                if (data["info"][0]["state"]) !="":
173                                                                        status=data["info"][0]["state"]
174                                                                else:
175                                                                        status=self.check_pkg_status(app,order)
176                                                        else:
177                                                                status=self.check_pkg_status(app,order)         
178                                                               
179
180                                                        description=data["info"][0]["description"]
181                                                        icon=data["info"][0]["icon"]
182                                                        name=data["info"][0]["name"]
183                                                        summary=data["info"][0]["summary"]
184                                                        debian_name=data["info"][0]["package"]
185                                                        component=data["info"][0]["component"]
186
187                                                else:
188                                                        status=self.check_pkg_status(app,order)         
189                                        else:
190                                                status=self.check_pkg_status(app,order) 
191                               
192                                except:
193                                        status=self.check_pkg_status(app,order) 
194                                                       
195                               
196                                pkg_info[app]={}
197                                pkg_info[app]["debian_name"]=debian_name
198                                pkg_info[app]["component"]=component
199                                pkg_info[app]["status"]=status
200                                pkg_info[app]["description"]=description
201                                pkg_info[app]["icon"]=icon
202                                pkg_info[app]["name"]=name
203                                pkg_info[app]["summary"]=summary
204
205                        return pkg_info
206
207        #def get_store_info                     
208
209        def check_pkg_status(self,pkg,order=None):
210       
211
212                if self.getStatus_byscript:
213                        if order !=None:
214                                if len(self.epiFiles[order]["script"])>0:
215                                        try:
216                                                script=self.epiFiles[order]["script"]["name"]
217                                                if os.path.exists(script):
218                                                        cmd=script +' getStatus ' + pkg;
219                                                        p=subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE)
220                                                        poutput=p.communicate()
221                                                        if len(poutput)>0:
222                                                                if poutput[0].decode("utf-8").split("\n")[0]=='0':
223                                                                        return "installed"
224                                               
225                                        except Exception as e:
226                                                #print (str(e))
227                                                pass
228                else:                                   
229
230                        cmd='dpkg -l '+ pkg + '| grep "^i[i]"'
231                        p=subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
232                        poutput,perror=p.communicate()
233
234                        if len(poutput)>0:
235                                return "installed"
236               
237                               
238                return "available"     
239
240        #def check_pkg_status                                   
241               
242        def check_root(self):
243
244                self.root=False
245
246                try:
247                        f=open("/etc/epi.token","w")
248                        f.close()
249                        os.remove("/etc/epi.token")
250                        self.download_path="/var/cache/epi-downloads"
251                        self.root=True
252                except:
253                        if not os.path.exists(os.path.expanduser("~/.cache/epi-downloads/")):
254                                os.mkdir(os.path.expanduser("~/.cache/epi-downloads/"))
255                        self.download_path=os.path.expanduser("~/.cache/epi-downloads/")
256
257        #def check_root         
258
259
260        def required_root (self):
261
262                cont=0
263
264                if not self.root:
265                        for item in self.epiFiles:
266                                if self.epiFiles[item]["type"]!="file":
267                                        cont=cont+1
268
269                                else:
270                                        if self.epiFiles[item]["required_root"]:
271                                                cont=cont+1
272                                                       
273                        if cont>0:
274                                return True
275                        else:
276                                return False   
277
278                else:
279                        return False           
280
281        #def required_root             
282
283
284       
285        def check_update_repos(self):
286               
287                #Only update repos if needed
288                current_date=datetime.date.today().strftime('%y%m%d')
289                filename='/var/cache/apt/pkgcache.bin'
290                lastmod=os.path.getmtime(filename)
291                lastupdate=datetime.datetime.fromtimestamp(lastmod).strftime('%y%m%d')
292                cmd=""
293
294                if current_date !=lastupdate or self.update:
295                        cmd="LANG=C LANGUAGE=en apt-get update; "
296                else:
297                        for item in self.epi_conf["pkg_list"]:
298                                update_repo=False
299                                app=item["name"]
300                                command="LANG=C LANGUAGE=en apt-cache policy %s"%app
301                                p=subprocess.Popen(command,shell=True, stdout=subprocess.PIPE)
302                                output=p.communicate()
303                                if str(output[0]) != '':
304                                        tmp=str(output[0]).split("\\n")
305                                        if len(tmp)>1:
306                                                if tmp[2].split(":")[1]=="":
307                                                        update_repo=True
308                                                        #cmd="LANG=C LANGUAGE=en apt-get update; "
309                                                        #return cmd
310                                        else:
311                                                update_repo=True
312                                                #cmd="LANG=C LANGUAGE=en apt-get update; "
313                                                #return cmd             
314
315                                else:
316                                        update_repo=True
317
318                                if update_repo: 
319                                        cmd="LANG=C LANGUAGE=en apt-get update; "
320                                        return cmd             
321
322                return cmd
323               
324               
325
326        def check_arquitecture(self):
327
328                self.force32=self.epi_conf['force32']
329                cmd=""
330               
331                if self.force32:
332                        if platform.architecture()[0]=='64bit':
333                                cmd='dpkg --add-architecture i386; '
334                                                               
335                self.arquitecture=True
336                return cmd             
337
338        #def check_arquitecture
339       
340        def add_repository_keys(self,order):
341
342                self.epi_conf=self.epiFiles[order]
343
344                cmd=""
345                self.type=self.epi_conf["type"]
346
347                if self.type=="apt":
348
349                        repos_list=self.epi_conf["repository"]
350
351                        if len(repos_list)>0:
352                                f = open(self.epi_sources,'w')
353                                for item in repos_list:
354                                        if item["url"]!="":
355                                                lines=item["url"].split(";")
356                                                for line in lines:
357                                                        f.write(line+'\n')
358                                        try:
359                                                key_cmd=item["key_cmd"]
360                                                if key_cmd !="":
361                                                        cmd=cmd+key_cmd+';'     
362                                        except Exception as e:
363                                                if len(self.epi_conf["script"])>0:
364                                                        try:
365                                                                if self.epi_conf["script"]["addRepoKeys"]:
366                                                                        script=self.epi_conf["script"]["name"]
367                                                                        if os.path.exists(script):
368                                                                                command=script + ' addRepoKeys;'
369                                                                                cmd=cmd+command
370                                                        except Exception as e:
371                                                                print (str(e))
372                                                                pass
373
374                                f.close()
375                                self.update=True
376
377                       
378                return cmd             
379
380        #def add_repository_keys       
381
382
383        def get_app_version(self,item=None):
384
385                self.force32=self.epi_conf["force32"]
386
387                if self.force32:
388                       
389                        #if self.type=="deb":
390                        version=item["version"]["32b"]
391                        '''
392                        else:
393                                version=self.epi_conf["version"]["32b"]
394                        '''     
395                else:
396                        try:
397                                version=item["version"]["all"]
398                        except Exception as e:
399                                if platform.architecture()[0]=='64bit': 
400                        #if self.type=="deb":
401                        #if item["version"]["all"]=="":
402                                        version=item["version"]["64b"]
403                                else:
404                                        version=item["version"]["32b"]
405                        '''
406                        else:
407                                if self.epi_conf["version"]["all"]=="":
408                                        version=self.epi_conf["version"]["64b"]
409                                else:
410                                        version=self.epi_conf["version"]["all"]                 
411                        '''
412                return version
413
414        #def get_app_version   
415                                               
416        def download_app(self):
417
418                self.manage_download=True
419                self.download_folder={}
420                cmd=""
421
422                self.type=self.epi_conf["type"]
423                if self.type !='apt':
424
425                        self.token_result_download=tempfile.mkstemp("_result_download")
426                       
427                        if self.type=="file":
428                                if len(self.epi_conf["script"])>0:
429                                        try:
430                                                if self.epi_conf["script"]["download"]:
431                                                        script=self.epi_conf["script"]["name"]
432                                                        if os.path.exists(script):
433                                                                cmd=script +' download; echo $? >' + self.token_result_download[1] +';'
434                                                                self.manage_download=False
435                                        except:
436                                                pass                   
437
438                        if self.manage_download:
439
440                                for item in self.epi_conf["pkg_list"]:
441                                        version=self.get_app_version(item)
442                                        if self.type=="deb":
443                                                name=item["name"]+".deb"
444                                                tmp_file=os.path.join(self.download_path,name)
445                                        else:
446                                                try:
447                                                        tmp_file=os.path.join(self.download_path,item["alias_download"])
448                                                except Exception as e: 
449                                                        #name=item["name"]
450                                                        tmp_file=os.path.join(self.download_path,version)
451                               
452                                        url=item["url_download"]
453                                       
454                                        if os.path.exists(tmp_file):
455                                                cmd=cmd+'rm -f '+ tmp_file +';'
456                                        self.download_folder["name"]=tmp_file
457                                        cmd=cmd+'wget ' +url+version + ' --progress=bar:force -O ' + tmp_file +'; '
458                                        #cmd=cmd+'curl -o ' + tmp_file +' -C - '+ url + version
459
460                                cmd=cmd + ' echo $? >' + self.token_result_download[1] +';'     
461                        '''
462                        if self.type=="deb":
463
464                                for item in self.epi_conf["pkg_list"]:
465                                        name=item["name"]+".deb"
466                                        version=self.get_app_version(item)
467                                        url=item["url_download"]
468                                        tmp_file=os.path.join(self.download_path,name)
469                                        if os.path.exists(tmp_file):
470                                                cmd=cmd+'rm -f '+ tmp_file +';'
471                                        self.download_folder["name"]=tmp_file
472                                        #cmd=cmd+'wget ' +url+version + ' --progress=bar:force -O ' + tmp_file
473                                        cmd=cmd+'curl -o ' + tmp_file +' -C - '+ url + version
474
475                                cmd=cmd + '; echo $? >' + self.token_result_download[1] +';'     
476
477                        else:
478                                if self.epi_conf["url_download"]!="":
479                                        name=self.epi_conf["name"]
480                                        version=self.get_app_version()
481                                        url=self.epi_conf["url_download"]
482                                        tmp_file=os.path.join(self.download_path,version)
483                                        if os.path.exists(tmp_file):
484                                                cmd=cmd+'rm -f '+ tmp_file +';'
485                                        self.download_folder["name"]=tmp_file   
486                                        #cmd=cmd+'wget ' +url+version + ' --progress=bar:force -O ' + tmp_file + '; echo $? >' + self.token_result_download[1] +';'
487                                        cmd=cmd+'curl -o ' + tmp_file +' -C - '+ url + version + '; echo $? >' + self.token_result_download[1] +';'
488
489                        '''
490
491                return cmd                     
492                                       
493        #def download_app               
494
495
496        def check_download(self):
497
498               
499                result=True
500
501                if self.type !='apt':
502
503                       
504                        if os.path.exists(self.token_result_download[1]):
505                                file=open(self.token_result_download[1])
506                                content=file.readline()
507                                if '0' not in content:
508                                        result=False
509                                file.close()
510                                os.remove(self.token_result_download[1])
511
512                                if result:     
513                                        if self.manage_download:
514                                                pkgs_todownload=len(self.download_folder)
515                                                cont=0
516
517                                                for item in self.download_folder:
518                                                        if os.path.exists(self.download_folder[item]):
519                                                                cont=cont+1
520
521                                                if cont != pkgs_todownload:
522                                                        result=False
523
524                return result
525
526        #def check_download             
527
528        def preinstall_app(self):
529       
530
531                cmd=""
532
533                if len(self.epi_conf["script"])>0:
534                        self.token_result_preinstall=tempfile.mkstemp("_result_preinstall")
535                        script=self.epi_conf["script"]["name"]
536                        if os.path.exists(script):
537                                cmd=script +' preInstall; echo $? >' + self.token_result_preinstall[1] +';'
538
539                return cmd             
540
541
542        def check_preinstall(self):
543               
544                result=True
545
546                try:
547                        if os.path.exists(self.token_result_preinstall[1]):
548                                file=open(self.token_result_preinstall[1])
549                                content=file.readline()
550                                if '0' not in content:
551                                        result=False
552                                file.close()
553                                os.remove(self.token_result_preinstall[1])
554
555                except:                 
556                        pass
557
558                return result
559
560
561        #def preinstall_app     
562
563        def install_app(self):
564       
565                add_i386=""
566               
567                if not self.arquitecture:
568                        add_i386=self.check_arquitecture()
569
570
571                cmd=""
572               
573                if self.type=="apt":
574
575                        update_repos=self.check_update_repos()
576                        cmd=update_repos+add_i386 + "LANG=C LANGUAGE=en DEBIAN_FRONTEND=noninteractive apt-get install --reinstall --allow-downgrades --allow-remove-essential --allow-change-held-packages --yes "
577                        for item in self.epi_conf["pkg_list"]:
578                                app=item["name"]
579                                cmd=cmd + app +" "
580
581       
582                       
583                elif self.type=="deb":
584                       
585                        cmd=add_i386 + "dpkg -i "
586                        for item in self.epi_conf["pkg_list"]:
587                                name=item["name"]+".deb"
588                                pkg=self.download_folder["name"]
589                                cmd=cmd+pkg +" "
590
591                       
592                else:
593                        self.token_result_install=tempfile.mkstemp("_result")
594                        script=self.epi_conf["script"]["name"]
595                        if os.path.exists(script):
596                                cmd=script + ' installPackage; echo $? >' + self.token_result_install[1]
597
598                cmd=cmd+";"
599                return cmd     
600
601        #def install_app       
602
603
604        def check_install_remove(self,action):
605
606                dpkg_status={}
607                cont=0
608                token=""
609               
610                if action=="install":
611                               
612                        if self.type !="file":
613                                pkgs=self.epi_conf["pkg_list"]
614                       
615                                for item in pkgs:
616                                        status=self.check_pkg_status(item["name"])
617                               
618                                        if status=="installed":
619                                                cont=cont+1
620                               
621                                        dpkg_status[item["name"]]=status
622
623                                if cont==len(pkgs):
624                                        result=True
625               
626                                else:
627                                        result=False
628
629                        else:
630                                token=self.token_result_install[1]     
631                                if os.path.exists(token):
632                                        file=open(token)
633                                        content=file.readline()
634                                        if '0' not in content:
635                                                result=False
636                                        else:
637                                                result=True     
638                                                                               
639                                        file.close()
640                                        os.remove(token)
641
642                else:
643               
644                        if self.epiFiles[0]["type"] !="file":
645                                        pkgs=self.epiFiles[0]["pkg_list"]                       
646                                        for item in pkgs:
647                                                status=self.check_pkg_status(item["name"])
648                                                if status!="installed":
649                                                        cont=cont+1
650                                                dpkg_status[item["name"]]=status
651
652               
653                        token=self.token_result_remove[1]
654                        if os.path.exists(token):
655                                        file=open(token)
656                                        content=file.readline()
657                                        if '0' not in content:
658                                                result=False
659                                        else:
660                                                result=True     
661                                                       
662                                        file.close()
663                                        os.remove(token)
664
665                return dpkg_status,result                       
666
667       
668               
669        #def check_install_remove       
670
671        def postinstall_app(self):
672       
673
674                cmd=""
675               
676                if len(self.epi_conf["script"])>0:
677                        self.token_result_postinstall=tempfile.mkstemp("_result_postinstall")
678                        script=self.epi_conf["script"]["name"]
679                        if os.path.exists(script):
680                                cmd=script + ' postInstall; echo $? >' + self.token_result_postinstall[1] +';'
681
682                return cmd     
683
684        #def postinstall_app   
685       
686        def check_postinstall(self):
687               
688                result=True
689
690                try:
691                        if os.path.exists(self.token_result_postinstall[1]):
692                                file=open(self.token_result_postinstall[1])
693                                content=file.readline()
694                                if '0' not in content:
695                                        result=False
696                                file.close()
697                                os.remove(self.token_result_postinstall[1])
698                except:
699                        pass                   
700
701                return result
702
703        #def check_postinstall 
704
705        def remove_repo_keys(self):
706       
707                if os.path.exists(self.epi_sources):
708                        os.remove(self.epi_sources)     
709
710                if os.path.exists(self.epi_keyring):
711                        os.remove(self.epi_keyring)     
712
713        #def remove_repo_keys   
714
715        def unistall_app(self,order):
716
717                cmd=""
718
719                if self.epiFiles[order]["script"]["remove"]:
720                        self.token_result_remove=tempfile.mkstemp("_result_remove")
721                        script=self.epiFiles[order]["script"]["name"]
722                        if os.path.exists(script):
723                                cmd=script + ' remove; echo $? >' + self.token_result_remove[1] + ';'
724
725                return cmd
726
727        def zerocenter_feedback(self,order,action,result=None):
728
729                zomando_name=self.zomando_name[order]
730
731                if zomando_name!="":
732                        if action=="init":
733                                cmd="zero-center add-pulsating-color " +zomando_name
734                        elif action=="install":
735                                if result:
736                                        cmd="zero-center remove-pulsating-color "+zomando_name + " ;zero-center set-configured " +zomando_name
737                                       
738                                else:
739                                        cmd="zero-center remove-pulsating-color "+zomando_name + " ;zero-center set-failed " +zomando_name
740                        elif action=="uninstall":
741                                if result:
742                                        cmd="zero-center remove-pulsating-color "+zomando_name + " ;zero-center set-non-configured " +zomando_name
743                                else:
744                                        cmd="zero-center remove-pulsating-color "+zomando_name + " ;zero-center set-failed " +zomando_name
745
746                        os.system(cmd)         
747
748        #def zero-center_feedback       
749
750
751#class ApplicationInstallerManager
752
753
754if __name__=="__main__":
755       
756        epi=EpiManager()
Note: See TracBrowser for help on using the repository browser.