From aa2062ba36d87b174fcea2a5daf6b987cdc9b61b Mon Sep 17 00:00:00 2001
From: Nikos Skalkotos <skalkoto@grnet.gr>
Date: Mon, 20 Feb 2012 19:59:43 +0200
Subject: [PATCH] Add OS specific classes

---
 image_creator/__init__.py         | 19 ++++++++++++++++
 image_creator/disk.py             | 10 +++------
 image_creator/main.py             |  6 ++++-
 image_creator/os_type/__init__.py | 34 ++++++++++++++++++++++++++++
 image_creator/os_type/freebsd.py  |  6 +++++
 image_creator/os_type/hurd.py     |  6 +++++
 image_creator/os_type/linux.py    |  6 +++++
 image_creator/os_type/netbsd.py   |  6 +++++
 image_creator/os_type/unix.py     | 37 +++++++++++++++++++++++++++++++
 image_creator/os_type/windows.py  |  6 +++++
 10 files changed, 128 insertions(+), 8 deletions(-)
 create mode 100644 image_creator/os_type/__init__.py
 create mode 100644 image_creator/os_type/freebsd.py
 create mode 100644 image_creator/os_type/hurd.py
 create mode 100644 image_creator/os_type/linux.py
 create mode 100644 image_creator/os_type/netbsd.py
 create mode 100644 image_creator/os_type/unix.py
 create mode 100644 image_creator/os_type/windows.py

diff --git a/image_creator/__init__.py b/image_creator/__init__.py
index 817a9c6..aec50d6 100644
--- a/image_creator/__init__.py
+++ b/image_creator/__init__.py
@@ -32,3 +32,22 @@
 # or implied, of GRNET S.A.
 
 __version__ = '0.1'
+
+import image_creator.os_type
+
+def get_os_class(distro, osfamily):
+    module = None
+    classname = None
+    try:
+        module = __import__("image_creator.os_type.%s"
+            % distro, fromlist=['image_creator.os_type'])
+        classname = distro.capitalize()
+    except ImportError:
+        module = __import__("image_creator.os_type.%s"
+            % osfamily, fromlist=['image_creator.os_type'])
+        classname = osfamily.capitalize()
+
+    return getattr(module, classname)
+
+
+# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
diff --git a/image_creator/disk.py b/image_creator/disk.py
index 4a6b78f..170d0fb 100644
--- a/image_creator/disk.py
+++ b/image_creator/disk.py
@@ -95,20 +95,16 @@ class DiskDevice(object):
             raise DiskError("Multiple operating systems found")
 
         self.root = roots[0]
+        self.ostype = self.g.inspect_get_type(self.root)
+        self.distro = self.g.inspect_get_distro(self.root)
     
     def destroy(self):
         self.g.umount_all()
         self.g.sync()
         # Close the guestfs handler
+        self.g.close()
         del self.g
     
-    def get_image_metadata(self):
-        meta = {}
-        meta["OSFAMILY"] = self.g.inspect_get_type(self.root)
-        meta["OS"] = self.g.inspect_get_distro(self.root)
-        meta["description"] = self.g.inspect_get_product_name(self.root)
-        return meta
-
     def mount(self):
         mps = g.inspect_get_mountpoints(self.root)
         # Sort the keys to mount the fs in a correct order.
diff --git a/image_creator/main.py b/image_creator/main.py
index 7040931..574d1a2 100644
--- a/image_creator/main.py
+++ b/image_creator/main.py
@@ -31,6 +31,7 @@
 # interpreted as representing official policies, either expressed
 # or implied, of GRNET S.A.
 
+from image_creator import get_os_class
 from image_creator.disk import Disk
 import sys
 import os
@@ -45,9 +46,12 @@ def main():
     disk = Disk(source)
     try:
         dev = disk.get_device()
-        metadata = dev.get_image_metadata()
+        osclass = get_os_class(dev.distro, dev.ostype)
+        image_os = osclass(dev.root, dev.g)
+        metadata = image_os.get_metadata()
         for key, val in metadata.iteritems():
             print "%s=%s" % (key,val)
+
     finally:
         disk.cleanup()
 
diff --git a/image_creator/os_type/__init__.py b/image_creator/os_type/__init__.py
new file mode 100644
index 0000000..59da31a
--- /dev/null
+++ b/image_creator/os_type/__init__.py
@@ -0,0 +1,34 @@
+#!/usr/bin/env python
+
+class OSBase(object):
+    def __init__(self, rootdev, ghandler):
+        self.root = rootdev
+        self.g = ghandler
+
+    def get_metadata(self):
+        meta = {}
+        meta["OSFAMILY"] = self.g.inspect_get_type(self.root)
+        meta["OS"] = self.g.inspect_get_distro(self.root)
+        meta["description"] = self.g.inspect_get_product_name(self.root)
+
+        return meta
+
+    def mount_all(self):
+        mps = g.inspect_get_mountpoints(self.root)
+        # Sort the keys to mount the fs in a correct order.
+        # / should be mounted befor /boot, etc
+        def compare (a, b):
+            if len(a[0]) > len(b[0]): return 1
+            elif len(a[0]) == len(b[0]): return 0
+            else: return -1
+        mps.sort(compare)
+        for mp, dev in mps:
+            try:
+                self.g.mount(dev, mp)
+            except RuntimeError as msg:
+                print "%s (ignored)" % msg
+
+    def cleanup_sensitive_data(self):
+        raise NotImplementedError
+
+# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
diff --git a/image_creator/os_type/freebsd.py b/image_creator/os_type/freebsd.py
new file mode 100644
index 0000000..9a09f28
--- /dev/null
+++ b/image_creator/os_type/freebsd.py
@@ -0,0 +1,6 @@
+from image_creator.os_type.unix import Unix
+
+class Freebsd(Unix):
+	pass
+
+# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
diff --git a/image_creator/os_type/hurd.py b/image_creator/os_type/hurd.py
new file mode 100644
index 0000000..f385b10
--- /dev/null
+++ b/image_creator/os_type/hurd.py
@@ -0,0 +1,6 @@
+from image_creator.os_type.unix import Unix
+
+class Hard(Unix):
+	pass
+
+# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
diff --git a/image_creator/os_type/linux.py b/image_creator/os_type/linux.py
new file mode 100644
index 0000000..a82d52c
--- /dev/null
+++ b/image_creator/os_type/linux.py
@@ -0,0 +1,6 @@
+from image_creator.os_type.unix import Unix
+
+class Linux(Unix):
+	pass
+
+# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
diff --git a/image_creator/os_type/netbsd.py b/image_creator/os_type/netbsd.py
new file mode 100644
index 0000000..bc81c17
--- /dev/null
+++ b/image_creator/os_type/netbsd.py
@@ -0,0 +1,6 @@
+from image_creator.os_type.unix import Unix
+
+class Netbsd(Unix):
+	pass
+
+# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
diff --git a/image_creator/os_type/unix.py b/image_creator/os_type/unix.py
new file mode 100644
index 0000000..ad65c15
--- /dev/null
+++ b/image_creator/os_type/unix.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+
+import re
+
+from image_creator.os_type import OSBase
+
+class Unix(OSBase):
+    def get_metadata(self):
+        meta = super(Unix, self).get_metadata()
+        meta["USERS"] = " ".join(self.get_passworded_users())
+        return meta
+
+    def get_passworded_users(self):
+        
+        users = []
+
+        regexp = re.compile('(\S+):((?:!\S+)|(?:[^!*]\S+)|):(?:\S*:){6}')
+
+        for line in open('/etc/shadow', 'r').readlines():
+            match = regexp.match(line)
+            if not match:
+                continue
+
+            user, passwd = match.groups()
+            if len(passwd) > 0 and passwd[0] == '!':
+                print "Warning: %s is locked" % user
+            else:
+                users.append(user)
+
+        return users
+
+    def cleanup_sensitive_data(self):
+        cleanup_userdata()
+        cleanup_tmp()
+        cleanup_log()
+
+# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
diff --git a/image_creator/os_type/windows.py b/image_creator/os_type/windows.py
new file mode 100644
index 0000000..72c1031
--- /dev/null
+++ b/image_creator/os_type/windows.py
@@ -0,0 +1,6 @@
+from image_creator.os_type import OSBase
+
+class Windows(OSBase):
+	pass
+
+# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
-- 
GitLab