def fstrim_systemd(): logging.debug('Setting up fstrim timer to run weekly once') with open(FSTRIM_SERVICE, 'w') as sfo: sfo.write('[Unit]\n') sfo.write('Description=Discard unused blocks\n\n') sfo.write('[Service]\n') sfo.write('Type=oneshot\n') sfo.write('ExecStart=/usr/sbin/fstrim -v /\n') sfo.write('ExecStart=/usr/sbin/fstrim -v /boot \n') logging.debug('Created %s' % FSTRIM_SERVICE) with open(FSTRIM_TIMER, 'w') as sto: sto.write('[Unit]\n') sto.write('Description=Discard unused blocks once a week\n') sto.write('Documentation=man:fstrim\n\n') sto.write('[Timer]\n') sto.write('OnCalendar=weekly\n') sto.write('AccuracySec=1h\n') sto.write('Persistent=true\n\n') sto.write('[Install]\n') sto.write('WantedBy=multi-user.target\n') logging.debug('Created %s' % FSTRIM_TIMER) service = '%s.timer' % FSTRIM_NAME systemctl(FSTRIM_NAME, 'enable') logging.info('Enabled %s' % FSTRIM_NAME)
def post(self, request, command=None): with self._handle_exception(request): if (command is not None): if (command != 'send-test-email'): e_msg = ('unknown command(%s) is not supported.' % command) handle_exception(Exception(e_msg), request) if (EmailClient.objects.count() == 0): e_msg = ('E-mail account must be setup first before test ' 'e-mail could be sent') handle_exception(Exception(e_msg), request) eco = EmailClient.objects.all()[0] subject = ('Test message from Rockstor. Appliance id: %s' % Appliance.objects.get(current_appliance=True).uuid) send_test_email(eco, subject) return Response() sender = request.data.get('sender') username = sender.split('@')[0] smtp_server = request.data.get('smtp_server') name = request.data.get('name') password = request.data.get('password') receiver = request.data.get('receiver') eco = EmailClient(smtp_server=smtp_server, name=name, sender=sender, receiver=receiver) eco.save() update_sasl(smtp_server, sender, password) update_forward(receiver) update_postfix(smtp_server) systemctl('postfix', 'restart') return Response(EmailClientSerializer(eco).data)
def main(): loglevel = logging.INFO if (len(sys.argv) > 1 and sys.argv[1] == '-x'): loglevel = logging.DEBUG logging.basicConfig(format='%(asctime)s: %(message)s', level=loglevel) rd = root_disk() logging.debug('Root drive is %s' % rd) do_more = False if (trim_support(rd) is True): do_more = True logging.info('TRIM support is available for %s' % rd) fstrim_systemd() logging.debug('Finished setting up fstrim timer') do_more = do_more or is_flash(rd) if (do_more): update_sysctl() logging.info('updated sysctl') #emable tmpfs on /tmp tmpmnt = 'tmp.mount' systemctl(tmpmnt, 'enable') logging.info('enabled %s' % tmpmnt) systemctl(tmpmnt, 'start') logging.info('started %s' % tmpmnt) #mount stuff with noatime #add noatime to /, /home and /boot in /etc/fstab update_fstab() logging.info('updated fstab') for fs in ROOT_FS: run_command(['mount', fs, '-o', 'remount']) logging.info('remounted %s' % fs)
def delete(self, request): update_sasl('', '', '', revert=True) update_forward('', revert=True) update_postfix('', revert=True) systemctl('postfix', 'restart') EmailClient.objects.all().delete() return Response()
def main(): loglevel = logging.INFO if len(sys.argv) > 1 and sys.argv[1] == "-x": loglevel = logging.DEBUG logging.basicConfig(format="%(asctime)s: %(message)s", level=loglevel) rd = root_disk() logging.debug("Root drive is %s" % rd) do_more = False if trim_support(rd) is True: do_more = True logging.info("TRIM support is available for %s" % rd) fstrim_systemd() logging.debug("Finished setting up fstrim timer") do_more = do_more or is_flash(rd) if do_more: update_sysctl() logging.info("updated sysctl") # emable tmpfs on /tmp tmpmnt = "tmp.mount" systemctl(tmpmnt, "enable") logging.info("enabled %s" % tmpmnt) systemctl(tmpmnt, "start") logging.info("started %s" % tmpmnt) # mount stuff with noatime # add noatime to /, /home and /boot in /etc/fstab update_fstab() logging.info("updated fstab") for fs in ROOT_FS: run_command(["mount", fs, "-o", "remount"]) logging.info("remounted %s" % fs)
def fstrim_systemd(): logging.debug("Setting up fstrim timer to run weekly once") with open(FSTRIM_SERVICE, "w") as sfo: sfo.write("[Unit]\n") sfo.write("Description=Discard unused blocks\n\n") sfo.write("[Service]\n") sfo.write("Type=oneshot\n") sfo.write("ExecStart=/usr/sbin/fstrim -v /\n") sfo.write("ExecStart=/usr/sbin/fstrim -v /boot \n") logging.debug("Created %s" % FSTRIM_SERVICE) with open(FSTRIM_TIMER, "w") as sto: sto.write("[Unit]\n") sto.write("Description=Discard unused blocks once a week\n") sto.write("Documentation=man:fstrim\n\n") sto.write("[Timer]\n") sto.write("OnCalendar=weekly\n") sto.write("AccuracySec=1h\n") sto.write("Persistent=true\n\n") sto.write("[Install]\n") sto.write("WantedBy=multi-user.target\n") logging.debug("Created %s" % FSTRIM_TIMER) systemctl(FSTRIM_NAME, "enable") logging.info("Enabled %s" % FSTRIM_NAME)
def post(self, request, command=None): with self._handle_exception(request): if (command is not None): if (command != 'send-test-email'): e_msg = ('unknown command(%s) is not supported.' % command) handle_exception(Exception(e_msg), request) if (EmailClient.objects.count() == 0): e_msg = ('E-mail account must be setup first before test ' 'e-mail could be sent') handle_exception(Exception(e_msg), request) eco = EmailClient.objects.all()[0] subject = ('Test message from Rockstor. Appliance id: %s' % Appliance.objects.get(current_appliance=True).uuid) send_test_email(eco, subject) return Response() sender = request.data.get('sender') username = sender.split('@')[0] smtp_server = request.data.get('smtp_server') name = request.data.get('name') password = request.data.get('password') receiver = request.data.get('receiver') eco = EmailClient(smtp_server=smtp_server, name=name, sender=sender, receiver=receiver) eco.save() update_sasl(smtp_server, sender, password) update_forward(receiver) update_generic(sender) update_postfix(smtp_server) systemctl('postfix', 'restart') return Response(EmailClientSerializer(eco).data)
def post(self, request, command=None): with self._handle_exception(request): commands_list = ['send-test-email', 'check-smtp-auth'] if (command is not None): if (command not in commands_list): e_msg = ('unknown command(%s) is not supported.' % command) handle_exception(Exception(e_msg), request) if (command == 'send-test-email'): if (EmailClient.objects.count() == 0): e_msg = ( 'E-mail account must be setup first before test ' 'e-mail could be sent') handle_exception(Exception(e_msg), request) eco = EmailClient.objects.all()[0] subject = ( 'Test message from Rockstor. Appliance id: %s' % Appliance.objects.get(current_appliance=True).uuid) send_test_email(eco, subject) return Response() elif (command == 'check-smtp-auth'): mail_auth = {} sender = request.data.get('sender') username = request.data.get('username') mail_auth[ 'username'] = sender if not username else username mail_auth['password'] = request.data.get('password') mail_auth['smtp_server'] = request.data.get('smtp_server') mail_auth['port'] = int(request.data.get('port', 587)) return Response(json.dumps( {'smtp_auth': test_smtp_auth(mail_auth)}), content_type="application/json") sender = request.data.get('sender') username = request.data.get( 'username') #collect new username field username = sender if not username else username #smtp auth - use username or if empty use sender smtp_server = request.data.get('smtp_server') port = int(request.data.get('port', 587)) name = request.data.get('name') password = request.data.get('password') receiver = request.data.get('receiver') eco = EmailClient(smtp_server=smtp_server, port=port, name=name, sender=sender, receiver=receiver, username=username) eco.save() update_sasl(smtp_server, port, username, password) update_forward(receiver) update_generic(sender) update_postfix(smtp_server, port) systemctl('postfix', 'restart') return Response(EmailClientSerializer(eco).data)
def sssd_add_ldap(ldap_params): """ Write to sssd.conf all parameters required for connecting to an ldap server. :param ldap_params: Dict :return: """ # Prepare options to write server = ldap_params["server"] opts = { "ldap_id_use_start_tls": "True", "cache_credentials": "True", "ldap_search_base": "{}".format(ldap_params["basedn"]), "id_provider": "ldap", "auth_provider": "ldap", "chpass_provider": "ldap", "ldap_uri": "{}".format(ldap_params["ldap_uri"]), "ldap_tls_reqcert": "demand", "ldap_tls_cacert": "{}".format(ldap_params["cacertpath"]), "ldap_tls_cacertdir": "{}".format(ldap_params["cacert_dir"]), "enumerate": "{}".format(ldap_params["enumerate"]), } # Write to file fh, npath = mkstemp() with open(SSSD_FILE) as sfo, open(npath, "w") as tfo: sssd_section = False domain_section = False for line in sfo.readlines(): if sssd_section is True: if re.match("domains = ", line) is not None: line = "".join([line.strip(), " {}\n".format(server)]) sssd_section = False elif len(line.strip()) == 0: tfo.write("domains = {}\n".format(server)) sssd_section = False elif domain_section is True: for k, v in opts.items(): if re.match(k, line) is None: tfo.write("{} = {}\n".format(k, v)) elif re.match("\[sssd]", line) is not None: sssd_section = True elif re.match("\[domain/{}]".format(server), line) is not None: domain_section = True tfo.write(line) if domain_section is False: # reached end of file, also coinciding with end of domain section tfo.write("\n[domain/{}]\n".format(server)) for k, v in opts.items(): tfo.write("{} = {}\n".format(k, v)) move(npath, SSSD_FILE) # Set file to rw- --- --- (600) via stat constants. os.chmod(SSSD_FILE, stat.S_IRUSR | stat.S_IWUSR) logger.debug( "The configuration of the {} domain in {} has been updated".format( server, SSSD_FILE ) ) systemctl("sssd", "restart")
def post(self, request, command=None): with self._handle_exception(request): commands_list = ['send-test-email', 'check-smtp-auth'] if (command is not None): if (command not in commands_list): e_msg = ('unknown command(%s) is not supported.' % command) handle_exception(Exception(e_msg), request) if (command == 'send-test-email'): if (EmailClient.objects.count() == 0): e_msg = ('E-mail account must be setup first before ' 'test e-mail could be sent') handle_exception(Exception(e_msg), request) eco = EmailClient.objects.all()[0] subject = ('Test message from Rockstor. Appliance id: %s' % Appliance.objects.get(current_appliance=True).uuid) # noqa E501 send_test_email(eco, subject) return Response() elif (command == 'check-smtp-auth'): mail_auth = {} sender = request.data.get('sender') username = request.data.get('username') mail_auth['username'] = sender if not username else username # noqa E501 mail_auth['password'] = request.data.get('password') mail_auth['smtp_server'] = request.data.get('smtp_server') mail_auth['port'] = int(request.data.get('port', 587)) return Response( json.dumps({'smtp_auth': test_smtp_auth(mail_auth)}), content_type="application/json") sender = request.data.get('sender') # collect new username field username = request.data.get('username') # smtp auth - use username or if empty use sender username = sender if not username else username smtp_server = request.data.get('smtp_server') port = int(request.data.get('port', 587)) name = request.data.get('name') password = request.data.get('password') receiver = request.data.get('receiver') eco = EmailClient(smtp_server=smtp_server, port=port, name=name, sender=sender, receiver=receiver, username=username) eco.save() update_sasl(smtp_server, port, username, password) update_forward(receiver) update_generic(sender) update_postfix(smtp_server, port) systemctl('postfix', 'restart') return Response(EmailClientSerializer(eco).data)
def delete(self, request): update_sasl("", "", "", "", revert=True) update_forward("", revert=True) update_generic("", revert=True) update_postfix("", "", revert=True) disable_sysconfig_mail() update_master() # Not needed as no revert but preserves consistency # Restart ensures service is running, even if not running previously. systemctl("postfix", "restart") EmailClient.objects.all().delete() return Response()
def post(self, request, command): """ execute a command on the service """ service = Service.objects.get(name="nfs") service_name = "nfs-server" if command == "config": # nothing to really configure atm. just save the model try: config = request.data["config"] self._save_config(service, config) except Exception as e: e_msg = ("NFS could not be configured due to the following " "exception. You could try again. %s" % e.__str__()) handle_exception(Exception(e_msg), request) else: try: if command == "stop": systemctl(service_name, "disable") systemctl(service_name, "stop") else: systemctl(service_name, "enable") # chkconfig('rpcbind', 'on') # init_service_op('rpcbind', command) systemctl(service_name, "restart") # init_service_op('nfs', command) except Exception as e: e_msg = "Failed to %s NFS due to this error: %s" % ( command, e.__str__(), ) handle_exception(Exception(e_msg), request) return Response()
def _switch_ntpd(switch): if (switch == 'start'): systemctl('ntpd', 'enable') systemctl('ntpd', 'start') else: systemctl('ntpd', 'disable') systemctl('ntpd', 'stop')
def post(self, request, command): """ execute a command on the service """ with self._handle_exception(request): service = Service.objects.get(name="nis") if command == "config": try: config = request.data["config"] configure_nis(config["domain"], config["server"]) self._save_config(service, config) except Exception as e: logger.exception(e) e_msg = "NIS could not be configured. Try again" handle_exception(Exception(e_msg), request) else: try: if command == "stop": systemctl("ypbind", "disable") systemctl("ypbind", "stop") else: # To instantiate our above config changes in /etc/yp.conf we: run_command(["netconfig", "update", "-f"]) systemctl("ypbind", "enable") systemctl("ypbind", "start") except Exception as e: logger.exception(e) e_msg = "Failed to %s NIS service due to system error." % command handle_exception(Exception(e_msg), request) return Response()
def post(self, request, command): """ execute a command on the service """ service = Service.objects.get(name='nfs') service_name = 'nfs-server' if (command == 'config'): # nothing to really configure atm. just save the model try: config = request.data['config'] self._save_config(service, config) except Exception as e: e_msg = ('NFS could not be configured due to the following ' 'exception. You could try again. %s' % e.__str__()) handle_exception(Exception(e_msg), request) else: try: if (command == 'stop'): systemctl(service_name, 'disable') systemctl(service_name, 'stop') else: systemctl(service_name, 'enable') # chkconfig('rpcbind', 'on') # init_service_op('rpcbind', command) systemctl(service_name, 'restart') # init_service_op('nfs', command) except Exception as e: e_msg = ('Failed to %s NFS due to this error: %s' % (command, e.__str__())) handle_exception(Exception(e_msg), request) return Response()
def _switch_snmp(cls, switch): if (switch == 'start'): systemctl(cls.service_name, 'enable') systemctl(cls.service_name, 'start') else: systemctl(cls.service_name, 'disable') systemctl(cls.service_name, 'stop')
def _switch_snmp(cls, switch): if switch == "start": systemctl(cls.service_name, "enable") systemctl(cls.service_name, "start") else: systemctl(cls.service_name, "disable") systemctl(cls.service_name, "stop")
def post(self, request, command): service = Service.objects.get(name=self.service_name) if command == "config": config = request.data.get("config") self._save_config(service, config) shelltype = config.get("shelltype") css = config.get("css") update_shell_config(shelltype, css) restart_shell(self.service_name) elif command == "start": # Assert config from db to re-establish our config file. # Avoids using package default config on first enable. # TODO: config assert every time is a little heavy / overkill. config = json.loads(service.config) shelltype = config.get("shelltype") css = config.get("css") update_shell_config(shelltype, css) systemctl(self.service_name, "enable") systemctl(self.service_name, "start") elif command == "stop": systemctl(self.service_name, "stop") systemctl(self.service_name, "disable") return Response()
def post(self, request, command): service = Service.objects.get(name=self.name) if command == 'config': config = request.data.get('config', None) root_share = config['root_share'] self._validate_root(request, root_share) self._save_config(service, config) elif command == 'start': try: config = self._get_config(service) except Exception as e: logger.exception(e) e_msg = ('Cannot start without configuration. ' 'Please configure (System->Services) and try again.') handle_exception(Exception(e_msg), request) share = self._validate_root(request, config['root_share']) mnt_pt = '{}{}'.format(settings.MNT_PT, share.name) if not share.is_mounted: mount_share(share, mnt_pt) docker_wrapper = '{}bin/docker-wrapper'.format(settings.ROOT_DIR) distro_id = distro.id() # for Leap 15 <--> Tumbleweed moves. if distro_id not in KNOWN_DISTRO_IDS: distro_id = 'generic' # If openSUSE, source conf file from docker package itself if re.match('opensuse', distro_id) is not None: inf = '/usr/lib/systemd/system/docker.service' else: inf = '{}/docker-{}.service'.format(settings.CONFROOT, distro_id) outf = '/etc/systemd/system/docker.service' with open(inf) as ino, open(outf, 'w') as outo: for l in ino.readlines(): if re.match('ExecStart=', l) is not None: outo.write('{} {}\n'.format( l.strip().replace(DOCKERD, docker_wrapper, 1), mnt_pt)) elif re.match('Type=notify', l) is not None: # Our docker wrapper use need NotifyAccess=all: avoids # "Got notification message from PID ####1, but # reception only permitted for main PID ####2" outo.write(l) outo.write('NotifyAccess=all\n') elif re.match('After=', l) is not None: outo.write('{} {}\n'.format( l.strip(), 'rockstor-bootstrap.service')) else: outo.write(l) if distro_id == 'rockstor': socket_file = '{}/docker.socket'.format(settings.CONFROOT) shutil.copy(socket_file, '/etc/systemd/system/docker.socket') systemctl(self.name, 'enable') systemctl(self.name, 'start') elif command == 'stop': systemctl(self.name, 'stop') systemctl(self.name, 'disable') return Response()
def post(self, request): with self._handle_exception(request): sender = request.data.get('sender') username = sender.split('@')[0] smtp_server = request.data.get('smtp_server') name = request.data.get('name') password = request.data.get('password') receiver = request.data.get('receiver') eco = EmailClient(smtp_server=smtp_server, name=name, sender=sender, receiver=receiver) eco.save() update_sasl(smtp_server, sender, password) update_forward(receiver) update_postfix(smtp_server) systemctl('postfix', 'restart') return Response(EmailClientSerializer(eco).data)
def sssd_update_services(service, remove=False): """ Update the list of sssd services. :param service: String - name of the service to be updated :param remove: Boolean - Remove from list of services if True """ fo, npath = mkstemp() sep = ", " pattern = ["services = "] append_to_line(SSSD_FILE, npath, pattern, service, sep, remove) move(npath, SSSD_FILE) # Set file to rw- --- --- (600) via stat constants. os.chmod(SSSD_FILE, stat.S_IRUSR | stat.S_IWUSR) logger.debug("The {} service has been added to {}".format(service, SSSD_FILE)) systemctl("sssd", "restart")
def _refresh_and_reload(request): try: refresh_afp_config(list(NetatalkShare.objects.all())) return systemctl('netatalk', 'reload-or-restart') except Exception as e: e_msg = ('Failed to reload Netatalk server. Exception: %s' % e.__str__()) handle_exception(Exception(e_msg), request)
def post(self, request, command): service = Service.objects.get(name=self.name) if command == 'config': config = request.data.get('config', None) root_share = config['root_share'] self._validate_root(request, root_share) self._save_config(service, config) elif command == 'start': try: config = self._get_config(service) except Exception as e: logger.exception(e) e_msg = ('Cannot start without configuration. ' 'Please configure (System->Services) and try again.') handle_exception(Exception(e_msg), request) share = self._validate_root(request, config['root_share']) mnt_pt = '{}{}'.format(settings.MNT_PT, share.name) if not share.is_mounted: mount_share(share, mnt_pt) docker_wrapper = '{}bin/docker-wrapper'.format(settings.ROOT_DIR) distro_id = distro.id() # for Leap 15 <--> Tumbleweed moves. if distro_id not in KNOWN_DISTRO_IDS: distro_id = 'generic' # TODO: Consider sourcing /usr/lib/systemd/system/docker.service inf = '{}/docker-{}.service'.format(settings.CONFROOT, distro_id) outf = '/etc/systemd/system/docker.service' with open(inf) as ino, open(outf, 'w') as outo: for l in ino.readlines(): if re.match('ExecStart=', l) is not None: outo.write('{} {}\n'.format( l.strip().replace(DOCKERD, docker_wrapper, 1), mnt_pt)) elif re.match('Type=notify', l) is not None: # Our docker wrapper use need NotifyAccess=all: avoids # "Got notification message from PID ####1, but # reception only permitted for main PID ####2" outo.write(l) outo.write('NotifyAccess=all\n') elif re.match('After=', l) is not None: outo.write('{} {}\n'.format( l.strip(), 'rockstor-bootstrap.service')) else: outo.write(l) if distro_id == 'rockstor': socket_file = '{}/docker.socket'.format(settings.CONFROOT) shutil.copy(socket_file, '/etc/systemd/system/docker.socket') systemctl(self.name, 'enable') systemctl(self.name, 'start') elif command == 'stop': systemctl(self.name, 'stop') systemctl(self.name, 'disable') return Response()
def _refresh_and_reload(request): try: refresh_afp_config(list(NetatalkShare.objects.all())) return systemctl('netatalk', 'reload') except Exception, e: logger.exception(e) e_msg = ('System error occured while reloading Netatalk server') handle_exception(Exception(e_msg), request)
def _rockon_check(request, sname, force): s = Service.objects.get(name='docker') if (s.config is None): return config = json.loads(s.config) if (config.get('root_share') == sname): if (force): #turn off docker service, nullify config. systemctl(s.name, 'stop') systemctl(s.name, 'disable') s.config = None return s.save() e_msg = ('Share(%s) cannot be deleted because it is in use ' 'by Rock-on service. If you must delete anyway, select ' 'the force checkbox and try again.' % sname) handle_exception(Exception(e_msg), request)
def post(self, request, command): service = Service.objects.get(name=self.name) if (command == 'start'): systemctl(self.name, 'enable') systemctl(self.name, 'start') elif (command == 'stop'): systemctl(self.name, 'stop') systemctl(self.name, 'disable') return Response()
def post(self, request, command): Service.objects.get(name=self.name) if command == "start": systemctl(self.name, "enable") systemctl(self.name, "start") elif command == "stop": systemctl(self.name, "stop") systemctl(self.name, "disable") return Response()
def post(self, request): if ('shares' not in request.data): e_msg = 'Must provide share names.' handle_exception(Exception(e_msg), request) shares = [validate_share(s, request) for s in request.data['shares']] description = request.data.get('description', '') if (description == ''): description = self.def_description time_machine = request.data.get('time_machine', 'yes') if (time_machine != 'yes' and time_machine != 'no'): e_msg = ('Time_machine must be yes or no. ' 'Not ({}).').format(time_machine) handle_exception(Exception(e_msg), request) for share in shares: if (NetatalkShare.objects.filter(share=share).exists()): e_msg = ('Share ({}) is already exported ' 'via AFP.').format(share.name) handle_exception(Exception(e_msg), request) try: for share in shares: mnt_pt = ('%s%s' % (settings.MNT_PT, share.name)) cur_description = '%s' % share.name #cur_description = '%s %s' % (share.name, description) if (len(shares) == 1 and description != self.def_description and share.name == ''): cur_description = description afpo = NetatalkShare(share=share, path=mnt_pt, description=cur_description, time_machine=time_machine) afpo.save() if not share.is_mounted: mount_share(share, mnt_pt) refresh_afp_config(list(NetatalkShare.objects.all())) systemctl('netatalk', 'reload-or-restart') return Response() except RockStorAPIException: raise except Exception as e: handle_exception(e, request)
def post(self, request): if ('shares' not in request.data): e_msg = ('Must provide share names') handle_exception(Exception(e_msg), request) shares = [validate_share(s, request) for s in request.data['shares']] description = request.data.get('description', '') if (description == ''): description = self.def_description time_machine = request.data.get('time_machine', 'yes') if (time_machine != 'yes' and time_machine != 'no'): e_msg = ('time_machine must be yes or now. not %s' % time_machine) handle_exception(Exception(e_msg), request) for share in shares: if (NetatalkShare.objects.filter(share=share).exists()): e_msg = ('Share(%s) is already exported via AFP' % share.name) handle_exception(Exception(e_msg), request) try: for share in shares: mnt_pt = ('%s%s' % (settings.MNT_PT, share.name)) cur_description = '%s %s' % (share.name, description) if (len(shares) == 1 and description != self.def_description): cur_description = description afpo = NetatalkShare(share=share, path=mnt_pt, description=cur_description, time_machine=time_machine) afpo.save() if (not is_share_mounted(share.name)): pool_device = Disk.objects.filter(pool=share.pool)[0].name mount_share(share, pool_device, mnt_pt) refresh_afp_config(list(NetatalkShare.objects.all())) systemctl('netatalk', 'reload') return Response() except RockStorAPIException: raise except Exception, e: handle_exception(e, request)
def _rockon_check(request, sname, force): s = Service.objects.get(name='docker') if (s.config is None): return config = json.loads(s.config) if (config.get('root_share') == sname): if (force): # turn off docker service, nullify config. systemctl(s.name, 'stop') systemctl(s.name, 'disable') s.config = None s.save() # delete all rockon metadata. RockOn.objects.all().delete() return e_msg = ('Share ({}) cannot be deleted because it is in use ' 'by the Rock-on service. To override this block select ' 'the force checkbox and try again.').format(sname) handle_exception(Exception(e_msg), request)
def sssd_update_ad(domain, config): """ Add enumerate = True in sssd so user/group lists will be visible on the web-ui. :param domain: String - Domain to which the update should apply :param config: Dict - Active Directory service configuration :return: """ el = "enumerate = True\n" csl = "case_sensitive = True\n" opts = [] if config.get("enumerate") is True: opts.append(el) if config.get("case_sensitive") is True: opts.append(csl) ol = "".join(opts) fh, npath = mkstemp() with open(SSSD_FILE) as sfo, open(npath, "w") as tfo: domain_section = False for line in sfo.readlines(): if domain_section is True: if len(line.strip()) == 0 or line[0] == "[": # empty line or new section without empty line before it. tfo.write(ol) domain_section = False elif re.match("\[domain/%s]" % domain, line) is not None: domain_section = True tfo.write(line) if domain_section is True: # reached end of file, also coinciding with end of domain section tfo.write(ol) move(npath, SSSD_FILE) # Set file to rw- --- --- (600) via stat constants. os.chmod(SSSD_FILE, stat.S_IRUSR | stat.S_IWUSR) logger.debug( "The configuration of the {} domain in {} has been updated".format( domain, SSSD_FILE ) ) systemctl("sssd", "restart")
def post(self, request, command): service = Service.objects.get(name=self.name) if command == "config": config = request.data.get("config", None) root_share = config["root_share"] self._validate_root(request, root_share) self._save_config(service, config) elif command == "start": try: config = self._get_config(service) except Exception as e: logger.exception(e) e_msg = ("Cannot start without configuration. " "Please configure (System->Services) and try again.") handle_exception(Exception(e_msg), request) share = self._validate_root(request, config["root_share"]) mnt_pt = "{}{}".format(settings.MNT_PT, share.name) if not share.is_mounted: mount_share(share, mnt_pt) distro_id = distro.id() # for Leap 15 <--> Tumbleweed moves. if distro_id not in KNOWN_DISTRO_IDS: distro_id = "generic" # Write a custom daemon.json file (openSUSE only) conf_file = "{}/docker-daemon.json".format(settings.CONFROOT) if re.match("opensuse", distro_id) is not None: # Write them to file self._write_docker_daemon_conf(conf_file, mnt_pt, request) # Then write the docker.service file try: self._write_docker_service(distro_id, mnt_pt, conf_file) except Exception as e: logger.exception(e) e_msg = "An error occurred while writing the docker.service file" handle_exception(Exception(e_msg), request) if distro_id == "rockstor": socket_file = "{}/docker.socket".format(settings.CONFROOT) shutil.copy(socket_file, "/etc/systemd/system/docker.socket") systemctl(self.name, "enable") systemctl(self.name, "start") elif command == "stop": systemctl(self.name, "stop") systemctl(self.name, "disable") return Response()
def _update_sssd(domain): #add enumerate = True in sssd so user/group lists will be #visible on the web-ui. el = 'enumerate = True\n' fh, npath = mkstemp() sssd_config = '/etc/sssd/sssd.conf' with open(sssd_config) as sfo, open(npath, 'w') as tfo: domain_section = False for line in sfo.readlines(): if (domain_section is True): if (len(line.strip()) == 0 or line[0] == '['): #empty line or new section without empty line before it. tfo.write(el) domain_section = False elif (re.match('\[domain/%s]' % domain, line) is not None): domain_section = True tfo.write(line) if (domain_section is True): #reached end of file, also coinciding with end of domain section tfo.write(el) shutil.move(npath, sssd_config) systemctl('sssd', 'restart')
def post(self, request, command): """ execute a command on the service """ e_msg = "Failed to %s S.M.A.R.T service due to system error." % command with self._handle_exception(request, e_msg): if not os.path.exists(SMART): install_pkg("smartmontools") if command == "config": service = Service.objects.get(name=self.service_name) config = request.DATA.get("config", {}) logger.debug("config = %s" % config) self._save_config(service, config) if "custom_config" in config: config = config["custom_config"] else: config = "" smart.update_config(config) systemctl(self.service_name, "enable") systemctl(self.service_name, "restart") else: self._switch(command) return Response()
def post(self, request, command): """ execute a command on the service """ e_msg = ('Failed to %s S.M.A.R.T service due to system error.' % command) with self._handle_exception(request, e_msg): if (not os.path.exists(SMART)): install_pkg('smartmontools') if (command == 'config'): service = Service.objects.get(name=self.service_name) config = request.DATA.get('config', {}) logger.debug('config = %s' % config) self._save_config(service, config) if ('smartd_config' in config): config = config['smartd_config'] else: config = '' smart.update_config(config) systemctl(self.service_name, 'enable') systemctl(self.service_name, 'restart') else: self._switch(command) return Response()
def post(self, request, command): service = Service.objects.get(name=self.name) if (command == 'config'): config = request.data.get('config') self._save_config(service, config) shelltype = config.get('shelltype') css = config.get('css') update_shell_config(shelltype, css) restart_shell() elif (command == 'start'): systemctl(self.name, 'enable') systemctl(self.name, 'start') elif (command == 'stop'): systemctl(self.name, 'stop') systemctl(self.name, 'disable') return Response()
def post(self, request, command): service = Service.objects.get(name=self.name) if (command == 'config'): config = request.data.get('config', None) root_share = config['root_share'] self._validate_root(request, root_share) self._save_config(service, config) elif (command == 'start'): try: config = self._get_config(service) except: e_msg = ('Cannot start without configuration. ' 'Please configure(System->Services) and try again.') handle_exception(Exception(e_msg), request) share = self._validate_root(request, config['root_share']) mnt_pt = ('%s%s' % (settings.MNT_PT, share.name)) if (not is_share_mounted(share.name)): pool_device = Disk.objects.filter(pool=share.pool)[0].name mount_share(share, pool_device, mnt_pt) inf = ('%s/docker.service' % (settings.CONFROOT)) outf = '/etc/systemd/system/docker.service' with open(inf) as ino, open(outf, 'w') as outo: for l in ino.readlines(): if (re.match('ExecStart=', l) is not None): outo.write('%s %s\n' % (l.strip(), mnt_pt)) else: outo.write(l) socket_file = ('%s/docker.socket' % (settings.CONFROOT)) shutil.copy(socket_file, '/etc/systemd/system/docker.socket') systemctl(self.name, 'enable') systemctl(self.name, 'start') elif (command == 'stop'): systemctl(self.name, 'stop') systemctl(self.name, 'disable') return Response()
def post(self, request, command): service = Service.objects.get(name=self.name) if command == "config": config = request.data.get("config", None) root_share = config["root_share"] self._validate_root(request, root_share) self._save_config(service, config) elif command == "start": try: config = self._get_config(service) except: e_msg = "Cannot start without configuration. " "Please configure(System->Services) and try again." handle_exception(Exception(e_msg), request) share = self._validate_root(request, config["root_share"]) mnt_pt = "%s%s" % (settings.MNT_PT, share.name) if not is_share_mounted(share.name): mount_share(share, mnt_pt) inf = "%s/docker.service" % (settings.CONFROOT) outf = "/etc/systemd/system/docker.service" with open(inf) as ino, open(outf, "w") as outo: for l in ino.readlines(): if re.match("ExecStart=", l) is not None: outo.write("%s %s\n" % (l.strip(), mnt_pt)) else: outo.write(l) socket_file = "%s/docker.socket" % (settings.CONFROOT) shutil.copy(socket_file, "/etc/systemd/system/docker.socket") systemctl(self.name, "enable") systemctl(self.name, "start") elif command == "stop": systemctl(self.name, "stop") systemctl(self.name, "disable") return Response()
if (command == 'config'): #nothing to really configure atm. just save the model try: config = request.data.get('config', {'workgroup': 'MYGROUP',}) workgroup = config['workgroup'] self._save_config(service, config) update_global_config(workgroup) restart_samba(hard=True) except Exception, e: e_msg = ('Samba could not be configured. Try again. ' 'Exception: %s' % e.__str__()) handle_exception(Exception(e_msg), request) else: try: if (command == 'stop'): systemctl('smb', 'disable') systemctl('nmb', 'disable') else: systemd_name = '%s.service' % service_name ss_dest = ('/etc/systemd/system/%s' % systemd_name) ss_src = ('%s/%s' % (settings.CONFROOT, systemd_name)) sum1 = md5sum(ss_dest) sum2 = md5sum(ss_src) if (sum1 != sum2): shutil.copy(ss_src, ss_dest) systemctl('smb', 'enable') systemctl('nmb', 'enable') systemctl('smb', command) systemctl('nmb', command) except Exception, e: e_msg = ('Failed to %s samba due to a system error: %s' % (command, e.__str__()))
service = Service.objects.get(name='winbind') if (command == 'config'): try: config = request.data['config'] toggle_auth_service('winbind', 'start', config) logger.info('authconfig executed') self._save_config(service, config) except Exception, e: logger.exception(e) e_msg = ('Winbind could not be configured. Try again') handle_exception(Exception(e_msg), request) else: try: toggle_auth_service('winbind', command, config=self._get_config(service)) logger.info('authconfig executed') if (command == 'stop'): systemctl('winbind', 'disable') else: systemctl('winbind', 'enable') systemctl('winbind', command) logger.info('winbind altered') except Exception, e: logger.exception(e) e_msg = ('Failed to %s winbind service due to system error.' % command) handle_exception(Exception(e_msg), request) return Response()
handle_exception(Exception(e_msg), request) try: exports = create_nfs_export_input(NFSExport.objects.all()) logger.info('export = %s' % exports) refresh_nfs_exports(exports) except Exception, e: e_msg = ('Unable to export all nfs shares due to a system' 'error') logger.error(e_msg) logger.exception(e) handle_exception(Exception(e_msg), request) # bootstrap services try: systemctl('firewalld', 'stop') systemctl('firewalld', 'disable') systemctl('nginx', 'stop') systemctl('nginx', 'disable') systemctl('sendmail', 'stop') systemctl('sendmail', 'disable') systemctl('atd', 'enable') systemctl('atd', 'start') except Exception, e: e_msg = ('Unable to bootstrap services due to a system error') logger.error(e_msg) logger.exception(e) handle_exception(Exception(e_msg), request) return Response()
handle_exception(Exception(e_msg), request) try: exports = create_nfs_export_input(NFSExport.objects.all()) logger.info('export = %s' % exports) refresh_nfs_exports(exports) except Exception, e: e_msg = ('Unable to export all nfs shares due to a system' 'error') logger.error(e_msg) logger.exception(e) handle_exception(Exception(e_msg), request) # bootstrap services try: systemctl('firewalld', 'stop') systemctl('firewalld', 'disable') systemctl('nginx', 'stop') systemctl('nginx', 'disable') systemctl('atd', 'enable') systemctl('atd', 'start') except Exception, e: e_msg = ('Unable to bootstrap services due to a system error') logger.error(e_msg) logger.exception(e) handle_exception(Exception(e_msg), request) return Response() elif (command == 'utcnow'): return Response(datetime.utcnow().replace(tzinfo=utc))
cmd += ['--enablewinbindoffline', '--enablewinbindkrb5', '--winbindtemplateshell=/bin/sh',] #general cmd += ['--update', '--enablelocauthorize',] run_command(cmd) workgroup = self._domain_workgroup(domain, method=method) update_global_config(workgroup, domain, config.get('idmap_range'), config.get('rfc2307')) self._join_domain(config, method=method) if (method == 'sssd' and config.get('enumerate') is True): self._update_sssd(domain) so = Service.objects.get(name='smb') so.config = json.dumps({'workgroup': workgroup}) so.save() if (method == 'winbind'): systemctl('winbind', 'enable') systemctl('winbind', 'start') systemctl('smb', 'restart') systemctl('nmb', 'restart') elif (command == 'stop'): config = self._config(service, request) try: self._leave_domain(config, method=method) update_global_config() systemctl('smb', 'restart') systemctl('nmb', 'restart') except Exception, e: e_msg = ('Failed to leave AD domain(%s). Error: %s' % (config.get('domain'), e.__str__())) handle_exception(Exception(e_msg), request)
execute a command on the service """ service = Service.objects.get(name='nfs') service_name = 'nfs-server' if (command == 'config'): #nothing to really configure atm. just save the model try: config = request.data['config'] self._save_config(service, config) except Exception, e: e_msg = ('NFS could not be configured due to the following ' 'exception. You could try again. %s' % e.__str__()) handle_exception(Exception(e_msg), request) else: try: if (command == 'stop'): systemctl(service_name, 'disable') systemctl(service_name, 'stop') else: systemctl(service_name, 'enable') #chkconfig('rpcbind', 'on') #init_service_op('rpcbind', command) systemctl(service_name, 'restart') #init_service_op('nfs', command) except Exception, e: e_msg = ('Failed to %s NFS due to this error: %s' % (command, e.__str__())) handle_exception(Exception(e_msg), request) return Response()
'bootstrap: %s' % e.__str__()) logger.error(e_msg) try: adv_entries = [a.export_str for a in AdvancedNFSExport.objects.all()] exports_d = self.create_adv_nfs_export_input(adv_entries, request) exports = self.create_nfs_export_input(NFSExport.objects.all()) exports.update(exports_d) self.refresh_wrapper(exports, request, logger) except Exception, e: e_msg = ('Exception while bootstrapping NFS: %s' % e.__str__()) logger.error(e_msg) # bootstrap services try: systemctl('firewalld', 'stop') systemctl('firewalld', 'disable') systemctl('nginx', 'stop') systemctl('nginx', 'disable') systemctl('atd', 'enable') systemctl('atd', 'start') except Exception, e: e_msg = ('Exception while setting service statuses during ' 'bootstrap: %s' % e.__str__()) logger.error(e_msg) handle_exception(Exception(e_msg), request) logger.debug('Bootstrap operations completed') return Response() if (command == 'utcnow'):
def post(self, request, command, rtcepoch=None): if (command == 'bootstrap'): self._update_disk_state() self._refresh_pool_state() for p in Pool.objects.all(): if p.disk_set.attached().count() == 0: continue if not p.is_mounted: # Prior _refresh_pool_state() should have ensure a mount. logger.error('Skipping import/update of prior known ' 'shares for pool ({}) as it is not mounted. ' '(see previous errors)' '.'.format(p.name)) continue # Import / update db shares counterpart for managed pool. import_shares(p, request) for share in Share.objects.all(): if share.pool.disk_set.attached().count() == 0: continue if not share.pool.is_mounted: logger.error('Skipping mount of share ({}) as pool () is ' 'not mounted (see previous errors)' '.'.format(share.name, share.pool.name)) continue try: if not share.is_mounted: mnt_pt = ('%s%s' % (settings.MNT_PT, share.name)) mount_share(share, mnt_pt) except Exception as e: e_msg = ('Exception while mounting a share ({}) during ' 'bootstrap: ({}).').format(share.name, e.__str__()) logger.error(e_msg) logger.exception(e) try: import_snapshots(share) except Exception as e: e_msg = ('Exception while importing snapshots of share ' '({}): ({}).').format(share.name, e.__str__()) logger.error(e_msg) logger.exception(e) for snap in Snapshot.objects.all(): if (snap.uvisible): try: mount_snap(snap.share, snap.real_name, snap.qgroup) except Exception as e: e_msg = ('Failed to make the snapshot ({}) visible. ' 'Exception: ({}).').format(snap.real_name, e.__str__()) logger.error(e_msg) mnt_map = sftp_mount_map(settings.SFTP_MNT_ROOT) for sftpo in SFTP.objects.all(): try: sftp_mount(sftpo.share, settings.MNT_PT, settings.SFTP_MNT_ROOT, mnt_map, sftpo.editable) sftp_snap_toggle(sftpo.share) except Exception as e: e_msg = ('Exception while exporting a SFTP share during ' 'bootstrap: ({}).').format(e.__str__()) logger.error(e_msg) try: adv_entries = [a.export_str for a in AdvancedNFSExport.objects.all()] exports_d = self.create_adv_nfs_export_input(adv_entries, request) exports = self.create_nfs_export_input(NFSExport.objects.all()) exports.update(exports_d) self.refresh_wrapper(exports, request, logger) except Exception as e: e_msg = ('Exception while bootstrapping NFS: ' '({}).').format(e.__str__()) logger.error(e_msg) # bootstrap services try: systemctl('firewalld', 'stop') systemctl('firewalld', 'disable') systemctl('nginx', 'stop') systemctl('nginx', 'disable') systemctl('atd', 'enable') systemctl('atd', 'start') except Exception as e: e_msg = ('Exception while setting service statuses during ' 'bootstrap: ({}).').format(e.__str__()) logger.error(e_msg) handle_exception(Exception(e_msg), request) logger.debug('Bootstrap operations completed') return Response() if (command == 'utcnow'): return Response(datetime.utcnow().replace(tzinfo=utc)) if (command == 'uptime'): return Response(uptime()) if (command == 'kernel'): try: return Response(kernel_info(settings.SUPPORTED_KERNEL_VERSION)) except Exception as e: handle_exception(e, request) if (command == 'update-check'): try: subo = None try: subo = UpdateSubscription.objects.get(name='Stable', status='active') except UpdateSubscription.DoesNotExist: try: subo = UpdateSubscription.objects.get(name='Testing', status='active') except UpdateSubscription.DoesNotExist: pass return Response(update_check(subscription=subo)) except Exception as e: e_msg = ('Unable to check update due to a system error: ' '({}).').format(e.__str__()) handle_exception(Exception(e_msg), request) if (command == 'update'): try: # Once again, like on system shutdown/reboot, we filter # incoming requests with request.auth: every update from # WebUI misses request.auth, while yum update requests from # data_collector APIWrapper have it, so we can avoid # an additional command for yum updates if request.auth is None: update_run() else: update_run(yum_update=True) return Response('Done') except Exception as e: e_msg = ('Update failed due to this exception: ' '({}).').format(e.__str__()) handle_exception(Exception(e_msg), request) if (command == 'current-version'): try: return Response(current_version()) except Exception as e: e_msg = ('Unable to check current version due to this ' 'exception: ({}).').format(e.__str__()) handle_exception(Exception(e_msg), request) # default has shutdown and reboot with delay set to now # having normal sytem power off with now = 1 min # reboot and shutdown requests from WebUI don't have request.auth # while same requests over rest api (ex. scheduled tasks) have # an auth token, so if we detect a token we delay with 3 mins # to grant connected WebUI user to close it or cancel shutdown/reboot delay = 'now' if request.auth is not None: delay = 3 if (command == 'shutdown'): msg = 'The system will now be shutdown.' try: # if shutdown request coming from a scheduled task # with rtc wake up time on we set it before # system shutdown starting if rtcepoch is not None: set_system_rtc_wake(rtcepoch) request.session.flush() system_shutdown(delay) except Exception as e: msg = ('Failed to shutdown the system due to a low level ' 'error: ({}).').format(e.__str__()) handle_exception(Exception(msg), request) finally: return Response(msg) if (command == 'reboot'): msg = 'The system will now reboot.' try: request.session.flush() system_reboot(delay) except Exception as e: msg = ('Failed to reboot the system due to a low level ' 'error: ({}).').format(e.__str__()) handle_exception(Exception(msg), request) finally: return Response(msg) if (command == 'suspend'): msg = 'The system will now be suspended to RAM.' try: request.session.flush() set_system_rtc_wake(rtcepoch) system_suspend() except Exception as e: msg = ('Failed to suspend the system due to a low level ' 'error: ({}).').format(e.__str__()) handle_exception(Exception(msg), request) finally: return Response(msg) if (command == 'current-user'): return Response(request.user.username) if (command == 'auto-update-status'): status = True try: status = auto_update_status() except: status = False finally: return Response({'enabled': status, }) if (command == 'enable-auto-update'): try: auto_update(enable=True) return Response({'enabled': True, }) except Exception as e: msg = ('Failed to enable auto update due to this exception: ' '({}).').format(e.__str__()) handle_exception(Exception(msg), request) if (command == 'disable-auto-update'): try: auto_update(enable=False) return Response({'enabled': False, }) except Exception as e: msg = ('Failed to disable auto update due to this exception: ' '({}).').format(e.__str__()) handle_exception(Exception(msg), request) if (command == 'refresh-disk-state'): self._update_disk_state() return Response() if (command == 'refresh-pool-state'): self._refresh_pool_state() return Response() if (command == 'refresh-share-state'): for p in Pool.objects.all(): import_shares(p, request) return Response() if (command == 'refresh-snapshot-state'): for share in Share.objects.all(): import_snapshots(share) return Response()
def post(self, request, command): """ execute a command on the service """ service = Service.objects.get(name=self.service_name) if (command == 'config'): try: config = request.data.get('config', {}) global_config = {} if 'global_config' in config: gc_lines = config['global_config'].split('\n') for l in gc_lines: gc_param = l.strip().split(' = ') if (len(gc_param) == 2): if '=' in gc_param[0]: raise Exception( 'Syntax error, one param has wrong ' 'spaces around equal signs, ' 'please check syntax of ' '\'%s\'' % ''.join(gc_param)) global_config[gc_param[0].strip().lower()] = gc_param[1].strip() # noqa # #E501 Default set current workgroup to one got via samba # config page global_config['workgroup'] = config['workgroup'] else: global_config = config # Check Active Directory config and status if AD configured and # ON set workgroup to AD retrieved workgroup else AD not # running and leave workgroup to one choosen by user adso = Service.objects.get(name='active-directory') adconfig = None adso_status = 1 if (adso.config is not None): adconfig = self._get_config(adso) adso_out, adso_err, adso_status = service_status( 'active-directory', adconfig) if adso_status == 0: global_config['workgroup'] = adconfig['workgroup'] else: adconfig = None self._save_config(service, global_config) update_global_config(global_config, adconfig) restart_samba(hard=True) except Exception as e: e_msg = ('Samba could not be configured. Try again. ' 'Exception: %s' % e.__str__()) handle_exception(Exception(e_msg), request) else: try: if (command == 'stop'): systemctl('smb', 'disable') systemctl('nmb', 'disable') else: systemd_name = '%s.service' % self.service_name ss_dest = ('/etc/systemd/system/%s' % systemd_name) ss_src = ('%s/%s' % (settings.CONFROOT, systemd_name)) sum1 = md5sum(ss_dest) sum2 = md5sum(ss_src) if (sum1 != sum2): shutil.copy(ss_src, ss_dest) systemctl('smb', 'enable') systemctl('nmb', 'enable') systemctl('nmb', command) systemctl('smb', command) except Exception as e: e_msg = ('Failed to %s samba due to a system error: %s' % (command, e.__str__())) handle_exception(Exception(e_msg), request) return Response()