From 49f7d48d65baefe64d93503d05978cf75c38444b Mon Sep 17 00:00:00 2001
From: Alain Takoudjou <alain.takoudjou@nexedi.com>
Date: Wed, 24 Jun 2015 13:41:56 +0200
Subject: [PATCH] kvm: add parameter to set text content which will be
 available for VMs of cluster

text content is saved in a file called 'data' of the corresponding http server. the file can be downloaded into the vm with:
- https://10.0.2.101/FOLDER_HASH/data : if parameter 'cluster-data' is used (for kvm-cluster only, file is accessible from all vm)
- http://10.0.2.100/data : if parameter 'data-to-vm' is used.
---
 software/kvm/common.cfg                       |  6 ++--
 .../instance-kvm-cluster-input-schema.json    | 12 ++++++-
 .../kvm/instance-kvm-cluster.cfg.jinja2.in    | 24 +++++++++++--
 software/kvm/instance-kvm-input-schema.json   | 21 ++++++++++-
 software/kvm/instance-kvm.cfg.jinja2          | 35 +++++++++++++------
 software/kvm/template/template-content.in     |  8 +++--
 6 files changed, 87 insertions(+), 19 deletions(-)

diff --git a/software/kvm/common.cfg b/software/kvm/common.cfg
index 1cb707feb..07d461976 100644
--- a/software/kvm/common.cfg
+++ b/software/kvm/common.cfg
@@ -95,7 +95,7 @@ mode = 0644
 recipe = hexagonit.recipe.download
 url = ${:_profile_base_location_}/instance-kvm.cfg.jinja2
 mode = 644
-md5sum = 3e3354844b2052609e3c49eca03b607e
+md5sum = fb2dcca424fa0bf4d6ec445965a8bc81
 download-only = true
 on-update = true
 
@@ -103,7 +103,7 @@ on-update = true
 recipe = hexagonit.recipe.download
 url = ${:_profile_base_location_}/instance-kvm-cluster.cfg.jinja2.in
 mode = 644
-md5sum = 1f7dc7b7f2740cf416927b144e93ccb1
+md5sum = 36d9ea062c13f88eadd6f635eed36b7e
 download-only = true
 on-update = true
 
@@ -182,7 +182,7 @@ recipe = hexagonit.recipe.download
 url = ${:_profile_base_location_}/template/template-content.in
 mode = 644
 filename = template-content.in
-md5sum = 47d492dafe5cb314bdc49bf013d21ead
+md5sum = 822737e483864bf255ad1259237bef2a
 download-only = true
 on-update = true
 
diff --git a/software/kvm/instance-kvm-cluster-input-schema.json b/software/kvm/instance-kvm-cluster-input-schema.json
index 3c8b1bfa1..93115bf20 100644
--- a/software/kvm/instance-kvm-cluster-input-schema.json
+++ b/software/kvm/instance-kvm-cluster-input-schema.json
@@ -122,11 +122,16 @@
       },
       "type": "object"
     },
-    "authorized-key": {
+    "authorized-keys": {
       "title": "Public keys for virtual machines.",
       "description": "Set the list of public keys to add in your virtual machine. The public key file will be available in the VM via url http://10.0.2.100/authorized_keys if you keep the NAT interface enabled",
       "type": "array"
     },
+    "cluster-data": {
+      "title": "Text content to share with virtual machines.",
+      "description": "Text content which will be written in a file data of cluster http server. All VM will be able to download that file via the static URL of cluster HTTP server: https://10.0.2.101/FOLDER_HASH/data.",
+      "type": "string"
+    },
     "kvm-partition-dict": {
       "title": "kvm instances definition",
       "description": "kvm instances definition",
@@ -284,6 +289,11 @@
                 80,
                 443
               ]
+            },
+            "data-to-vm": {
+              "title": "Text content to send to this virtual machine.",
+              "description": "Text content which will be written in a file 'data' of http server of this virtual machine instance. The file will be available via URL: http://10.0.2.100/data in the VM.",
+              "type": "string"
             }
           },
           "type": "object"
diff --git a/software/kvm/instance-kvm-cluster.cfg.jinja2.in b/software/kvm/instance-kvm-cluster.cfg.jinja2.in
index c649ab9e9..0b1db1acf 100644
--- a/software/kvm/instance-kvm-cluster.cfg.jinja2.in
+++ b/software/kvm/instance-kvm-cluster.cfg.jinja2.in
@@ -34,8 +34,8 @@ config-frontend-software-type = {{ dumps(frontend_dict.get('software-type', 'fro
 config-frontend-software-url = {{ dumps(frontend_dict.get('software-url', 'http://git.erp5.org/gitweb/slapos.git/blob_plain/refs/tags/slapos-0.92:/software/kvm/software.cfg')) }}
 config-frontend-instance-guid = {{ dumps(frontend_dict.get('instance-guid', '')) }}
 config-name = {{ instance_name }}
-{% if slapparameter_dict.get('authorized-key', []) -%}
-config-authorized-key = {{ slapparameter_dict.get('authorized-key') | join('##') }}
+{% if slapparameter_dict.get('authorized-keys', []) -%}
+config-authorized-key = {{ dumps(slapparameter_dict.get('authorized-keys') | join('\n')) }}
 {% endif -%}
 config-nbd-port = {{ dumps(kvm_parameter_dict.get('nbd-port', 1024)) }}
 config-nbd-host = {{ dumps(kvm_parameter_dict.get('nbd-host', '')) }}
@@ -61,6 +61,9 @@ config-external-disk-size = {{ dumps(kvm_parameter_dict.get('external-disk-size'
 config-external-disk-format = {{ dumps(kvm_parameter_dict.get('external-disk-format', 'qcow2')) }}
 config-enable-http-server = {{ dumps(kvm_parameter_dict.get('enable-http-server', True)) }}
 config-httpd-port = {{ dumps(kvm_parameter_dict.get('httpd-port', 8081)) }}
+{% if kvm_parameter_dict.get('data-to-vm', '') -%}
+config-data-to-vm = {{ dumps(kvm_parameter_dict.get('data-to-vm', '')) }}
+{% endif -%}
 
 # Enable simple http server on ipv6 so all VMs will access it
 config-document-host = ${http-server:host}
@@ -161,6 +164,7 @@ wrapper = ${directory:services}/simple-http-server
 log-file = ${directory:log}/http.log
 cert-file = ${http-ssl:cert}
 key-file = ${http-ssl:key}
+{% do publish_dict.__setitem__('http-file-server', 'https://' ~ '[${http-server:host}]:' ~ '${http-server:port}/' ~ '${http-server:path}') -%}
 
 [write-vm-hostname]
 recipe = slapos.recipe.template:jinja2
@@ -171,6 +175,22 @@ context =
     raw content_list {{ kvm_hostname_list | join('#') }}
     raw sep #
 
+{% macro writefile(section_name, file_path, content, mode='') -%}
+{% do part_list.append(section_name) -%}
+{% set data_list =  content.split('\n') -%}
+[{{ section_name }}]
+recipe = collective.recipe.template
+input = inline:
+  {{ data_list | join('\n  ') }}
+output = {{ file_path }}
+mode = {{ mode }}
+{% endmacro -%}
+
+# write cluster-data into file public/data
+{% if slapparameter_dict.get('cluster-data', '') -%}
+{{ writefile('cluster-data-content', '${http-server:root-dir}/data', slapparameter_dict.get('cluster-data', ''), '700') }}
+{% endif -%}
+
 [publish]
 recipe = slapos.cookbook:publish
 {% for name, value in publish_dict.items() -%}
diff --git a/software/kvm/instance-kvm-input-schema.json b/software/kvm/instance-kvm-input-schema.json
index 90c257e3e..264f3cb9c 100644
--- a/software/kvm/instance-kvm-input-schema.json
+++ b/software/kvm/instance-kvm-input-schema.json
@@ -135,9 +135,28 @@
       "description": "List of rules for NAT of QEMU user mode network stack, as comma-separated list of ports. For each port specified, it will redirect port x of the VM (example: 80) to the port x + 10000 of the public IPv6 (example: 10080). Defaults to \"22 80 443\". Ignored if \"use-tap\" parameter is enabled.",
       "type": "string"
     },
+    "enable-http-server": {
+      "title": "Enable local http server",
+      "description": "Set if local http server which serve files to the vm should be deployed. If set to true, get file into the vm with URL: http://10.0.2.100/FILE.",
+      "type": "boolean",
+      "default": false
+    },
+    "httpd-port": {
+      "title": "Local http server port",
+      "description": "Port of the local http server used to share files.",
+      "type": "integer",
+      "default": 8081,
+      "minimum": 1,
+      "maximum": 65535
+    },
     "authorized-key": {
       "title": "Public keys to get from all virtual machines.",
-      "description": "Set the public keys to add in your virtual machine. Keys are separated with '##'. The public key file will be available in the VM via url http://10.0.2.100/authorized_keys if you keep the NAT interface enabled",
+      "description": "Set the public keys to add in your virtual machine. The public key file will be available in the VM via url http://10.0.2.100/authorized_keys if you keep the NAT interface enabled",
+      "type": "string"
+    },
+    "data-to-vm": {
+      "title": "Text content to send to this virtual machine.",
+      "description": "Text content which will be written in a file 'data' of http server of this virtual machine instance. The file will be available via URL: http://10.0.2.100/data in the VM.",
       "type": "string"
     },
     "frontend-instance-guid": {
diff --git a/software/kvm/instance-kvm.cfg.jinja2 b/software/kvm/instance-kvm.cfg.jinja2
index 3cc361b49..870090900 100644
--- a/software/kvm/instance-kvm.cfg.jinja2
+++ b/software/kvm/instance-kvm.cfg.jinja2
@@ -23,6 +23,12 @@ parts =
   httpd
   httpd-promise
   publish-host-config
+{% if slapparameter_dict.get('data-to-vm', '') %}
+  vm-data-content
+{% endif -%}
+{% if slapparameter_dict.get('authorized-key', '') %}
+  get-authorized-key
+{%   endif -%}
   
 extends = 
   {{ template_httpd_cfg }}
@@ -295,7 +301,7 @@ tap-ipv4 = ${slap-network-information:tap-ipv4}
 {%     set kvm_http = 'http://10.0.2.100' -%}
 {%   endif %}
 {%   if slapparameter_dict.get('authorized-key', '') -%}
-7_info = Get the publick key file in your VM with the command: wget {{ kvm_http }}/${get-authorized-key:filename}
+7_info = Get the publick key file in your VM with the command: wget {{ kvm_http }}/authorized_keys
 {%   endif %}
 {% endif %}
 
@@ -332,15 +338,21 @@ command =
 update-command = ${:command}
 {% endif -%}
 
-[get-authorized-key]
-recipe = slapos.recipe.template:jinja2
-template = {{ template_content }}
-filename = authorized_keys
-rendered = ${directory:public}/${:filename}
-public-key = {{ slapparameter_dict.get('authorized-key', '') }}
-context =
-    key content_list :public-key
-    raw sep ##
+{% macro writefile(section_name, file_path, content, mode='') -%}
+{% set data_list =  content.split('\n') -%}
+[{{ section_name }}]
+recipe = collective.recipe.template
+input = inline:
+  {{ data_list | join('\n  ') }}
+output = {{ file_path }}
+mode = {{ mode }}
+{% endmacro -%}
+
+# write vm-data into file public/data
+{{ writefile('vm-data-content', '${directory:public}/data', slapparameter_dict.get('data-to-vm', ''), '700') }}
+
+# write public key for vms to public/authorized_keys
+{{ writefile('get-authorized-key', '${directory:public}/authorized_keys', slapparameter_dict.get('authorized-key', ''), '700') }}
 
 [publish-host-config]
 recipe = plone.recipe.command
@@ -419,3 +431,6 @@ enable-http-server = False
 httpd-port = 8081
 # for auto config, the public key file will be available in the VM via url http://10.0.2.100/authorized_key if use-nat = True
 authorized-key = 
+
+# send some content which will be accessible to the vm through static url: http://10.0.2.100/data
+data-to-vm =
diff --git a/software/kvm/template/template-content.in b/software/kvm/template/template-content.in
index eb9efd6a2..22557669c 100644
--- a/software/kvm/template/template-content.in
+++ b/software/kvm/template/template-content.in
@@ -1,3 +1,7 @@
-{% for content in content_list.split(sep) -%}
+{% if not sep -%}
+{{ content_list }}
+{% else -%}
+{%   for content in content_list.split(sep) -%}
 {{ content }}
-{% endfor -%}
\ No newline at end of file
+{%   endfor -%}
+{% endif -%}
\ No newline at end of file
-- 
2.30.9