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

Last change on this file was 8725, checked in by jrpelegrina, 14 months ago

Improved internet connection checking

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