source: llx-netinstall/trunk/fuentes/install.llx-netinstall/usr/share/n4d/python-plugins/NetinstallManager.py @ 3686

Last change on this file since 3686 was 3686, checked in by mabarracus, 4 years ago

Fixed blocking bug when installing without unattended option
Increased password generation
New mirror availability checking before showing netinstall options

File size: 8.6 KB
Line 
1# npackage example  https://svn.lliurex.net/pandora/n4d-ldap/trunk
2# jinja2 http://jinja.pocoo.org/docs/templates
3
4from jinja2 import Environment
5from jinja2.loaders import FileSystemLoader
6from jinja2 import Template
7import tempfile
8import shutil
9import os
10import subprocess
11import string
12import random
13import crypt
14
15class NetinstallManager:
16
17        def __init__(self):
18                #Load template file
19                self.tpl_env = Environment(loader=FileSystemLoader('/usr/share/n4d/templates/netinstall'))
20                self.imagepath="/etc/ltsp/bootopts/"
21                pass
22        #def init
23       
24        def startup(self,options):
25                # executed when launching n4d
26                pass
27               
28        #def startup
29
30        def apt(self):
31                # executed after apt operations
32                pass
33               
34        #def apt
35       
36        # service test and backup functions #
37       
38        def test(self):
39
40                pass
41               
42        #def test
43       
44        def backup(self):
45
46                pass
47               
48        #def test
49       
50        def restore(self):
51
52                pass
53               
54        #def test
55               
56        def load_exports(self):
57                #Get template
58                template_cname = self.tpl_env.get_template("cname")
59                list_variables = {}
60               
61                ###########################
62                #Getting VARS
63                ###########################
64
65                #Obtains INTERNAL_DOMAIN
66                list_variables['INTERNAL_DOMAIN'] = objects['VariablesManager'].get_variable('INTERNAL_DOMAIN')
67                #If INTERNAL_DOMAIN is not defined returns an error
68                if  list_variables['INTERNAL_DOMAIN'] == None:
69                        return {'status':False,'msg':'Variable INTERNAL_DOMAIN not defined'}
70                       
71                #Obtains HOSTNAME
72                list_variables['HOSTNAME'] = objects['VariablesManager'].get_variable('HOSTNAME')
73                #If variable SRV_IP is not defined returns an error
74                if  list_variables['HOSTNAME'] == None:
75                        return {'status':False,'msg':'Variable HOSTNAME not defined'}
76                       
77                #Encode vars to UTF-8
78                string_template = template_cname.render(list_variables).encode('UTF-8')
79                #Open template file
80                fd, tmpfilepath = tempfile.mkstemp()
81                new_export_file = open(tmpfilepath,'w')
82                new_export_file.write(string_template)
83                new_export_file.close()
84                os.close(fd)
85                #Write template values
86                n4d_mv(tmpfilepath,'/var/lib/dnsmasq/config/cname-preseed',True,'root','root','0644',True )
87                subprocess.Popen(['/etc/init.d/dnsmasq','restart'],stdout=subprocess.PIPE).communicate()
88                return {'status':True,'msg':'Exports written'}
89        #def load_exports
90        # ######################### #
91       
92        def getNetinstall(self):
93                '''
94                Reads file /etc/ltsp/bootopts/netinstall and returns true or false
95                '''
96                # 1. /opt/ltsp/name-chroot
97                # 2. /opt/ltsp/images/name-chroot.img
98                # 3. /var/lib/tftpboot/ltsp/name-chroot
99                # if 1,2 and 3 exist -> show
100                # if 1 but not exist 2 or/and 3 -> show with error
101                #
102               
103                json_data=open(self.imagepath+"netinstall.json")
104                data = json.load(json_data)
105                json_data.close()
106                if(data["netinstall_boot"].lower()=="true"):
107                        netinstall='true';
108                else:
109                        netinstall='false';
110               
111                if(data["netinstall_unattended"].lower()=="true"):
112                        unattended='true';
113                else:
114                        unattended='false';
115               
116                if("netinstall_stats" not in data.keys() or data["netinstall_stats"].lower()!="false"):
117                        do_stats='true';
118                else:
119                        do_stats='false';
120               
121                #write the json file
122                ret=self.setNetinstall(data["netinstall_boot"].lower(),data["netinstall_unattended"].lower(),data["netinstall_stats"].lower())
123                if ret['status'].lower() != 'true':
124                    raise Exception('Error setting json file calling setNetinstall')
125               
126                return {"netinstall":netinstall, "unattended":unattended, "stats": do_stats}
127                       
128                       
129        # END def GetNetInstall
130
131        def setNetinstall(self, status, unattended,stats):
132                '''
133                receives data from admin-center form
134                sets option for netinstall int bootopt.json (status and unattended install)
135                '''
136                try:
137                        mirror_var="/var/lib/n4d/variables-dir/LLIUREXMIRROR"
138                        if os.path.isfile(mirror_var):
139                                if (status.lower()=="true" or status.lower()=="false"):
140                                        path_to_write = os.path.join(self.imagepath,"netinstall.json")
141                                        f = open(path_to_write,'w')
142                                        data='{"netinstall_boot":"'+str(status)+'", "netinstall_unattended":"'+str(unattended)+'", "netinstall_stats":"'+str(stats)+'"}'
143                                        f.writelines(data)
144                                        f.close()
145                                       
146                                        # Enable or disable NETINSTALL on menu (the last option, but enabled)
147                                        if (status.lower()=="true"):
148                                                objects["LlxBootManager"].pushToBootList("netinstall")
149                                        else:
150                                                objects["LlxBootManager"].removeFromBootList("netinstall")
151
152                                        # Removing user and password from preseed
153                                        self.setNetinstallUnattended(status, "", "", "")
154                                       
155                                        return {"status":"true", "msg":"all ok"}
156       
157                                else:
158                                        return {"status":"false", "msg":"option not valid"}
159                        else:
160                                        return {"status":"false", "msg":"mirror is not available"}
161                               
162                        #return data;
163                except Exception as e:
164                        return {"status":"false", "msg":str(e)};
165
166                # END def getListTemplate(self, image)
167       
168        def set_force_classroom_stats(self,stats):
169                var_name='STATS_ENABLED'
170                manager = objects['VariablesManager']
171                stats_value = manager.get_variable(var_name)
172               
173                if  stats_value == None:
174                    # Register new variable
175                    ret,msg=manager.add_variable(var_name,'0','','Stats enabled','lliurex-statistics')
176#                   if ret==True:
177#                       ret,msg=manager.init_variable(var_name,'0');
178#                       if ret!=True:
179#                           raise Exception('Error initalizing variable')
180#                   else:
181#                       raise Exception('Error adding variable')
182                if stats.lower() == 'true' or stats == '1':
183                    # Enable
184                    ret,msg=manager.set_variable(var_name,'1')
185                else:
186                    # Disable
187                    ret,msg=manager.set_variable(var_name,'0')
188                if ret != True:
189                    raise Exception('Error setting variable')
190                else:
191                    return True
192        #END def set_force_classroom_stats(self,status)
193       
194        def get_force_classroom_stats(self):
195                var_name='STATS_ENABLED'
196                manager = objects['VariablesManager']
197                stats_value = manager.get_variable(var_name)
198               
199                if  stats_value == None:
200                    # Register new variable
201                    ret,msg=manager.add_variable(var_name,'0','','Stats enabled','lliurex-statistics')
202                    stats_value = manager.get_variable(var_name)
203                    return str(stats_value)
204#                   if ret==True:
205#                       ret,msg=manager.init_variable(var_name,'0');
206#                       if ret!=True:
207#                           raise Exception('Error initalizing variable'+str(ret)+' '+str(msg))
208#                   else:
209#                       raise Exception('Error adding variable')
210                else:
211                    return str(stats_value)
212
213       
214        #END def get_force_classroom_stats(self):
215       
216        def setNetinstallUnattended(self, status, username, password, rootpassword):
217                '''
218                Writing in presseed username and password
219                '''                             
220                if status == True and (not username or not password or not rootpassword):
221                    return {"status":"false", "msg": "Usernames or Passwords can't be an empty string"}
222                try:
223                        filedir="/var/www/preseed"
224                        filepath="/var/www/preseed/unattended.cfg"
225                        filepartman="/var/www/preseed/partman_sda.cfg"
226
227                        if not os.path.exists(filedir):
228                                os.makedirs(filedir)
229                       
230                        preseed=open(filepath,'w')
231                        preseed.write("# LMD Created user account\n")
232                        salt=''.join([random.choice(string.ascii_letters + string.digits) for _ in range(16)])
233                        userpassencrypted=crypt.crypt(str(password),"$6$"+salt+"$")
234                        salt=''.join([random.choice(string.ascii_letters + string.digits) for _ in range(16)])
235                        rootpassencrypted=crypt.crypt(str(rootpassword),"$6$"+salt+"$")
236                       
237                        if(status==True):
238                                # Saving file
239                               
240                                userfullline="d-i passwd/user-fullname string "+str(username)+"\n";
241                                userline="d-i passwd/username string "+str(username)+"\n";
242                                passline="d-i passwd/user-password-crypted password "+str(userpassencrypted)+"\n"
243                               
244                                if (len(rootpassword) > 0):
245                                        rootpassline = "d-i passwd/root-password-crypted password "+str(rootpassencrypted) + "\n"
246                                else:
247                                        rootpassline = "# d-i passwd/root-password-crypted password "+str(rootpassencrypted) + "\n"
248                                       
249                                # Partition preseed
250                                try:
251                                        partman = open(filepartman,'r')
252                                        preseed.writelines(partman.readlines())
253                                        preseed.write("\n")
254                                        partman.close()
255                                except Exception as e:
256                                        return str(e)
257                               
258                        else:
259                                userfullline="#d-i passwd/user-fullname string \n"
260                                userline="#d-i passwd/username string \n"
261                                passline="# d-i passwd/user-password-crypted password \n"
262                                rootpassline = "# d-i passwd/root-password-crypted password \n"
263
264                        preseed.write("# Normal user name\n")
265                        preseed.write(userfullline)
266                        preseed.write(userline)
267                        preseed.write("# Normal user's password, either in clear text\n")
268                        preseed.write("#d-i passwd/user-password password insecure\n")
269                        preseed.write("# Normal user's password encrypted using an MD5 hash.\n")
270                        preseed.write(passline)
271                        preseed.write(rootpassline)
272                       
273                        # Allow weak passwords
274                        preseed.write("d-i user-setup/allow-password-weak boolean true\n")
275                       
276                        preseed.close()
277                       
278                        return {"status":"true", "msg":"all ok"}
279                       
280                except Exception as e:
281                        return {"status":"false", "msg":str(e)}
282
283                # END def getListTemplate(self, image)
284               
285               
286       
287#class N4dProxy
Note: See TracBrowser for help on using the repository browser.