def delete(self, request, id): try: sftpo = SFTP.objects.get(id=id) except: e_msg = ('SFTP config for the id(%s) does not exist' % id) handle_exception(Exception(e_msg), request) try: mnt_prefix = ('%s%s/' % (settings.SFTP_MNT_ROOT, sftpo.share.owner)) if (is_share_mounted(sftpo.share.name, mnt_prefix)): sftp_snap_toggle(sftpo.share, mount=False) mnt_pt = ('%s%s' % (mnt_prefix, sftpo.share.name)) umount_root(mnt_pt) if (os.path.isdir(mnt_pt)): shutil.rmtree(mnt_pt) sftpo.delete() input_map = {} for so in SFTP.objects.all(): if (so.id != sftpo.id): input_map[so.share.owner] = ( '%s%s' % (settings.SFTP_MNT_ROOT, so.share.owner)) update_sftp_config(input_map) return Response() except RockStorAPIException: raise except Exception, e: handle_exception(e, request)
def post(self, request): if ('shares' not in request.DATA): e_msg = ('Cannot export without specifying shares') handle_exception(Exception(e_msg), request) shares = [validate_share(s, request) for s in request.DATA['shares']] try: options = parse_options(request) for s in shares: dup_export_check(s, options['host_str'], request) cur_exports = list(NFSExport.objects.all()) eg = NFSExportGroup(**options) eg.save() for s in shares: mnt_pt = ('%s%s' % (settings.MNT_PT, s.name)) export_pt = ('%s%s' % (settings.NFS_EXPORT_ROOT, s.name)) if (not is_share_mounted(s.name)): pool_device = Disk.objects.filter(pool=s.pool)[0].name mount_share(s.subvol_name, pool_device, mnt_pt) export = NFSExport(export_group=eg, share=s, mount=export_pt) export.full_clean() export.save() cur_exports.append(export) exports = create_nfs_export_input(cur_exports) refresh_wrapper(exports, request, logger) nfs_serializer = NFSExportGroupSerializer(eg) return Response(nfs_serializer.data) except RockStorAPIException: raise except Exception, e: handle_exception(e, request)
def post(self, request): with self._handle_exception(request): if ('shares' not in request.data): e_msg = ('Cannot export without specifying shares') handle_exception(Exception(e_msg), request) shares = [ validate_share(s, request) for s in request.data['shares'] ] options = parse_options(request) for s in shares: dup_export_check(s, options['host_str'], request) cur_exports = list(NFSExport.objects.all()) eg = NFSExportGroup(**options) eg.save() for s in shares: mnt_pt = ('%s%s' % (settings.MNT_PT, s.name)) export_pt = ('%s%s' % (settings.NFS_EXPORT_ROOT, s.name)) if (not is_share_mounted(s.name)): pool_device = Disk.objects.filter(pool=s.pool)[0].name mount_share(s, pool_device, mnt_pt) export = NFSExport(export_group=eg, share=s, mount=export_pt) export.full_clean() export.save() cur_exports.append(export) exports = create_nfs_export_input(cur_exports) adv_entries = [ e.export_str for e in AdvancedNFSExport.objects.all() ] exports_d = create_adv_nfs_export_input(adv_entries, request) exports.update(exports_d) refresh_wrapper(exports, request, logger) nfs_serializer = NFSExportGroupSerializer(eg) return Response(nfs_serializer.data)
def post(self, request, sname): with self._handle_exception(request): share = Share.objects.get(name=sname) options = { 'owner': 'root', 'group': 'root', 'perms': '755', 'orecursive': True, 'precursive': True, } options['owner'] = request.data.get('owner', options['owner']) options['group'] = request.data.get('group', options['group']) options['perms'] = request.data.get('perms', options['perms']) options['orecursive'] = request.data.get('orecursive', options['orecursive']) options['precursive'] = request.data.get('precursive', options['precursive']) share.owner = options['owner'] share.group = options['group'] share.perms = options['perms'] share.save() mnt_pt = ('%s%s' % (settings.MNT_PT, share.name)) force_mount = False if (not is_share_mounted(share.name)): mount_share(share, mnt_pt) force_mount = True chown(mnt_pt, options['owner'], options['group'], options['orecursive']) chmod(mnt_pt, options['perms'], options['precursive']) if (force_mount is True): umount_root(mnt_pt) return Response(ShareSerializer(share).data)
def post(self, request, sname): with self._handle_exception(request): share = Share.objects.get(name=sname) options = { 'owner': 'root', 'group': 'root', 'perms': '755', 'orecursive': True, 'precursive': True, } options['owner'] = request.data.get('owner', options['owner']) options['group'] = request.data.get('group', options['group']) options['perms'] = request.data.get('perms', options['perms']) options['orecursive'] = request.data.get('orecursive', options['orecursive']) options['precursive'] = request.data.get('precursive', options['precursive']) share.owner = options['owner'] share.group = options['group'] share.perms = options['perms'] share.save() mnt_pt = ('%s%s' % (settings.MNT_PT, share.name)) force_mount = False if (not is_share_mounted(share.name)): pool_device = Disk.objects.filter(pool=share.pool)[0].name mount_share(share, pool_device, mnt_pt) force_mount = True chown(mnt_pt, options['owner'], options['group'], options['orecursive']) chmod(mnt_pt, options['perms'], options['precursive']) if (force_mount is True): umount_root(mnt_pt) return Response(ShareSerializer(share).data)
def delete(self, request, id): try: sftpo = SFTP.objects.get(id=id) except: e_msg = ('SFTP config for the id(%s) does not exist' % id) handle_exception(Exception(e_msg), request) try: mnt_prefix = ('%s%s/' % (settings.SFTP_MNT_ROOT, sftpo.share.owner)) if (is_share_mounted(sftpo.share.name, mnt_prefix)): sftp_snap_toggle(sftpo.share, mount=False) umount_root(('%s%s' % (mnt_prefix, sftpo.share.name))) import shutil shutil.rmtree(mnt_prefix) sftpo.delete() input_list = [] for so in SFTP.objects.all(): if (so.id != sftpo.id): input_list.append({ 'user': so.share.owner, 'dir': ('%s%s' % (settings.SFTP_MNT_ROOT, so.share.name)), }) update_sftp_config(input_list) return Response() except RockStorAPIException: raise except Exception, e: handle_exception(e, request)
def delete(self, request, sname, export_id): try: share = Share.objects.get(name=sname) if (not NFSExport.objects.filter(id=export_id).exists()): e_msg = ('NFS export with id: %d does not exist' % export_id) handle_exception(Exception(e_msg), request) export = NFSExport.objects.get(id=export_id) if (len(NFSExport.objects.filter(share=share)) == 1): export_mnt_pt = ('/export/%s' % sname) umount_root(export_mnt_pt) if (is_share_mounted(sname, mnt_prefix='/export/')): e_msg = ('Cannot delete nfs export with id: %d due to ' 'busy mount. Try again later.' % export_id) handle_exception(Exception(e_msg), request) export.enabled = False exports = self._create_nfs_export_input(export) export.delete() refresh_nfs_exports(exports) return Response() except RockStorAPIException: raise except Exception, e: handle_exception(e, request)
def post(self, request, command): if (command == 'bootstrap'): try: for share in Share.objects.all(): if (not is_share_mounted(share.name)): mnt_pt = ('%s%s' % (settings.MNT_PT, share.name)) pool_device = Disk.objects.filter( pool=share.pool)[0].name mount_share(share.subvol_name, pool_device, mnt_pt) except Exception, e: e_msg = ('Unable to mount a share(%s, %s) during bootstrap.' % (pool_device, mnt_pt)) logger.error(e_msg) logger.exception(e) handle_exception(Exception(e_msg), request) try: mnt_map = sftp_mount_map(settings.SFTP_MNT_ROOT) for sftpo in SFTP.objects.all(): sftp_mount(sftpo.share, settings.MNT_PT, settings.SFTP_MNT_ROOT, mnt_map, sftpo.editable) sftp_snap_toggle(sftpo.share) except Exception, e: e_msg = ('Unable to export all sftp shares due to a system' ' error') logger.error(e_msg) logger.exception(e) handle_exception(Exception(e_msg), request)
def post(self, request, sname): with self._handle_exception(request): share = Share.objects.get(name=sname) options = {"owner": "root", "group": "root", "perms": "755", "orecursive": True, "precursive": True} options["owner"] = request.data.get("owner", options["owner"]) options["group"] = request.data.get("group", options["group"]) options["perms"] = request.data.get("perms", options["perms"]) options["orecursive"] = request.data.get("orecursive", options["orecursive"]) options["precursive"] = request.data.get("precursive", options["precursive"]) share.owner = options["owner"] share.group = options["group"] share.perms = options["perms"] share.save() mnt_pt = "%s%s" % (settings.MNT_PT, share.name) force_mount = False if not is_share_mounted(share.name): pool_device = Disk.objects.filter(pool=share.pool)[0].name mount_share(share, pool_device, mnt_pt) force_mount = True chown(mnt_pt, options["owner"], options["group"], options["orecursive"]) chmod(mnt_pt, options["perms"], options["precursive"]) if force_mount is True: umount_root(mnt_pt) return Response(ShareSerializer(share).data)
def delete(self, request, id): with self._handle_exception(request): try: sftpo = SFTP.objects.get(id=id) except: e_msg = ( "SFTP config for the id ({}) does not exist.").format(id) handle_exception(Exception(e_msg), request) mnt_prefix = "{}{}/".format(settings.SFTP_MNT_ROOT, sftpo.share.owner) if is_share_mounted(sftpo.share.name, mnt_prefix): sftp_snap_toggle(sftpo.share, mount=False) mnt_pt = "{}{}".format(mnt_prefix, sftpo.share.name) umount_root(mnt_pt) if os.path.isdir(mnt_pt): shutil.rmtree(mnt_pt) sftpo.delete() input_map = {} for so in SFTP.objects.all(): if so.id != sftpo.id: input_map[so.share.owner] = "{}{}".format( settings.SFTP_MNT_ROOT, so.share.owner, ) update_sftp_config(input_map) 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 = [ self._validate_share(request, s) for s in request.data['shares'] ] options = self._validate_input(request) custom_config = options['custom_config'] del (options['custom_config']) for share in shares: if (SambaShare.objects.filter(share=share).exists()): e_msg = ('Share(%s) is already exported via Samba' % share.name) handle_exception(Exception(e_msg), request) with self._handle_exception(request): for share in shares: mnt_pt = ('%s%s' % (settings.MNT_PT, share.name)) options['share'] = share options['path'] = mnt_pt smb_share = SambaShare(**options) smb_share.save() for cc in custom_config: cco = SambaCustomConfig(smb_share=smb_share, custom_config=cc) cco.save() if (not is_share_mounted(share.name)): mount_share(share, mnt_pt) admin_users = request.data.get('admin_users', []) if (admin_users is None): admin_users = [] self._set_admin_users(admin_users, smb_share) refresh_smb_config(list(SambaShare.objects.all())) self._restart_samba() return Response(SambaShareSerializer(smb_share).data)
def _toggle_visibility(self, share, snap_name, on=True): cur_exports = list(NFSExport.objects.all()) snap_short_name = snap_name.split(share.name)[-1][1:] snap_mnt_pt = ('%s%s/.%s' % (settings.MNT_PT, share.name, snap_short_name)) export_pt = snap_mnt_pt.replace(settings.MNT_PT, settings.NFS_EXPORT_ROOT) if (on): pool_device = Disk.objects.filter(pool=share.pool)[0].name if (not is_share_mounted(share.name)): share_mnt_pt = ('%s%s' % (settings.MNT_PT, share.name)) mount_share(share.subvol_name, pool_device, share_mnt_pt) mount_share(snap_name, pool_device, snap_mnt_pt) if (NFSExport.objects.filter(share=share).exists()): se = NFSExport.objects.filter(share=share)[0] export_group = NFSExportGroup( host_str=se.export_group.host_str, nohide=True) export_group.save() export = NFSExport(share=share, export_group=export_group, mount=snap_mnt_pt) export.full_clean() export.save() cur_exports.append(export) else: try: export = NFSExport.objects.get(share=share, mount=snap_mnt_pt) cur_exports.remove(export) export.export_group.delete() export.delete() except Exception, e: logger.exception(e) finally:
def post(self, request): with self._handle_exception(request): if ('shares' not in request.data): e_msg = ('Cannot export without specifying shares') handle_exception(Exception(e_msg), request) shares = [validate_share(s, request) for s in request.data['shares']] options = parse_options(request) for s in shares: dup_export_check(s, options['host_str'], request) cur_exports = list(NFSExport.objects.all()) eg = NFSExportGroup(**options) eg.save() for s in shares: mnt_pt = ('%s%s' % (settings.MNT_PT, s.name)) export_pt = ('%s%s' % (settings.NFS_EXPORT_ROOT, s.name)) if (not is_share_mounted(s.name)): pool_device = Disk.objects.filter(pool=s.pool)[0].name mount_share(s, pool_device, mnt_pt) export = NFSExport(export_group=eg, share=s, mount=export_pt) export.full_clean() export.save() cur_exports.append(export) exports = create_nfs_export_input(cur_exports) adv_entries = [e.export_str for e in AdvancedNFSExport.objects.all()] exports_d = create_adv_nfs_export_input(adv_entries, request) exports.update(exports_d) refresh_wrapper(exports, request, logger) nfs_serializer = NFSExportGroupSerializer(eg) return Response(nfs_serializer.data)
def post(self, request, sname): try: share = validate_share(sname, request) options = parse_options(request) dup_export_check(share, options['host_str'], request) cur_exports = list(NFSExport.objects.all()) eg = NFSExportGroup(**options) eg.save() mnt_pt = ('%s%s' % (settings.MNT_PT, share.name)) export_pt = ('%s%s' % (settings.NFS_EXPORT_ROOT, share.name)) if (not is_share_mounted(share.name)): pool_device = Disk.objects.filter(pool=share.pool)[0].name mount_share(share.subvol_name, pool_device, mnt_pt) export = NFSExport(export_group=eg, share=share, mount=export_pt) export.full_clean() export.save() cur_exports.append(export) exports = create_nfs_export_input(cur_exports) refresh_wrapper(exports, request, logger) nfs_serializer = NFSExportGroupSerializer(eg) return Response(nfs_serializer.data) except RockStorAPIException: raise except Exception, e: handle_exception(e, request)
def create_adv_nfs_export_input(exports, request): exports_d = {} for e in exports: fields = e.split() if (len(fields) < 2): e_msg = ('Invalid exports input -- %s' % e) handle_exception(Exception(e_msg), request) share = fields[0].split('/')[-1] s = validate_share(share, request) mnt_pt = ('%s%s' % (settings.MNT_PT, s.name)) if (not is_share_mounted(s.name)): pool_device = Disk.objects.filter(pool=s.pool)[0].name mount_share(s, pool_device, mnt_pt) exports_d[fields[0]] = [] for f in fields[1:]: cf = f.split('(') if (len(cf) != 2 or cf[1][-1] != ')'): e_msg = ('Invalid exports input -- %s. offending ' 'section: %s' % (e, f)) handle_exception(Exception(e_msg), request) exports_d[fields[0]].append({ 'client_str': cf[0], 'option_list': cf[1][:-1], 'mnt_pt': ('%s%s' % (settings.MNT_PT, share)) }) return exports_d
def post(self, request): if ('shares' not in request.data): e_msg = ('Must provide share names') handle_exception(Exception(e_msg), request) shares = [self._validate_share(request, s) for s in request.data['shares']] options = self._validate_input(request) custom_config = options['custom_config'] del(options['custom_config']) for share in shares: if (SambaShare.objects.filter(share=share).exists()): e_msg = ('Share(%s) is already exported via Samba' % share.name) handle_exception(Exception(e_msg), request) with self._handle_exception(request): for share in shares: mnt_pt = ('%s%s' % (settings.MNT_PT, share.name)) options['share'] = share options['path'] = mnt_pt smb_share = SambaShare(**options) smb_share.save() for cc in custom_config: cco = SambaCustomConfig(smb_share=smb_share, custom_config=cc) cco.save() if (not is_share_mounted(share.name)): mount_share(share, mnt_pt) admin_users = request.data.get('admin_users', []) if (admin_users is None): admin_users = [] self._set_admin_users(admin_users, smb_share) refresh_smb_config(list(SambaShare.objects.all())) self._restart_samba() return Response(SambaShareSerializer(smb_share).data)
def delete(self, request, id): try: sftpo = SFTP.objects.get(id=id) except: e_msg = ('SFTP config for the id(%s) does not exist' % id) handle_exception(Exception(e_msg), request) try: mnt_prefix = ('%s%s/' % (settings.SFTP_MNT_ROOT, sftpo.share.owner)) if (is_share_mounted(sftpo.share.name, mnt_prefix)): sftp_snap_toggle(sftpo.share, mount=False) umount_root(('%s%s' % (mnt_prefix, sftpo.share.name))) import shutil shutil.rmtree(mnt_prefix) sftpo.delete() input_list = [] for so in SFTP.objects.all(): if (so.id != sftpo.id): input_list.append({'user': so.share.owner, 'dir': ('%s%s' % (settings.SFTP_MNT_ROOT, so.share.name)), }) update_sftp_config(input_list) return Response() except RockStorAPIException: raise except Exception, e: handle_exception(e, request)
def post(self, request, sname): with self._handle_exception(request): share = Share.objects.get(name=sname) try: samba_o = SambaShare.objects.get(share=share) samba_serializer = SambaShareSerializer(samba_o) return Response(samba_serializer.data) except: options = { 'comment': ('samba for %s' % sname), 'browsable': 'yes', 'guest_ok': 'no', 'read_only': 'no', 'create_mask': '0755', } if ('comment' in request.DATA): options['comment'] = request.DATA['comment'] if ('browsable' in request.DATA): if (request.DATA['browsable'] != 'yes' and request.DATA['browsable'] != 'no'): e_msg = ('Invalid choice for browsable. Possible ' 'choices are yes or no.') handle_exception(Exception(e_msg), request) options['browsable'] = request.DATA['browsable'] if ('guest_ok' in request.DATA): if (request.DATA['guest_ok'] != 'yes' and request.DATA['guest_ok'] != 'no'): e_msg = ('Invalid choice for guest_ok. Possible ' 'options are yes or no.') handle_exception(Exception(e_msg), request) options['guest_ok'] = request.DATA['guest_ok'] if ('read_only' in request.DATA): if (request.DATA['read_only'] != 'yes' and request.DATA['read_only'] != 'no'): e_msg = ('Invalid choice for read_only. Possible ' 'options are yes or no.') handle_exception(Exception(e_msg), request) options['read_only'] = request.DATA['read_only'] if ('create_mask' in request.DATA): if (request.DATA['create_mask'] not in self.CREATE_MASKS): e_msg = ('Invalid choice for create_mask. Possible ' 'options are: %s' % self.CREATE_MASKS) handle_exception(Exception(e_msg), request) mnt_pt = ('%s%s' % (settings.MNT_PT, share.name)) smb_share = SambaShare(share=share, path=mnt_pt, comment=options['comment'], browsable=options['browsable'], read_only=options['read_only'], guest_ok=options['guest_ok'], create_mask=options['create_mask']) smb_share.save() if (not is_share_mounted(share.name)): pool_device = Disk.objects.filter(pool=share.pool)[0].name mount_share(share.subvol_name, pool_device, mnt_pt) refresh_smb_config(list(SambaShare.objects.all())) restart_samba() samba_serializer = SambaShareSerializer(smb_share) return Response(samba_serializer.data)
def put(self, request, smb_id): with self._handle_exception(request): try: smbo = SambaShare.objects.get(id=smb_id) except: e_msg = ('Samba export for the id(%s) does not exist' % smb_id) handle_exception(Exception(e_msg), request) options = self._validate_input(request) custom_config = options['custom_config'] del(options['custom_config']) smbo.__dict__.update(**options) admin_users = request.data.get('admin_users', None) if (admin_users is None): admin_users = [] for uo in User.objects.filter(smb_shares=smbo): if (uo.username not in admin_users): uo.smb_shares.remove(smbo) for u in admin_users: if (not User.objects.filter(username=u, smb_shares=smbo).exists()): auo = User.objects.get(username=u) auo.smb_shares.add(smbo) smbo.save() for cco in SambaCustomConfig.objects.filter(smb_share=smbo): if (cco.custom_config not in custom_config): cco.delete() else: custom_config.remove(cco.custom_config) for cc in custom_config: cco = SambaCustomConfig(smb_share=smbo, custom_config=cc) cco.save() for smb_o in SambaShare.objects.all(): if (not is_share_mounted(smb_o.share.name)): pool_device = Disk.objects.filter( pool=smb_o.share.pool)[0].name mnt_pt = ('%s%s' % (settings.MNT_PT, smb_o.share.name)) try: mount_share(smb_o.share, pool_device, mnt_pt) except Exception, e: logger.exception(e) if (smb_o.id == smbo.id): e_msg = ('Failed to mount share(%s) due to a low ' 'level error.' % smb_o.share.name) handle_exception(Exception(e_msg), request) refresh_smb_config(list(SambaShare.objects.all())) self._restart_samba() return Response(SambaShareSerializer(smbo).data)
def put(self, request, smb_id): with self._handle_exception(request): try: smbo = SambaShare.objects.get(id=smb_id) except: e_msg = ('Samba export for the id(%s) does not exist' % smb_id) handle_exception(Exception(e_msg), request) options = self._validate_input(request, smbo=smbo) custom_config = options['custom_config'] del (options['custom_config']) smbo.__dict__.update(**options) admin_users = request.data.get('admin_users', None) if (admin_users is None): admin_users = [] for uo in User.objects.filter(smb_shares=smbo): if (uo.username not in admin_users): uo.smb_shares.remove(smbo) for u in admin_users: if (not User.objects.filter(username=u, smb_shares=smbo).exists()): auo = User.objects.get(username=u) auo.smb_shares.add(smbo) smbo.save() for cco in SambaCustomConfig.objects.filter(smb_share=smbo): if (cco.custom_config not in custom_config): cco.delete() else: custom_config.remove(cco.custom_config) for cc in custom_config: cco = SambaCustomConfig(smb_share=smbo, custom_config=cc) cco.save() for smb_o in SambaShare.objects.all(): if (not is_share_mounted(smb_o.share.name)): pool_device = Disk.objects.filter( pool=smb_o.share.pool)[0].name mnt_pt = ('%s%s' % (settings.MNT_PT, smb_o.share.name)) try: mount_share(smb_o.share, pool_device, mnt_pt) except Exception, e: logger.exception(e) if (smb_o.id == smbo.id): e_msg = ('Failed to mount share(%s) due to a low ' 'level error.' % smb_o.share.name) handle_exception(Exception(e_msg), request) refresh_smb_config(list(SambaShare.objects.all())) self._restart_samba() return Response(SambaShareSerializer(smbo).data)
def put(self, request, export_id): if ('shares' not in request.DATA): e_msg = ('Cannot export without specifying shares') handle_exception(Exception(e_msg), request) shares = [validate_share(s, request) for s in request.DATA['shares']] try: eg = validate_export_group(export_id, request) options = parse_options(request) for s in shares: dup_export_check(s, options['host_str'], request, export_id=int(export_id)) NFSExportGroup.objects.filter(id=export_id).update(**options) NFSExportGroup.objects.filter(id=export_id)[0].save() cur_exports = list(NFSExport.objects.all()) for e in NFSExport.objects.filter(export_group=eg): if (e.share not in shares): cur_exports.remove(e) e.delete() else: shares.remove(e.share) for s in shares: mnt_pt = ('%s%s' % (settings.MNT_PT, s.name)) export_pt = ('%s%s' % (settings.NFS_EXPORT_ROOT, s.name)) if (not is_share_mounted(s.name)): pool_device = Disk.objects.filter(pool=s.pool)[0].name mount_share(s.subvol_name, pool_device, mnt_pt) export = NFSExport(export_group=eg, share=s, mount=export_pt) export.full_clean() export.save() cur_exports.append(export) exports = create_nfs_export_input(cur_exports) adv_entries = [ e.export_str for e in AdvancedNFSExport.objects.all() ] exports_d = create_adv_nfs_export_input(adv_entries, request) exports.update(exports_d) refresh_wrapper(exports, request, logger) nfs_serializer = NFSExportGroupSerializer(eg) return Response(nfs_serializer.data) except RockStorAPIException: raise except Exception, e: handle_exception(e, request)
def post(self, request, sname): try: share = Share.objects.get(name=sname) options = { 'owner': 'root', 'group': 'root', 'perms': '755', 'orecursive': False, 'precursive': False, } if ('owner' in request.DATA): options['owner'] = request.DATA['owner'] if ('group' in request.DATA): options['group'] = request.DATA['group'] else: options['group'] = options['owner'] if ('orecursive' in request.DATA): options['orecursive'] = True if ('perms' in request.DATA): options['perms'] = request.DATA['perms'] if ('precursive' in request.DATA): options['precursive'] = True share.owner = options['owner'] share.group = options['group'] share.perms = options['perms'] share.save() mnt_pt = ('%s%s' % (settings.MNT_PT, share.name)) force_mount = False if (not is_share_mounted(share.name)): pool_device = Disk.objects.filter(pool=share.pool)[0].name mount_share(share.subvol_name, pool_device, mnt_pt) force_mount = True chown(mnt_pt, options['owner'], options['group'], options['orecursive']) chmod(mnt_pt, options['perms'], options['precursive']) if (force_mount is True): umount_root(mnt_pt) return Response(ShareSerializer(share).data) except RockStorAPIException: raise except Exception, e: handle_exception(e, request)
def delete(self, request, sname): try: share = Share.objects.get(name=sname) if (not SambaShare.objects.filter(share=share).exists()): e_msg = ('Share is not exported via Samba. Nothing to delete') handle_exception(Exception(e_msg), request) samba_share = SambaShare.objects.get(share=share) if (not NFSExport.objects.filter(share=share).exists() and is_share_mounted(share.name)): umount_root(samba_share.path) samba_share.delete() refresh_smb_config(list(SambaShare.objects.all()), settings.SMB_CONF) restart_samba() return Response() except RockStorAPIException: raise except Exception, e: handle_exception(e, request)
def put(self, request, export_id): if ('shares' not in request.DATA): e_msg = ('Cannot export without specifying shares') handle_exception(Exception(e_msg), request) shares = [validate_share(s, request) for s in request.DATA['shares']] try: eg = validate_export_group(export_id, request) options = parse_options(request) for s in shares: dup_export_check(s, options['host_str'], request, export_id=int(export_id)) NFSExportGroup.objects.filter(id=export_id).update(**options) NFSExportGroup.objects.filter(id=export_id)[0].save() cur_exports = list(NFSExport.objects.all()) for e in NFSExport.objects.filter(export_group=eg): if (e.share not in shares): cur_exports.remove(e) e.delete() else: shares.remove(e.share) for s in shares: mnt_pt = ('%s%s' % (settings.MNT_PT, s.name)) export_pt = ('%s%s' % (settings.NFS_EXPORT_ROOT, s.name)) if (not is_share_mounted(s.name)): pool_device = Disk.objects.filter(pool=s.pool)[0].name mount_share(s.subvol_name, pool_device, mnt_pt) export = NFSExport(export_group=eg, share=s, mount=export_pt) export.full_clean() export.save() cur_exports.append(export) exports = create_nfs_export_input(cur_exports) adv_entries = [e.export_str for e in AdvancedNFSExport.objects.all()] exports_d = create_adv_nfs_export_input(adv_entries, request) exports.update(exports_d) refresh_wrapper(exports, request, logger) nfs_serializer = NFSExportGroupSerializer(eg) return Response(nfs_serializer.data) except RockStorAPIException: raise except Exception, 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 delete(self, request, sname, export_id): try: share = Share.objects.get(name=sname) if (not NFSExport.objects.filter(id=export_id).exists()): e_msg = ('NFS export with id: %d does not exist' % export_id) handle_exception(Exception(e_msg), request) export = NFSExport.objects.get(id=export_id) if (is_share_mounted(share.name) and not SambaShare.objects.filter(share=share).exists() and not len(NFSExport.objects.filter(share=share)) > 1): umount_root(export.mount) export.enabled = False exports = self._create_nfs_export_input(export) export.delete() refresh_nfs_exports(exports) return Response() except RockStorAPIException: raise except Exception, e: handle_exception(e, request)
def post(self, request, sname): with self._handle_exception(request): share = validate_share(sname, request) options = parse_options(request) dup_export_check(share, options["host_str"], request) cur_exports = list(NFSExport.objects.all()) eg = NFSExportGroup(**options) eg.save() mnt_pt = "%s%s" % (settings.MNT_PT, share.name) export_pt = "%s%s" % (settings.NFS_EXPORT_ROOT, share.name) if not is_share_mounted(share.name): mount_share(share, mnt_pt) export = NFSExport(export_group=eg, share=share, mount=export_pt) export.full_clean() export.save() cur_exports.append(export) exports = create_nfs_export_input(cur_exports) refresh_wrapper(exports, request, logger) nfs_serializer = NFSExportGroupSerializer(eg) return Response(nfs_serializer.data)
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 delete(self, request, sname): """ For now, we delete all snapshots, if any of the share and delete the share itself. """ try: try: share = Share.objects.get(name=sname) except: e_msg = ('Share: %s does not exist' % sname) handle_exception(Exception(e_msg), request) if (NFSExport.objects.filter(share=share).exists()): e_msg = ('Share: %s cannot be deleted as it is exported via ' 'nfs. Delete nfs exports and try again' % sname) handle_exception(Exception(e_msg), request) if (SambaShare.objects.filter(share=share).exists()): e_msg = ('Share: %s cannot be deleted as it is shared via ' 'Samba. Unshare and try again' % sname) handle_exception(Exception(e_msg), request) if (Snapshot.objects.filter(share=share).exists()): e_msg = ('Share: %s cannot be deleted as it has ' 'snapshots. Delete snapshots and try again' % sname) handle_exception(Exception(e_msg), request) pool_device = Disk.objects.filter(pool=share.pool)[0].name e_msg = ('Share: %s is still mounted and cannot be deleted.' ' Try again later' % sname) try: remove_share(share.pool.name, pool_device, share.subvol_name) except Exception, e: logger.exception(e) handle_exception(Exception(e_msg), request) if (is_share_mounted(sname)): handle_exception(Exception(e_msg), request) share.delete() return Response()
def post(self, request, sname): try: share = Share.objects.get(name=sname) options = { 'host_str': '*', 'mod_choice': 'ro', 'sync_choice': 'async', 'security': 'insecure', 'id': -1, } if ('host_str' in request.DATA): options['host_str'] = request.DATA['host_str'] if ('mod_choice' in request.DATA): options['mod_choice'] = request.DATA['mod_choice'] if ('sync_choice' in request.DATA): options['sync_choice'] = request.DATA['sync_choice'] 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.subvol_name, pool_device, mnt_pt) export = NFSExport(share=share, mount=mnt_pt, host_str=options['host_str'], editable=options['mod_choice'], syncable=options['sync_choice'], mount_security=options['security']) export.full_clean() export.save() exports = self._create_nfs_export_input(export) refresh_nfs_exports(exports) nfs_serializer = NFSExportSerializer(export) return Response(nfs_serializer.data) except RockStorAPIException: raise except Exception, e: handle_exception(e, request)
def create_adv_nfs_export_input(exports, request): exports_d = {} for e in exports: fields = e.split() if len(fields) < 2: e_msg = "Invalid exports input -- %s" % e handle_exception(Exception(e_msg), request) share = fields[0].split("/")[-1] s = validate_share(share, request) mnt_pt = "%s%s" % (settings.MNT_PT, s.name) if not is_share_mounted(s.name): pool_device = Disk.objects.filter(pool=s.pool)[0].name mount_share(s, pool_device, mnt_pt) exports_d[fields[0]] = [] for f in fields[1:]: cf = f.split("(") if len(cf) != 2 or cf[1][-1] != ")": e_msg = "Invalid exports input -- %s. offending " "section: %s" % (e, f) handle_exception(Exception(e_msg), request) exports_d[fields[0]].append( {"client_str": cf[0], "option_list": cf[1][:-1], "mnt_pt": ("%s%s" % (settings.MNT_PT, share))} ) return exports_d
def create_adv_nfs_export_input(exports, request): exports_d = {} for e in exports: fields = e.split() if (len(fields) < 2): e_msg = ('Invalid exports input -- %s' % e) handle_exception(Exception(e_msg), request) share = fields[0].split('/')[-1] s = validate_share(share, request) mnt_pt = ('%s%s' % (settings.MNT_PT, s.name)) if (not is_share_mounted(s.name)): mount_share(s, mnt_pt) exports_d[fields[0]] = [] for f in fields[1:]: cf = f.split('(') if (len(cf) != 2 or cf[1][-1] != ')'): e_msg = ('Invalid exports input -- %s. offending ' 'section: %s' % (e, f)) handle_exception(Exception(e_msg), request) exports_d[fields[0]].append( {'client_str': cf[0], 'option_list': cf[1][:-1], 'mnt_pt': ('%s%s' % (settings.MNT_PT, share))}) return exports_d
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()
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']] options = self._validate_input(request) custom_config = options['custom_config'] del(options['custom_config']) for share in shares: if (SambaShare.objects.filter(share=share).exists()): e_msg = ('Share(%s) is already exported via Samba' % share.name) handle_exception(Exception(e_msg), request) with self._handle_exception(request): for share in shares: mnt_pt = ('%s%s' % (settings.MNT_PT, share.name)) options['share'] = share options['path'] = mnt_pt smb_share = SambaShare(**options) smb_share.save() for cc in custom_config: cco = SambaCustomConfig(smb_share=smb_share, custom_config=cc) cco.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) admin_users = request.DATA.get('admin_users', None) if (admin_users is None): admin_users = [] for au in admin_users: auo = User.objects.get(username=au) auo.smb_shares.add(smb_share) refresh_smb_config(list(SambaShare.objects.all())) self._restart_samba() return Response(SambaShareSerializer(smb_share).data)
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']] options = { 'comment': 'samba export', 'browsable': 'yes', 'guest_ok': 'no', 'read_only': 'no', 'create_mask': '0755', } if ('comment' in request.DATA): options['comment'] = request.DATA['comment'] if ('browsable' in request.DATA): if (request.DATA['browsable'] != 'yes' and request.DATA['browsable'] != 'no'): e_msg = ('Invalid choice for browsable. Possible ' 'choices are yes or no.') handle_exception(Exception(e_msg), request) options['browsable'] = request.DATA['browsable'] if ('guest_ok' in request.DATA): if (request.DATA['guest_ok'] != 'yes' and request.DATA['guest_ok'] != 'no'): e_msg = ('Invalid choice for guest_ok. Possible ' 'options are yes or no.') handle_exception(Exception(e_msg), request) options['guest_ok'] = request.DATA['guest_ok'] if ('read_only' in request.DATA): if (request.DATA['read_only'] != 'yes' and request.DATA['read_only'] != 'no'): e_msg = ('Invalid choice for read_only. Possible ' 'options are yes or no.') handle_exception(Exception(e_msg), request) options['read_only'] = request.DATA['read_only'] if ('create_mask' in request.DATA): if (request.DATA['create_mask'] not in self.CREATE_MASKS): e_msg = ('Invalid choice for create_mask. Possible ' 'options are: %s' % self.CREATE_MASKS) handle_exception(Exception(e_msg), request) for share in shares: if (SambaShare.objects.filter(share=share).exists()): e_msg = ('Share(%s) is already exported via Samba' % share.name) handle_exception(Exception(e_msg), request) try: for share in shares: mnt_pt = ('%s%s' % (settings.MNT_PT, share.name)) smb_share = SambaShare(share=share, path=mnt_pt, comment=options['comment'], browsable=options['browsable'], read_only=options['read_only'], guest_ok=options['guest_ok'], create_mask=options['create_mask']) smb_share.save() if (not is_share_mounted(share.name)): pool_device = Disk.objects.filter(pool=share.pool)[0].name mount_share(share.subvol_name, pool_device, mnt_pt) refresh_smb_config(list(SambaShare.objects.all()), settings.SMB_CONF) restart_samba() return Response() except RockStorAPIException: raise except Exception, 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']] options = { 'comment': 'samba export', 'browsable': 'yes', 'guest_ok': 'no', 'read_only': 'no', 'create_mask': '0755', 'admin_users': 'Administrator', } if ('comment' in request.DATA): options['comment'] = request.DATA['comment'] if ('browsable' in request.DATA): if (request.DATA['browsable'] != 'yes' and request.DATA['browsable'] != 'no'): e_msg = ('Invalid choice for browsable. Possible ' 'choices are yes or no.') handle_exception(Exception(e_msg), request) options['browsable'] = request.DATA['browsable'] if ('guest_ok' in request.DATA): if (request.DATA['guest_ok'] != 'yes' and request.DATA['guest_ok'] != 'no'): e_msg = ('Invalid choice for guest_ok. Possible ' 'options are yes or no.') handle_exception(Exception(e_msg), request) options['guest_ok'] = request.DATA['guest_ok'] if ('read_only' in request.DATA): if (request.DATA['read_only'] != 'yes' and request.DATA['read_only'] != 'no'): e_msg = ('Invalid choice for read_only. Possible ' 'options are yes or no.') handle_exception(Exception(e_msg), request) options['read_only'] = request.DATA['read_only'] if ('create_mask' in request.DATA): if (request.DATA['create_mask'] not in self.CREATE_MASKS): e_msg = ('Invalid choice for create_mask. Possible ' 'options are: %s' % self.CREATE_MASKS) handle_exception(Exception(e_msg), request) if ('admin_users' in request.DATA): options['admin_users'] = request.DATA['admin_users'] for share in shares: if (SambaShare.objects.filter(share=share).exists()): e_msg = ('Share(%s) is already exported via Samba' % share.name) handle_exception(Exception(e_msg), request) try: for share in shares: mnt_pt = ('%s%s' % (settings.MNT_PT, share.name)) smb_share = SambaShare(share=share, path=mnt_pt, comment=options['comment'], browsable=options['browsable'], read_only=options['read_only'], guest_ok=options['guest_ok'], create_mask=options['create_mask'], admin_users=options['admin_users']) smb_share.save() if (not is_share_mounted(share.name)): pool_device = Disk.objects.filter(pool=share.pool)[0].name mount_share(share.subvol_name, pool_device, mnt_pt) refresh_smb_config(list(SambaShare.objects.all())) restart_samba() return Response() except RockStorAPIException: raise except Exception, e: handle_exception(e, request)
def helper_mount_share(share, mnt_pt=None): if (not is_share_mounted(share.name)): if (mnt_pt is None): mnt_pt = ('%s%s' % (settings.MNT_PT, share.name)) mount_share(share, mnt_pt)
def helper_mount_share(share, mnt_pt=None): if (not is_share_mounted(share.name)): pool_device = Disk.objects.filter(pool=share.pool)[0].name if(mnt_pt is None): mnt_pt = ('%s%s' % (settings.MNT_PT, share.name)) mount_share(share.subvol_name, pool_device, mnt_pt)
def helper_mount_share(share, mnt_pt=None): if (not is_share_mounted(share.name)): if(mnt_pt is None): mnt_pt = ('%s%s' % (settings.MNT_PT, share.name)) mount_share(share, mnt_pt)
def post(self, request, sname): try: share = Share.objects.get(name=sname) try: samba_o = SambaShare.objects.get(share=share) samba_serializer = SambaShareSerializer(samba_o) return Response(samba_serializer.data) except: options = { 'comment': ('samba for %s' % sname), 'browsable': 'yes', 'guest_ok': 'no', 'read_only': 'no', 'create_mask': '0755', } if ('comment' in request.DATA): options['comment'] = request.DATA['comment'] if ('browsable' in request.DATA): if (request.DATA['browsable'] != 'yes' and request.DATA['browsable'] != 'no'): e_msg = ('Invalid choice for browsable. Possible ' 'choices are yes or no.') handle_exception(Exception(e_msg), request) options['browsable'] = request.DATA['browsable'] if ('guest_ok' in request.DATA): if (request.DATA['guest_ok'] != 'yes' and request.DATA['guest_ok'] != 'no'): e_msg = ('Invalid choice for guest_ok. Possible ' 'options are yes or no.') handle_exception(Exception(e_msg), request) options['guest_ok'] = request.DATA['guest_ok'] if ('read_only' in request.DATA): if (request.DATA['read_only'] != 'yes' and request.DATA['read_only'] != 'no'): e_msg = ('Invalid choice for read_only. Possible ' 'options are yes or no.') handle_exception(Exception(e_msg), request) options['read_only'] = request.DATA['read_only'] if ('create_mask' in request.DATA): if (request.DATA['create_mask'] not in self.CREATE_MASKS): e_msg = ('Invalid choice for create_mask. Possible ' 'options are: %s' % self.CREATE_MASKS) handle_exception(Exception(e_msg), request) mnt_pt = ('%s%s' % (settings.MNT_PT, share.name)) smb_share = SambaShare(share=share, path=mnt_pt, comment=options['comment'], browsable=options['browsable'], read_only=options['read_only'], guest_ok=options['guest_ok'], create_mask=options['create_mask']) smb_share.save() if (not is_share_mounted(share.name)): pool_device = Disk.objects.filter(pool=share.pool)[0].name mount_share(share.subvol_name, pool_device, mnt_pt) refresh_smb_config(list(SambaShare.objects.all())) restart_samba() samba_serializer = SambaShareSerializer(smb_share) return Response(samba_serializer.data) except RockStorAPIException: raise except Exception, e: handle_exception(e, request)