In branch 'platform' of
you can find four commits which represent working code to address

What is done:
1. ipapython.services module represents system-agnostic way to
communicate with platform-specific services management and other
platform-specific functions.

2. ipapython.platform.* implements platform-specific functionality. The
code is pulled in by ipapython.services module and should not be
adressed directly.

3. ipapython.platform.redhat module (not to be called directly!) is what
FreeIPA 2.1 has had previously -- current RHEL6 and Fedora14/15

4. Install tools, IPA client, and IPA server install code is converted
to use ipapython.services.

To facilitate more expressive way of working with often used services,
ipapython.services module provides a shortcut to access them by name via
ipapython.services.knownservices.<service>. A typical code change looks
like this:
(from ipapython import services as ipaservices)
-    service.restart("dirsrv")
-    service.restart("krb5kdc")
-    service.restart("httpd")
+    ipaservices.knownservices.dirsrv.restart()
+    ipaservices.knownservices.krb5kdc.restart()
+    ipaservices.knownservices.httpd.restart()

Besides expression change this also makes more explicit to platform
providers access to what services they have to implement. Service names
are defined in ipapython.platform.base.wellknownservices and represent
definitive names to access these services from FreeIPA code. Of course,
platform provider should remap those names to platform-specific ones --
for ipapython.platform.redhat provider mapping is identity.

If code needs direct access to some unnamed service, one could use
ipapython.services.service class:
     for (order, svc) in sorted(svc_list):
         svc_name = service.SERVICE_LIST[svc][0]
+       svchandle = ipaservices.service(svc_name)
             print "Starting %s Service" % svc
-            service.start(svc_name,
capture_output=get_capture_output(svc_name, options.debug))
+            svchandle.start(capture_output=get_capture_output(svc_name,
             emit_err("Failed to start %s Service" % svc)

Server-side installation code depends on quite a delicate arrangement of
Certificate Server, Directory Server, and is not really portable to
other environments unless you do provide same packages as Fedora or RHEL
have. However, I tried to abstract service-specific calls in such way
that they all go through ipapython.platform.* so even here remapping of
names is possible. Unfortunately, not for file paths yet.

Client side is more ready for porting except authconfig(8) use.
One of substantial issues for porting FreeIPA client code to platforms
other than Red Hat's is use of authconfig(8) utility to configure
authentication services. What I ended up is a flexible interface
(ipapython.platform.base.AuthConfig) to specify options and execute
external apps. As with knownservices, one step more is to make those
options accessible as member attributes instead of strings but even with
current approach this gives full isolation of implementation of
authconfig replacement from FreeIPA code.

Typical use for AuthConfig is via ipapython.services.authconfig class:
-        run(["/usr/sbin/authconfig", "--disableldap", "--disablekrb5",
"--disablesssd", "--disablesssdauth", "--disablemkhomedir", "--update"])
+        auth_config = ipaservices.authconfig()
+        auth_config.disable("ldap").\
+                    disable("krb5").\
+                    disable("sssd").\
+                    disable("sssdauth").\
+                    disable("mkhomedir").\
+                    add_option("update")
+        auth_config.execute()
This should make porting much simpler -- less code to touch in core FreeIPA.

Now good things: this all works! :)

I tried on F15, doing ipa-server-install with different options and
uninstalling as well, joining another client and removing it later. Of
course, more testing is needed too.

/ Alexander Bokovoy

Freeipa-devel mailing list

Reply via email to