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

Last change on this file since 8035 was 8035, checked in by jrpelegrina, 7 months ago

Change code to manage EULA by package

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