source: n4d-nfs/trunk/fuentes/install/usr/share/n4d/python-plugins/NfsManager.py @ 1184

Last change on this file since 1184 was 1184, checked in by hectorgh, 3 years ago

minor changes

File size: 5.2 KB
Line 
1import subprocess
2import re
3import os
4import tempfile
5from jinja2 import Environment
6from jinja2.loaders import FileSystemLoader
7from jinja2 import Template
8
9
10class NfsManager:
11       
12        def __init__(self):
13               
14                self.nfs_dir="/etc/exports.d/"
15                self.nfs_file=self.nfs_dir+"net.exports"
16                self.default_options="rw,sync,no_subtree_check"
17                self.regex_pattern="^(/[\-/\w]+)(\s+)((((\d{1,3}\.){3}\d{1,3})|\w+)\((.*)\)(\s+|$))+"
18                self.file_header="#\n# File generated by NfsManager plugin. Do not edit\n#\n\n"
19               
20                self.default_mount_options="rw,hard,intr,nosuid"
21                self.tpl_env = Environment(loader=FileSystemLoader('/usr/share/n4d/templates/nfs'))
22               
23                # LLX TESTING
24                #self.nfs_file="/tmp/exports"
25                #
26               
27                if not os.path.exists(self.nfs_dir):
28                        os.makedirs(self.nfs_dir)
29               
30               
31        #def __init__
32               
33               
34        def parse_exports_file(self,f=None):
35               
36                if f==None:
37                        f=self.nfs_file
38
39                if not os.path.isfile(f):
40                        return {}
41               
42                f=open(f)
43                lines=f.readlines()
44                f.close()
45               
46                exports={}
47               
48                for line in lines:
49                        ret=re.match(self.regex_pattern,line)
50                        if ret:
51                                d,ip_list=ret.group(1),ret.group(3)
52                               
53                                for info in ip_list.split(" "):
54                                        info=info.strip("\n")
55                                        info=info.split("(")
56                                        ip=info[0]
57                                        options=info[1].strip(")")
58                                       
59                                        if d not in exports:
60                                                exports[d]={}
61                                       
62                                        exports[d][ip]=options
63                return exports
64
65       
66        #def parse_exports_file
67       
68
69        def export_directories(self):
70               
71                #ret=os.system("exportfs -ra")
72                p=subprocess.Popen(["exportfs","-ra"],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
73                ret=p.communicate()
74               
75                if p.poll()==0:
76               
77                        return {"status":True , "msg": "NFS shares exported"}
78                       
79                else:
80                       
81                        return {"status":False, "msg":ret[1]}
82               
83        #def export_directories
84
85       
86        def add_share(self,d,ip,options=None):
87               
88                if options==None:
89                        options=self.default_options
90                       
91                exports=self.parse_exports_file()
92       
93                print 1
94       
95                if d not in exports:
96                        exports[d]={}
97                print 2                 
98                exports[d][ip]=options
99                return self.write_exports_file(exports)
100               
101        #def add_share
102       
103       
104        def remove_ip_from_share(self,share,ip):
105               
106                exports=self.parse_exports_file()
107               
108                if share in exports:
109                        if ip in exports[share]:
110                                exports[share].pop(ip)
111                               
112                                self.write_exports_file(exports)
113                               
114                                return {"status":True,"msg":"Removed IP from server"}
115                       
116                        else:
117                                return {"status":False,"msg":"IP not found"}
118                               
119                else:
120                        return {"status":True,"msg":"Share dir. not found"}
121                       
122               
123        #def remove_ip_from_share
124       
125       
126       
127        def write_exports_file(self,exports,f=None):
128               
129                if f==None:
130                        f=self.nfs_file
131                       
132                file_lines=[]
133                file_lines.append(self.file_header)
134                       
135                for d in exports:
136                        line="%s\t\t%s\n"
137                        ip_list=""
138                        for ip in exports[d]:
139                                ip_list+="%s(%s) "%(ip,exports[d][ip])
140                        ip_list=ip_list.rstrip(" ")
141                        file_lines.append(line%(d,ip_list))
142                       
143                file_lines.append("\n")
144               
145                f=open(f,"w")
146                for line in file_lines:
147                        f.write(line)
148                f.close()
149                self.export_directories()
150                return {"status":True,"msg":"NFS exports.d file written"}
151                       
152        #def write_exports_file
153       
154       
155        def configure_mount_on_boot(self,source,target,options=None):
156               
157                if options==None:
158                        options=self.default_mount_options
159                       
160               
161                template_cname = self.tpl_env.get_template("mount.skel")
162                list_variables = {}
163                list_variables["SRC"]=source
164                list_variables["DEST"]=target
165                list_variables["OPTIONS"]=options
166               
167                string_template = template_cname.render(list_variables).encode('UTF-8')
168               
169                fd, tmpfilepath = tempfile.mkstemp()
170                new_export_file = open(tmpfilepath,'w')
171                new_export_file.write(string_template)
172                new_export_file.close()
173                os.close(fd)
174               
175                p=subprocess.Popen(["systemd-escape",target.lstrip("/")],stdout=subprocess.PIPE)
176                file_name=p.communicate()[0].strip("\n")+".mount"
177                file_dest="/lib/systemd/system/"+file_name
178                print tmpfilepath
179                print target.lstrip("/")
180                print file_dest
181               
182                n4d_mv(tmpfilepath,file_dest,True,'root','root','0644',False )
183               
184                os.system("systemctl daemon-reload")
185                o=subprocess.Popen(["systemctl","enable",file_name],stdout=subprocess.PIPE,stderr=subprocess.PIPE).communicate()
186                o2=subprocess.Popen(["systemctl","start",file_name],stdout=subprocess.PIPE,stderr=subprocess.PIPE).communicate()
187               
188                ret=(o,o2)
189               
190                return {"status":True,"msg":ret}
191               
192        #def configure_mount_on_boot
193       
194        def remove_mount_on_boot(self,target):
195               
196                p=subprocess.Popen(["systemd-escape",target.lstrip("/")],stdout=subprocess.PIPE)
197                file_name=p.communicate()[0].strip("\n")+".mount"
198                file_dest="/lib/systemd/system/"+file_name
199               
200                ret=""
201               
202                if os.path.exists(file_dest):
203                        o2=subprocess.Popen(["systemctl","stop",file_name],stdout=subprocess.PIPE,stderr=subprocess.PIPE).communicate()
204                        o=subprocess.Popen(["systemctl","disable",file_name],stdout=subprocess.PIPE,stderr=subprocess.PIPE).communicate()
205                        os.remove(file_dest)
206                        ret=(o,o2)
207                       
208                return {"status":True,"msg":ret}
209               
210        #def remove_mount_on_boot
211       
212        def clean_exports_file(self):
213               
214                if os.path.exists(self.nfs_file):
215                        os.remove(self.nfs_file)
216                        self.export_directories()
217               
218                return {"status":True,"msg":"NfsManager exports.d file is now clean"}
219               
220
221       
222       
223#class NfsManager
224
225if __name__=="__main__":
226       
227        nfsman=NfsManager()
228       
229        #nfsman.add_share("/net","172.20.8.5")
230        nfsman.parse_exports_file()
231        nfsman.remove_ip_from_share("/net","1.2.3.4")
232        nfsman.add_share("/pepito","2.3.4.4","one,two,three")
233        nfsman.configure_mount_on_boot("server:/net","/net/server-sync")
234
Note: See TracBrowser for help on using the repository browser.