From 8cd32a72e1770bb6ee7f2b28d3344d127f52eed9 Mon Sep 17 00:00:00 2001
From: Yingjie Xu <yxu@nexedi.com>
Date: Thu, 19 Apr 2012 13:58:21 +0200
Subject: [PATCH] SlapOS Test Agent Packaging.

---
 slapos/recipe/agent/__init__.py    | 89 +++++++++++++++++++++++++++++-
 slapos/recipe/agent/catdatefile.py | 14 +++++
 software/agent/instance-agent.cfg  | 23 --------
 software/agent/instance.cfg        | 33 ++++++-----
 software/agent/software.cfg        | 32 ++++++++---
 5 files changed, 143 insertions(+), 48 deletions(-)
 create mode 100644 slapos/recipe/agent/catdatefile.py
 delete mode 100644 software/agent/instance-agent.cfg

diff --git a/slapos/recipe/agent/__init__.py b/slapos/recipe/agent/__init__.py
index f199f13bd..0ea8a163b 100644
--- a/slapos/recipe/agent/__init__.py
+++ b/slapos/recipe/agent/__init__.py
@@ -28,9 +28,92 @@
 import os
 import sys
 import zc.buildout
-from slapos.recipe.librecipe import GenericBaseRecipe
+import slapos.slap
+from slapos.recipe.librecipe import BaseSlapRecipe
+from slapos.recipe.librecipe import GenericSlapRecipe
+import json
+import ConfigParser
 
-class Recipe(GenericBaseRecipe):
+class Recipe(BaseSlapRecipe, GenericSlapRecipe):
   def install(self):
+    self.path_list = []
+    self.crond = self.installCrond()
 
-    return []
+    slap = slapos.slap.slap()
+    computer_id = self.computer_id
+    computer_partition_id = self.computer_partition_id
+    server_url = self.server_url
+    key_file = self.key_file
+    cert_file = self.cert_file
+    slap.initializeConnection(server_url, key_file, cert_file)
+    self.computer_partition = slap.registerComputerPartition(
+        computer_id, computer_partition_id)
+    self.parameter_dict = self.computer_partition.getInstanceParameterDict()
+
+    configuration_path = os.path.join(self.work_directory, "agent.cfg")
+    configuration = ConfigParser.SafeConfigParser()
+    configuration.add_section("agent")
+    configuration.set("agent", "portal_url", self.parameter_dict["portal_url"])
+    configuration.set("agent", "master_url", self.parameter_dict["master_url"])
+    key_filepath = os.path.join(self.work_directory, "key")
+    key_file = open(key_filepath, "w")
+    key_file.write(self.parameter_dict["key"])
+    key_file.close()
+    configuration.set("agent", "key_file", key_filepath)
+    cert_filepath = os.path.join(self.work_directory, "cert")
+    cert_file = open(cert_filepath, "w")
+    cert_file.write(self.parameter_dict["cert"])
+    cert_file.close()
+    configuration.set("agent", "cert_file", cert_filepath)
+    configuration.set("agent", "maximum_software_installation_duration",
+        self.parameter_dict["maximum_software_installation_duration"])
+    configuration.set("agent", "software_live_duration",
+        self.parameter_dict["software_live_duration"])
+    configuration.set("agent", "computer_list",
+        self.parameter_dict["computer_list"])
+    configuration.set("agent", "software_list",
+        self.parameter_dict["software_list"])
+    configuration.set("agent", "log_directory", self.options["log_directory"])
+    configuration.set("agent", "state_file", self.options["state_file"])
+    state = open(self.options["state_file"], "w")
+    state.write('')
+    state.close()
+    configuration.add_section("software_uri")
+    software_list = json.loads(self.parameter_dict["software_list"])
+    for software in software_list:
+      configuration.set("software_uri", software, self.parameter_dict[software])
+
+    configuration.write(open(configuration_path, "w"))
+
+    agent_crond_path = os.path.join(self.crond, "agent")
+    agent_crond = open(agent_crond_path, "w")
+    agent_crond.write("*/1 * * * * %s -S %s" % \
+      (self.options["python_binary"],
+        "%s --pidfile=%s %s" % \
+          (self.options["agent_binary"], self.options["pidfile"],
+            configuration_path)))
+    agent_crond.close()
+
+    return self.path_list + [configuration_path, key_filepath, cert_filepath, agent_crond_path]
+
+  def installCrond(self):
+    _, self.ws = self.egg.working_set()
+    timestamps = self.createDataDirectory('cronstamps')
+    cron_output = os.path.join(self.log_directory, 'cron-output')
+    self._createDirectory(cron_output)
+    catcher = zc.buildout.easy_install.scripts([('catchcron',
+      __name__ + '.catdatefile', 'catdatefile')], self.ws, sys.executable,
+      self.bin_directory, arguments=[cron_output])[0]
+    self.path_list.append(catcher)
+    cron_d = os.path.join(self.etc_directory, 'cron.d')
+    crontabs = os.path.join(self.etc_directory, 'crontabs')
+    self._createDirectory(cron_d)
+    self._createDirectory(crontabs)
+    wrapper = zc.buildout.easy_install.scripts([('crond',
+      'slapos.recipe.librecipe.execute', 'execute')], self.ws, sys.executable,
+      self.wrapper_directory, arguments=[
+        self.options['dcrond_binary'].strip(), '-s', cron_d, '-c', crontabs,
+        '-t', timestamps, '-f', '-l', '5', '-M', catcher]
+      )[0]
+    self.path_list.append(wrapper)
+    return cron_d
diff --git a/slapos/recipe/agent/catdatefile.py b/slapos/recipe/agent/catdatefile.py
new file mode 100644
index 000000000..d3de298b2
--- /dev/null
+++ b/slapos/recipe/agent/catdatefile.py
@@ -0,0 +1,14 @@
+import os
+import sys
+import time
+def catdatefile(args):
+  directory = args[0]
+  try:
+    suffix = args[1]
+  except IndexError:
+    suffix = '.log'
+  f = open(os.path.join(directory,
+    time.strftime('%Y-%m-%d.%H:%M.%s') + suffix), 'aw')
+  for line in sys.stdin.read():
+    f.write(line)
+  f.close()
diff --git a/software/agent/instance-agent.cfg b/software/agent/instance-agent.cfg
deleted file mode 100644
index bca330cc3..000000000
--- a/software/agent/instance-agent.cfg
+++ /dev/null
@@ -1,23 +0,0 @@
-[buildout]
-parts =
-  agent-instance
-
-eggs-directory = ${buildout:eggs-directory}
-develop-eggs-directory = ${buildout:develop-eggs-directory} 
-offline = true
-
-[agent-instance]
-recipe = slapos.cookbook:agent
-
-[rootdirectory]
-recipe = slapos.cookbook:mkdirectory
-etc = $${buildout:directory}/etc
-var = $${buildout:directory}/var
-srv = $${buildout:directory}/srv
-bin = $${buildout:directory}/bin
-
-[basedirectory]
-recipe = slapos.cookbook:mkdirectory
-services = $${rootdirectory:etc}/run
-run = $${rootdirectory:var}/run
-framebuffer = $${rootdirectory:srv}/framebuffer
diff --git a/software/agent/instance.cfg b/software/agent/instance.cfg
index 6a1f274ba..15ef5a0e4 100644
--- a/software/agent/instance.cfg
+++ b/software/agent/instance.cfg
@@ -1,18 +1,25 @@
 [buildout]
 parts =
-  switch-softwaretype
+  rootdirectory
+  instance
+
 eggs-directory = ${buildout:eggs-directory}
 develop-eggs-directory = ${buildout:develop-eggs-directory}
-offline = true
 
-[switch-softwaretype]
-recipe = slapos.cookbook:softwaretype
-default = ${template-agent:output}
-  
-[slap-connection]
-computer-id = $${slap_connection:computer_id}
-partition-id = $${slap_connection:partition_id}
-server-url = $${slap_connection:server_url}
-software-release-url = $${slap_connection:software_release_url}
-key-file = $${slap_connection:key_file}
-cert-file = $${slap_connection:cert_file}
+[instance]
+recipe = ${instance-recipe:egg}:${instance-recipe:module}
+agent_binary = ${buildout:directory}/bin/agent
+dcrond_binary = ${dcron:location}/sbin/crond
+python_binary = ${python2.7:location}/bin/python
+pidfile = $${buildout:directory}/agent.pid
+log_directory = $${buildout:directory}/var/log
+state_file = $${buildout:directory}/state.cfg
+
+[rootdirectory]
+recipe = slapos.cookbook:mkdirectory
+etc = $${buildout:directory}/etc/
+run = $${rootdirectory:etc}/run/
+var = $${buildout:directory}/var/
+log = $${rootdirectory:var}/log/
+srv = $${buildout:directory}/srv/
+bin = $${buildout:directory}/bin/
diff --git a/software/agent/software.cfg b/software/agent/software.cfg
index a94d03bf7..51e9ce5dd 100644
--- a/software/agent/software.cfg
+++ b/software/agent/software.cfg
@@ -1,7 +1,7 @@
 [buildout]
 
 develop =
-  /srv/slapgrid/slappart2/srv/runner/project/SlapOS
+  /opt/slapdev
   /opt/slapos.toolbox
 
 extends =
@@ -13,21 +13,25 @@ extends =
 parts =
   template
   eggs
+  instance-recipe-egg
   dcron
   python2.7
+  script
+
+[instance-recipe]
+egg = slapos.cookbook
+module = agent
+
+[instance-recipe-egg]
+recipe = zc.recipe.egg
+python = python2.7
+eggs = ${instance-recipe:egg}
 
 [template]
 recipe = slapos.recipe.template
 url = ${:_profile_base_location_}/instance.cfg
-md5sum = 3cd7b47f979bb880eb9f61f8424e2814
 output = ${buildout:directory}/template.cfg
-mode = 0644
-
-[template-agent]
-recipe = slapos.recipe.template
-url = ${:_profile_base_location_}/instance-agent.cfg
-md5sum = 400945519a33bbdd6a807dbc6b828169
-output = ${buildout:directory}/template-agent.cfg
+md5sum = 2e1a7a68b18de68b163e98a5f92cc776
 mode = 0644
 
 [eggs]
@@ -41,6 +45,16 @@ eggs =
 [lxml-python]
 python = python2.7
 
+[script]
+recipe = z3c.recipe.scripts
+python = python2.7
+eggs =
+  zc.buildout
+  ${lxml-python:egg}
+  slapos.core
+  slapos.cookbook
+  slapos.toolbox
+
 [networkcache]
 # signature certificates of the following uploaders.
 #   Romain Courteaud
-- 
2.30.9