Here is a patch to add serializer support for MySQL against the devel
branch. It is not well tested and, for the moment, I am not running
this patch on my cobbler server. However, it seems to work in my
limited testing. You should consider this experimental until proven
otherwise.
It will auto-create tables, but you need to give it a database name of a
pre-existing database and user with permissions with which cobbler can
create tables.
I hope someone will get some use from it.
Sean
---
cobbler/modules/serializer_mysql.py | 139 +++++++++++++++++++++++++++++++++++
cobbler/settings.py | 5 +
config/settings | 12 +++
3 files changed, 156 insertions(+), 0 deletions(-)
create mode 100644 cobbler/modules/serializer_mysql.py
diff --git a/cobbler/modules/serializer_mysql.py b/cobbler/modules/serializer_mysql.py
new file mode 100644
index 0000000..3cad584
--- /dev/null
+++ b/cobbler/modules/serializer_mysql.py
@@ -0,0 +1,139 @@
+"""
+MySQL Serializer code for cobbler
+
+based heavily on the serializer_catalog.py code
+
+"""
+import distutils.sysconfig
+import os
+import sys
+import MySQLdb
+
+from cexceptions import *
+import api as cobbler_api
+
+plib = distutils.sysconfig.get_python_lib()
+mod_path="%s/cobbler" % plib
+sys.path.insert(0, mod_path)
+
+def connect_db(type="master"):
+ capi = cobbler_api.BootAPI()
+ settings = capi.settings()
+
+ if type == "slave" and settings.mysql_server_slave != "":
+ host = settings.mysql_server_slave
+ else:
+ host = settings.mysql_server
+ try:
+ db = MySQLdb.connect(db=settings.mysql_database, user=settings.mysql_user, host=host)
+ except MySQLdb.Error, e:
+ raise CX("Error %d: %s" % (e.args[0], e.args[1]))
+
+ return db
+
+def register():
+ """
+ The mandatory cobbler module registration hook.
+ """
+ return "serializer"
+
+def create_table_if_not_exists(db, table):
+ """
+ Internal serializer function to create the MySQL table if it doesn't already exist.
+ """
+ c = db.cursor()
+ if not c.execute("SHOW TABLES LIKE '"+table+"'"):
+ c.execute("CREATE TABLE IF NOT EXISTS "+table+" ( name varchar(255) PRIMARY KEY, data TEXT ) Engine=InnoDB")
+
+ return None
+
+def serialize_item(obj, item):
+ db = connect_db()
+ table = obj.collection_type()
+
+ create_table_if_not_exists(db, table)
+ c = db.cursor()
+ datastruct = item.to_datastruct()
+ c.execute("REPLACE INTO "+table+""" (name, data) VALUES (%s, %s)""", (str(item.name), repr(datastruct)))
+ db.commit()
+ db.close()
+ return True
+
+def serialize_delete(obj, item):
+ db = connect_db()
+ table = obj.collection_type()
+ c = db.cursor()
+ c.execute("DELETE FROM "+table+""" WHERE name = %s""", (item.name,))
+ db.commit()
+ db.close()
+ return True
+
+def deserialize_item_raw(collection_type, item_name):
+ db = connect_db("slave")
+ table = obj.collection_type()
+ c = db.cursor()
+
+ try:
+ c.execute("SELECT data FROM "+table+" WHERE name = %s""", (item_name,))
+ except MySQLdb.ProgrammingError:
+ sys.stderr.write("error retrieving row for %s in %s\n" % (item_name, table))
+ db.close()
+ return None
+ row = c.fetchone()
+ datastruct = eval(row[0])
+ db.close()
+ return datastruct
+
+def serialize(obj):
+ """
+ Save an object to the database. Object must "implement" Serializable.
+ Will create the table if it can. Returns True on Success,
+ False on permission errors.
+ This should not be used by API if serialize_item is available.
+ """
+
+ for entry in obj:
+ serialize_item(obj, entry)
+ return True
+
+def deserialize_raw(collection_type):
+ datastruct = []
+ db = connect_db("slave")
+ c = db.cursor()
+ try:
+ c.execute("SELECT data FROM "+collection_type)
+ except MySQLdb.ProgrammingError:
+ return []
+ while (1):
+ row = c.fetchone()
+ if row == None:
+ break
+ datastruct.append(eval(row[0]))
+ db.close()
+ return datastruct
+
+def deserialize(obj,topological=False):
+ """
+ Populate an existing object with the contents of datastruct.
+ Object must "implement" Serializable.
+ """
+
+ datastruct = deserialize_raw(obj.collection_type())
+
+ if topological and type(datastruct) == list:
+ # in order to build the graph links from the flat list, sort by the
+ # depth of items in the graph. If an object doesn't have a depth, sort it as
+ # if the depth were 0. It will be assigned a proper depth at serialization
+ # time. This is a bit cleaner implementation wise than a topological sort,
+ # though that would make a shiny upgrade.
+ datastruct.sort(__depth_cmp)
+ obj.from_datastruct(datastruct)
+ return True
+
+def __depth_cmp(item1, item2):
+ if not item1.has_key("depth"):
+ return 1
+ if not item2.has_key("depth"):
+ return -1
+ return cmp(item1["depth"],item2["depth"])
+
diff --git a/cobbler/settings.py b/cobbler/settings.py
index 527b3dc..66158ef 100644
--- a/cobbler/settings.py
+++ b/cobbler/settings.py
@@ -61,6 +61,11 @@ DEFAULTS = {
"manage_dns" : 0,
"manage_forward_zones" : [],
"manage_reverse_zones" : [],
+ "mysql_database" : 'cobbler',
+ "mysql_password" : '',
+ "mysql_server" : 'localhost',
+ "mysql_server_slave" : '',
+ "mysql_user" : 'cobbler',
"named_conf" : "/etc/named.conf",
"next_server" : "127.0.0.1",
"omapi_enabled" : 0,
diff --git a/config/settings b/config/settings
index d48e2f4..190aec6 100644
--- a/config/settings
+++ b/config/settings
@@ -94,6 +94,18 @@ manage_dns: 0
manage_forward_zones: []
manage_reverse_zones: []
+# if using serializer_mysql to store objects, you can set the MySQL DB
+# configuration parameters here. You can ignore this if you are not
+# using "serializer_mysql"
+# If you set "mysql_server_slave" to something other than '', cobbler will
+# query that MySQL server for all SELECTs and send updates to mysql_server.
+# You can use that to support a master->slave replication environment.
+mysql_server: 'localhost'
+mysql_server_slave: ''
+mysql_database: 'cobbler'
+mysql_user: 'cobbler'
+mysql_password: ''
+
# if using cobbler with manage_dhcp, put the IP address
# of the cobbler server here so that PXE booting guests can find it
# if you do not set this correctly, this will be manifested in TFTP open timeouts.
--
1.5.5.1
_______________________________________________
cobbler mailing list
[email protected]
https://fedorahosted.org/mailman/listinfo/cobbler