Fixed ws etc. and renamed _bitCount to _bc.
Signed-off-by: Tony Asleson tasleson@redhat.com --- targetd/nfs.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/targetd/nfs.py b/targetd/nfs.py index 083760e..6daf99e 100644 --- a/targetd/nfs.py +++ b/targetd/nfs.py @@ -76,7 +76,12 @@ class Export(object): export_regex = '([/a-zA-Z0-9.-_]+)[\s]+(.+)((.+))'
@staticmethod - def _bitCount(int_type): + def _bc(int_type): + """ + Bit count. + + returns the number of bits set. + """ count = 0 while int_type: int_type &= int_type - 1 @@ -86,23 +91,22 @@ class Export(object): @staticmethod def _validate_options(options):
- if Export._bitCount(((Export.RW | Export.RO) & options)) == 2: + if Export._bc(((Export.RW | Export.RO) & options)) == 2: raise ValueError("Both RO & RW set")
- if Export._bitCount(((Export.INSECURE | Export.SECURE) & options)) == 2: + if Export._bc(((Export.INSECURE | Export.SECURE) & options)) == 2: raise ValueError("Both INSECURE & SECURE set")
- if Export._bitCount(((Export.SYNC | Export.ASYNC) & options)) == 2: + if Export._bc(((Export.SYNC | Export.ASYNC) & options)) == 2: raise ValueError("Both SYNC & ASYNC set")
- if Export._bitCount(((Export.HIDE | Export.NOHIDE) & options)) == 2: + if Export._bc(((Export.HIDE | Export.NOHIDE) & options)) == 2: raise ValueError("Both HIDE & NOHIDE set")
- if Export._bitCount(((Export.WDELAY | Export.NO_WDELAY) & options)) \ - == 2: + if Export._bc(((Export.WDELAY | Export.NO_WDELAY) & options)) == 2: raise ValueError("Both WDELAY & NO_WDELAY set")
- if Export._bitCount(((Export.ROOT_SQUASH | Export.NO_ROOT_SQUASH) + if Export._bc(((Export.ROOT_SQUASH | Export.NO_ROOT_SQUASH) & options)) > 1: raise ValueError("Only one option of ROOT_SQUASH, NO_ROOT_SQUASH, " "can be specified") @@ -205,7 +209,7 @@ class Nfs(object): Return list of exports """ rc = [] - ec, out, error = invoke([Nfs.cmd, '-v']) + ec, out, error = invoke([Nfs.cmd, '-v']) rc = Export.parse(out) return rc
In a glaring oversight the changes made via targetd for nfs exports was lost on system reboot. This patch fixes that by taking every export that is listed via `exportfs -v` and writes each entry to /etc/exports.d.
At the moment for updates the code just removes every file that is has created and re-creates a new file for each entry. Not the most performant implementation, but it minimizes risk to updating an existing export and not getting the change written out correctly. In big config testing we may find that this simple approach is actually faster than opening and checking each file for correctness and then updating/deleting etc. as needed.
Signed-off-by: Tony Asleson tasleson@redhat.com --- targetd/nfs.py | 43 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-)
diff --git a/targetd/nfs.py b/targetd/nfs.py index 6daf99e..3b157db 100644 --- a/targetd/nfs.py +++ b/targetd/nfs.py @@ -13,6 +13,15 @@
from subprocess import Popen, PIPE import re +import hashlib +import os +import os.path + + +def md5(t): + h = hashlib.md5() + h.update(t) + return h.hexdigest()
def invoke(cmd, raise_exception=True): @@ -189,12 +198,21 @@ class Export(object): return "%s%s(%s)" % (self.path.ljust(50), self.host, self.options_string())
+ def to_export_file(self, file_name): + content = "%s %s(%s)\n" % (self.path, self.host, self.options_string()) + + with open(file_name, 'w') as ef: + ef.write(content) +
class Nfs(object): """ Python module for configuring NFS exports """ - cmd = 'exportfs' + CMD = 'exportfs' + FILE_PREFIX = 'targetd_' + + EXPORT_FS_CONFIG_DIR = '/etc/exports.d'
def __init__(self): pass @@ -204,12 +222,25 @@ class Nfs(object): return "sys", "krb5", "krb5i", "krb5p"
@staticmethod + def _save_exports(): + #Remove all existing exports that we created + for root, dirs, files in os.walk(Nfs.EXPORT_FS_CONFIG_DIR): + for f in files: + if f[0:len(Nfs.FILE_PREFIX)] == Nfs.FILE_PREFIX: + os.remove(os.path.join(root, f)) + + #Recreate all existing exports + for e in Nfs.exports(): + fn = "%s%s.exports" % (Nfs.FILE_PREFIX, md5(str(e))) + e.to_export_file(os.path.join(Nfs.EXPORT_FS_CONFIG_DIR, fn)) + + @staticmethod def exports(): """ Return list of exports """ rc = [] - ec, out, error = invoke([Nfs.cmd, '-v']) + ec, out, error = invoke([Nfs.CMD, '-v']) rc = Export.parse(out) return rc
@@ -221,7 +252,7 @@ class Nfs(object): export = Export(host, path, bit_wise_options, key_value_options) options = export.options_string()
- cmd = [Nfs.cmd] + cmd = [Nfs.CMD]
if len(options): cmd.extend(['-o', options]) @@ -230,6 +261,7 @@ class Nfs(object):
ec, out, err = invoke(cmd, False) if ec == 0: + Nfs._save_exports() return None elif ec == 22: raise ValueError("Invalid option: %s" % err) @@ -240,5 +272,8 @@ class Nfs(object):
@staticmethod def export_remove(export): - ec, out, err = invoke([Nfs.cmd, '-u', '%s:%s' % + ec, out, err = invoke([Nfs.CMD, '-u', '%s:%s' % (export.host, export.path)]) + + if ec == 0: + Nfs._save_exports()
On 12/09/2013 05:22 PM, Tony Asleson wrote:
In a glaring oversight the changes made via targetd for nfs exports was lost on system reboot. This patch fixes that by taking every export that is listed via `exportfs -v` and writes each entry to /etc/exports.d.
At the moment for updates the code just removes every file that is has created and re-creates a new file for each entry. Not the most performant implementation, but it minimizes risk to updating an existing export and not getting the change written out correctly. In big config testing we may find that this simple approach is actually faster than opening and checking each file for correctness and then updating/deleting etc. as needed.
Hi Tony, nice work.
I was assuming we'd just write one file to /etc/exports.d. Is this not possible, or are there advantages to splitting them out?
Thanks -- Regards -- Andy
----- Original Message -----
From: "Andy Grover" agrover@redhat.com To: targetd-devel@lists.fedorahosted.org Cc: "Tony Asleson" tasleson@redhat.com Sent: Monday, December 9, 2013 8:03:36 PM Subject: Re: [PATCH 2/2] nfs.py: Make nfs export changes persistent
On 12/09/2013 05:22 PM, Tony Asleson wrote:
In a glaring oversight the changes made via targetd for nfs exports was lost on system reboot. This patch fixes that by taking every export that is listed via `exportfs -v` and writes each entry to /etc/exports.d.
At the moment for updates the code just removes every file that is has created and re-creates a new file for each entry. Not the most performant implementation, but it minimizes risk to updating an existing export and not getting the change written out correctly. In big config testing we may find that this simple approach is actually faster than opening and checking each file for correctness and then updating/deleting etc. as needed.
Hi Tony, nice work.
I was assuming we'd just write one file to /etc/exports.d. Is this not possible, or are there advantages to splitting them out?
I originally tried to be smarter about making the settings persistent with separate files and eventually ended up with this simple approach. We can put them all in one file. I will re-submit a patch that does just that.
Regards, Tony
targetd-devel@lists.fedorahosted.org