diff options
author | Rob Crittenden <rcritten@redhat.com> | 2012-01-19 16:15:50 -0500 |
---|---|---|
committer | Martin Kosek <mkosek@redhat.com> | 2012-02-06 10:51:29 +0100 |
commit | b458c963a6750dbe4d2ed7b8d604d9e4f5d9cc71 (patch) | |
tree | 3497694ca8ffdf39c645a913117456abe8727eb2 | |
parent | c080c65636ec0e01ffec460c79d0d0d4a7f9da4b (diff) | |
download | freeipa.git-b458c963a6750dbe4d2ed7b8d604d9e4f5d9cc71.tar.gz freeipa.git-b458c963a6750dbe4d2ed7b8d604d9e4f5d9cc71.tar.xz freeipa.git-b458c963a6750dbe4d2ed7b8d604d9e4f5d9cc71.zip |
Make submount automount maps work.
Indirect automount nesting is achieved by adding a key that references
another map. This isn't heirarchical, in fact, you can have multiple
duplicate keys all pointing at the same map, which itself is mounted
in other places. It can be a real mess if you want.
In any case, a submount map has its information set to
"-fstype=autofs <type>:<map>"
The type can be any valid automount type: file, nis, yp, ldap, etc. We
are going to hardcode ldap in when we create these using
automountmap-add-indirect. If a user wants a different type they can
create the key themselves (or edit it later).
Here is an example of creating a submount:
$ ipa automountlocation-add baltimore
$ ipa automountmap-add-indirect baltimore auto.share --mount=/share
$ ipa automountmap-add-indirect baltimore --parentmap=auto.share --mount=sub auto.sub
$ ipa automountkey-add baltimore auto.sub --key=share --info=attic:/share
$ ls /share/sub/share
builds lost+found
This looks like:
etc/auto.master:
/- /etc/auto.direct
/share /etc/auto.share
---------------------------
/etc/auto.direct:
---------------------------
/etc/auto.share:
sub -fstype=autofs ldap:auto.sub
maps not connected to /etc/auto.master:
---------------------------
/etc/auto.sub:
share attic:/share
I've also added a catch-all when using the tofiles function. We were
missing any maps that weren't attached to auto.master. They will now
be shown along with whatever keys they have.
https://fedorahosted.org/freeipa/ticket/1268
-rw-r--r-- | ipalib/plugins/automount.py | 78 |
1 files changed, 72 insertions, 6 deletions
diff --git a/ipalib/plugins/automount.py b/ipalib/plugins/automount.py index 1b2214d1..8d743d75 100644 --- a/ipalib/plugins/automount.py +++ b/ipalib/plugins/automount.py @@ -53,6 +53,11 @@ it: auto.master and auto.direct. auto.master is the root map for all automount maps for the location. auto.direct is the default map for direct mounts and is mounted on /-. +An automount map may contain a submount key. This key defines a mount +location within the map that references another map. This can be done +either using automountmap-add-indirect --parentmap or manually +with automountkey-add and setting info to "-type=autofs :<mapname>". + EXAMPLES: Locations: @@ -90,6 +95,14 @@ Maps: Find maps in the location baltimore: ipa automountmap-find baltimore + Create an indirect map with auto.share as a submount: + ipa automountmap-add-indirect baltimore --parentmap=auto.share --mount=sub auto.man + + This is equivalent to: + + ipa automountmap-add-indirect baltimore --mount=/man auto.man + ipa automountkey-add baltimore auto.man --key=sub --info="-fstype=autofs ldap:auto.share" + Remove the auto.share map: ipa automountmap-del baltimore auto.share @@ -123,6 +136,7 @@ A few notes on automount: URL format. Support for ldap as a map source in nsswitch.conf was added in autofs version 4.1.3-197. Any version prior to that is not expected to work. +- An indirect key should not begin with / As an example, the following automount files: @@ -271,19 +285,38 @@ class automountlocation_tofiles(LDAPQuery): # ?use ldap.find_entries instead of automountkey_find? keys = {} + mapnames = [u'auto.master'] for m in maps: info = m['automountinformation'][0] + mapnames.append(info) key = info.split(None) result = self.api.Command['automountkey_find'](args[0], key[0]) truncated = result['truncated'] keys[info] = result['result'] # TODO: handle truncated results, same as above - return dict(result=dict(maps=maps, keys=keys)) + allmaps = self.api.Command['automountmap_find'](args[0])['result'] + orphanmaps = [] + for m in allmaps: + if m['automountmapname'][0] not in mapnames: + orphanmaps.append(m) + + orphankeys = [] + # Collect all the keys for the orphaned maps + for m in orphanmaps: + key = m['automountmapname'] + result = self.api.Command['automountkey_find'](args[0], key[0]) + truncated = result['truncated'] + orphankeys.append(result['result']) + + return dict(result=dict(maps=maps, keys=keys, + orphanmaps=orphanmaps, orphankeys=orphankeys)) def output_for_cli(self, textui, result, *keys, **options): maps = result['result']['maps'] keys = result['result']['keys'] + orphanmaps = result['result']['orphanmaps'] + orphankeys = result['result']['orphankeys'] textui.print_plain('/etc/auto.master:') for m in maps: @@ -312,6 +345,21 @@ class automountlocation_tofiles(LDAPQuery): ) ) + textui.print_plain('') + textui.print_plain(_('maps not connected to /etc/auto.master:')) + for m in orphanmaps: + textui.print_plain('---------------------------') + textui.print_plain('/etc/%s: ' % m['automountmapname']) + for k in orphankeys: + if len(k) == 0: continue + dn = DN(k[0]['dn']) + if dn['automountmapname'] == m['automountmapname'][0]: + textui.print_plain( + '%s\t%s' % ( + k[0]['automountkey'][0], k[0]['automountinformation'][0] + ) + ) + api.register(automountlocation_tofiles) @@ -779,11 +827,29 @@ class automountmap_add_indirect(LDAPCreate): def execute(self, *keys, **options): result = self.api.Command['automountmap_add'](*keys, **options) try: - options['automountinformation'] = keys[1] - self.api.Command['automountkey_add']( - keys[0], options['parentmap'], - automountkey=options['key'], **options - ) + if options['parentmap'] != u'auto.master': + if options['key'].startswith('/'): + raise errors.ValidationError(name='mount', error=_('mount point is relative to parent map, cannot begin with /')) + location = keys[0] + map = keys[1] + options['automountinformation'] = map + + # Ensure the referenced map exists + self.api.Command['automountmap_show']( + location, options['parentmap'] + ) + # Add a submount key + kw = dict(key=options['key'], automountinformation='-fstype=autofs ldap:%s' % map) + self.api.Command['automountkey_add']( + location, options['parentmap'], + automountkey=options['key'], **kw + ) + else: # adding to auto.master + options['automountinformation'] = keys[1] + self.api.Command['automountkey_add']( + keys[0], u'auto.master', + automountkey=options['key'], **options + ) except Exception, e: # The key exists, drop the map self.api.Command['automountmap_del'](*keys, **options) |