Commit 0359eddb authored by Alain Takoudjou's avatar Alain Takoudjou

kvm-cluster software release allow to clone vm into another instance

parent 9e3acf2a
......@@ -7,7 +7,6 @@ extends =
../../component/dcron/buildout.cfg
../../component/gzip/buildout.cfg
../../component/qemu-kvm/buildout.cfg
../../component/logrotate/buildout.cfg
../../component/noVNC/buildout.cfg
../../component/openssl/buildout.cfg
../../component/dcron/buildout.cfg
......@@ -15,8 +14,12 @@ extends =
../../component/pycurl/buildout.cfg
../../stack/slapos.cfg
../../stack/nodejs.cfg
../../stack/logrotate/buildout.cfg
../../stack/resilient/buildout.cfg
../../stack/monitor/buildout.cfg
../../stack/certificate-authority/buildout.cfg
../../stack/sshd/buildout.cfg
../../stack/sync/buildout.cfg
# stacks are listed from most generic to most specific,
# to avoid versioning issues
......@@ -44,6 +47,7 @@ parts =
[eggs]
recipe = zc.recipe.egg
interpreter = python.eggs
eggs =
${python-cffi:egg}
${python-cryptography:egg}
......@@ -92,7 +96,7 @@ command =
[template]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/instance.cfg.in
md5sum = 110df709a7c8a5c749f93663f6ab0d28
md5sum = aa44905893b2ca9268f9ffc6cdf85340
output = ${buildout:directory}/template.cfg
mode = 0644
......@@ -101,7 +105,7 @@ recipe = hexagonit.recipe.download
ignore-existing = true
url = ${:_profile_base_location_}/instance-kvm.cfg.jinja2
mode = 644
md5sum = d09d37dc3bcf34da8d31b11215866b27
md5sum = 730d1b066f606e64b3652d83c3c54026
download-only = true
on-update = true
......@@ -110,7 +114,7 @@ recipe = hexagonit.recipe.download
ignore-existing = true
url = ${:_profile_base_location_}/instance-kvm-cluster.cfg.jinja2.in
mode = 644
md5sum = 6ef7e38526f024356743e77973f0fb5f
md5sum = 52151f5a8ff341206d23034694c2f776
download-only = true
on-update = true
......@@ -168,6 +172,15 @@ md5sum = 22bd2e0c8fdb39a764a14c403a3bd752
download-only = true
mode = 0755
[template-kvm-moved]
recipe = hexagonit.recipe.download
ignore-existing = true
url = ${:_profile_base_location_}/instance-kvm-moved.cfg.jinja2
mode = 644
md5sum = 36c04df26b315f45e97257ac40f10b41
download-only = true
on-update = true
[template-nbd]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/instance-nbd.cfg.in
......@@ -197,7 +210,7 @@ ignore-existing = true
url = ${:_profile_base_location_}/template/template-kvm-run.in
mode = 644
filename = template-kvm-run.in
md5sum = 178a24cdad77cb6c2e519ac629dd0e74
md5sum = ca4bdec9ea5944de5fd23f3c7de0762f
download-only = true
on-update = true
......@@ -251,23 +264,32 @@ md5sum = 599dbbbd438fe7801e3f8642ae9e9a78
download-only = true
on-update = true
[template-logrotate-base]
recipe = slapos.recipe.template:jinja2
filename = instance-logrotate-base.cfg
template = ${:_profile_base_location_}/instance-logrotate-base.cfg.in
rendered = ${buildout:parts-directory}/${:_buildout_section_name_}/instance-logrotate-base.cfg
md5sum = f28fbd310944f321ccb34b2a34c82005
context =
key dcron_location dcron:location
key gzip_location gzip:location
key logrotate_location logrotate:location
[template-before-clone-script]
recipe = hexagonit.recipe.download
ignore-existing = true
url = ${:_profile_base_location_}/template/kvm-before-clone.py.in
mode = 644
filename = kvm-before-clone.py.in
md5sum = 9155900468a051d7686e076ec50d7ee5
download-only = true
on-update = true
[template-certificate-sign-bash]
recipe = hexagonit.recipe.download
ignore-existing = true
url = ${:_profile_base_location_}/template/ca-sign.sh.in
mode = 644
filename = ca-sign.sh.in
md5sum = ebd6f1c1ded6532aad24561d1f16cc3a
download-only = true
on-update = true
[template-httpd]
recipe = slapos.recipe.template:jinja2
filename = template-httpd.cfg
template = ${:_profile_base_location_}/instance-kvm-http.cfg.in
rendered = ${buildout:parts-directory}/${:_buildout_section_name_}/instance-kvm-http.cfg
md5sum = 26a181a48046ce88570adb32334747ef
md5sum = 833e64bc2d389d4c9ed8e1754220016f
context =
key apache_location apache:location
raw openssl_executable_location ${openssl:location}/bin/openssl
......
......@@ -389,6 +389,18 @@
"description": "If the VM of cluster doesn't run Ansible and report status to this SlapOS instances, then this allow to disable ansible promise so your instance will not fail to check ansible promise.",
"type": "boolean",
"default": false
},
"instance-server-url": {
"title": "Server URL of the instance to clone.",
"description": "Server URL on instance where this VM should be copied. If specified, the Server instance will be stopped and data will be moved to this VM. Please specify this parameter only if you really know what you are doing.",
"format": "uri",
"type": "string"
},
"allow-to-move": {
"title": "Allow to clone and move this VM",
"description": "If set to False this VM will not be moved and will continue to exists event if the vm is cloned. If the VM was moved, set this to True will change the state to a normal VM.",
"type": "boolean",
"default": true
}
},
"type": "object"
......
{% set publish_dict = {} -%}
{% set part_list = [] -%}
{% set ipv6 = (ipv6 | list)[0] -%}
{% set kvm_parameter_list = slapparameter_dict.get('kvm-partition-dict', {'kvm-default': {}}).items() -%}
{% set frontend_dict = slapparameter_dict.get('frontend', {}) -%}
{% set slave_frontend_dict = slapparameter_dict.get('slave-frontend', {}) -%}
{% set slave_frontend_sr = slave_frontend_dict.get('software-url', 'http://git.erp5.org/gitweb/slapos.git/blob_plain/HEAD:/software/apache-frontend/software.cfg') -%}
......@@ -9,6 +10,8 @@
{% set kvm_instance_dict = {} -%}
{% set kvm_hostname_list = [] -%}
{% set monitor_url_list = [] -%}
{% set instance_cn_list = [] -%}
{% set skip_publish_list = [] -%}
{% set enable_monitoring = slapparameter_dict.get('enable-monitor', True) -%}
[request-common]
......@@ -22,12 +25,25 @@ partition-id = ${slap-connection:partition-id}
config-use-ipv6 = {{ dumps(slapparameter_dict.get('use-ipv6', False)) }}
# Request kvm instances
{% for instance_name, kvm_parameter_dict in slapparameter_dict.get('kvm-partition-dict', {'kvm-default': {}}).items() -%}
{% for instance_name, kvm_parameter_dict in kvm_parameter_list -%}
{% set section = 'request-' ~ instance_name -%}
{% set use_nat = kvm_parameter_dict.get('use-nat', 'True') -%}
{% do instance_cn_list.append('instance@' ~ instance_name) -%}
{% set skip_publish = False -%}
{% set item_dict = {'skip_publish': False, 'has_slave': False} -%}
[{{ section }}]
<= request-common
software-type = kvm
{% for slave in slave_instance_list -%}
{% if slave.get('source', '') == instance_name and slave.has_key('software-type') -%}
{% do item_dict.__setitem__('has_slave', True) -%}
{% if kvm_parameter_dict.get('allow-to-move', True) -%}
{% do skip_publish_list.extend([instance_name ~ '-backend-url', instance_name ~ '-url']) -%}
# Redefine software-type to {{ slave['software-type'] }}
software-type = {{ slave['software-type'] }}
{% endif -%}
{% endif -%}
{% endfor -%}
name = {{ instance_name }}
sla-computer_guid = {{ dumps(kvm_parameter_dict.get('computer-guid', '')) }}
{% if kvm_parameter_dict.get('state', '') == 'stopped' -%}
......@@ -89,18 +105,39 @@ config-document-port = ${apache-conf:port}
config-document-path = ${hash-code:passwd}
config-keyboard-layout-language = {{ dumps(kvm_parameter_dict.get('keyboard-layout-language', 'fr')) }}
config-type = cluster
config-root-instance-guid = {{ instance_guid }}
{% set bootstrap_script_url = slapparameter_dict.get('bootstrap-script-url', kvm_parameter_dict.get('bootstrap-script-url', '')) -%}
{% if bootstrap_script_url -%}
config-bootstrap-script-url = {{ bootstrap_script_url }}
{% endif -%}
config-allow-to-move-vm = {{ dumps(kvm_parameter_dict.get('allow-to-move', True)) }}
config-ca-url = ${certificate-authority-web:url}
{% set authorized_source_list = slapparameter_dict.get('fw-authorized-sources', []) -%}
{% set rejected_source_list = slapparameter_dict.get('fw-reject-sources', []) -%}
sla-fw_authorized_sources = {{ authorized_source_list | join(' ') }}
sla-fw_rejected_sources = {{ rejected_source_list | join(' ') }}
sla-fw_restricted_access = {{ dumps(slapparameter_dict.get('fw-restricted-access', 'off')) }}
{% set test = kvm_parameter_dict.get('allow-to-move', True) == True -%}
{% if kvm_parameter_dict.get('instance-server-url', '') -%}
{% do item_dict.__setitem__('skip_publish', True) -%}
recipe = slapos.cookbook:request.clone
clone-software-type = kvm-clone
clone-return = clone-is-done
{% if item_dict['has_slave'] and not kvm_parameter_dict.get('allow-to-move', True) -%}
{# If this vm was cloned, and user try to restore the vm, set force-create-clone to True to allow to clone the instance event if it is already deployed -#}
config-force-create-clone = True
clone-force-deploy = True
{% endif -%}
config-instance-server-url = {{ dumps(kvm_parameter_dict['instance-server-url']) }}
config-publish-parameter-name = clone-is-done
{% endif -%}
return =
url
backend-url
......@@ -117,7 +154,9 @@ return =
{{ ' ' }}tap-ipv4
{% do publish_dict.__setitem__('lan-' ~ instance_name, '${' ~ section ~ ':connection-tap-ipv4}') -%}
{% do kvm_hostname_list.append(instance_name ~ ' ' ~ '${' ~ section ~ ':connection-tap-ipv4}') -%}
{% if not item_dict['skip_publish'] -%}
{% do kvm_hostname_list.append(instance_name ~ ' ' ~ '${' ~ section ~ ':connection-tap-ipv4}') -%}
{% endif -%}
{% endif -%}
{% do publish_dict.__setitem__(instance_name ~ '-backend-url', '${' ~ section ~ ':connection-backend-url}') -%}
{% do publish_dict.__setitem__(instance_name ~ '-url', '${' ~ section ~ ':connection-url}') -%}
......@@ -246,20 +285,59 @@ monitor-url-list +=
private-path-list +=
${directory:webroot}/
# CA
[certificate-authority-parameters]
server-port = 8009
# crl-url =
[certificate-authority-sign]
recipe = slapos.recipe.template:jinja2
template = {{ template_certificate_sign_bash }}
rendered = ${directory:bin}/ca-sign
mode = 700
context =
raw ca_sign_script {{ certificate_authority_sign_bin }}
raw ca_directory ${ca-directory:ca-web}
raw ca_url ${certificate-authority-web:url}
raw ca_cn_list {{ instance_cn_list | join(' ') }}
raw client_host ${slap-network-information:global-ipv6}
[certificate-authority-sign-cron-entry]
recipe = slapos.cookbook:cron.d
cron-entries = ${cron:cron-entries}
name = certificate-authority-sign
frequency = * * * * *
command = ${certificate-authority-sign:rendered}
[publish-connection-information]
recipe = slapos.cookbook:publish
{% for name, value in publish_dict.items() -%}
{% if not name in skip_publish_list -%}
{{ name }} = {{ value }}
{% endif -%}
{% endfor %}
{% if enable_monitoring -%}
{% set monitor_interface_url = slapparameter_dict.get('monitor-interface-url', 'https://monitor.app.officejs.com') -%}
{% do part_list.append('monitor-base') -%}
monitor-setup-url = {{ monitor_interface_url }}/#page=settings_configurator&url=${publish:monitor-url}&username=${publish:monitor-user}&password=${publish:monitor-password}
{% endif -%}
ca-url = ${certificate-authority-web:url}
{% for slave in slave_instance_list -%}
{% if slave.get('source', '') and slave.has_key('software-type') -%}
{% do part_list.append('publish-' ~ slave['slave_reference']) -%}
[{{ 'publish-' ~ slave['slave_reference'] }}]
recipe = slapos.cookbook:publish
-slave-reference = {{ slave['slave_reference'] }}
instance-source = {{ slave['source'] }}
software-type = {{ slave['software-type'] }}
{% endif -%}
{% endfor %}
[buildout]
extends =
{{ template_httpd_cfg }}
{{ template_certificate_authority }}
{% if enable_monitoring -%}
{{ ' ' ~ template_monitor }}
{% endif -%}
......@@ -268,6 +346,8 @@ parts =
httpd
httpd-graceful
httpd-promise
certificate-authority-web
certificate-authority-sign-cron-entry
publish-connection-information
directory-doc
......
......@@ -58,10 +58,13 @@ mode = 700
[httpd-ssl]
recipe = plone.recipe.command
command = "{{ openssl_executable_location }}" req -newkey rsa -batch -new -x509 -days 3650 -nodes -keyout "${:key}" -out "${:cert}"
command =
if [ ! -s "${directory:ssl}/cert" ] || [ ! -s "${directory:ssl}/key" ]; then
"{{ openssl_executable_location }}" req -newkey rsa -batch -new -x509 -days 3650 -nodes -keyout "${:key}" -out "${:cert}"
fi
key = ${directory:ssl}/key
cert = ${directory:ssl}/cert
update-command =
update-command = ${:command}
stop-on-error = true
[httpd-promise]
......
......@@ -237,6 +237,24 @@
"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"
},
"instance-server-url": {
"title": "Server URL of the instance to clone.",
"description": "Server URL on instance where this VM should be copied. If specified, qemu hardrive will be copied from the specified instance.",
"format": "uri",
"type": "string"
},
"ca-url": {
"title": "Certificate Authority URL",
"description": "The certificate Authority web URL, if this parameter is not specified a new certificate Authority server will be deployed with this instance",
"format": "uri",
"type": "string"
},
"ca-cert": {
"title": "CA Certificate (optional)",
"description": "The CA certificate, if specified this certificate will be used or added to the current CA Certificate",
"format": "uri",
"type": "string"
},
"frontend-instance-guid": {
"title": "Frontend Instance ID",
"description": "Unique identifier of the frontend instance, like \"SOFTINST-11031\".",
......
{% set monitor = str(slapparameter_dict.get('enable-monitor', False)).lower() == 'true' -%}
[buildout]
extends =
{{ kvm_template }}
parts =
certificate-authority
authenticated-httpd-server
instance-sshd
cron
cron-entry-logrotate
cron-entry-instance-sync-server
server-is-ready
request-hibernate
{% if monitor -%}
# monitor parts
monitor-base
{% endif %}
publish-connection-information
[publish-connection-information]
backend-url =
url =
[server-is-ready]
recipe = plone.recipe.command
bang-done-file = ${directory:var}/request-bang-done
command =
if [ -s "${:bang-done-file}" ]; then
touch ${before-server-ready-script:start-file}
fi
update-command = ${:command}
[request-hibernate]
recipe = slapos.cookbook:request
software-url = ${slap-connection:software-release-url}
server-url = ${slap-connection:server-url}
key-file = ${slap-connection:key-file}
cert-file = ${slap-connection:cert-file}
computer-id = ${slap-connection:computer-id}
partition-id = ${slap-connection:partition-id}
software-type = kvm-cluster
name = {{ instance_name }}-hibernate
sla-instance_guid = {{ dumps(slapparameter_dict.get('root-instance-guid', '')) }}
config-software-type = kvm-moved
config-source = {{ instance_name }}
slave = true
#-XXX This section is defined in sync stack (instance-sync-server)
[server-post-sync-script]
work-dir = ${authenticated-server-parameters:web-directory}
input = inline:#!/bin/sh
# get client tap-ipv4 and send to slapgrid for update ip route
CLIENT_ID=$1
CLIENT_INFO=${:work-dir}/keys/$CLIENT_ID"_info"
if [ -s "$CLIENT_INFO" ]; then
GATEWAY_IP=$(cat $CLIENT_INFO | grep "tap-gateway" | cut -d' ' -f3)
if [ ! -z $GATEWAY_IP ]; then
cat << EOF > ${buildout:directory}/.${slap-connection:partition-id}-request-update-route
[${slap-connection:partition-id}-routes]
forward-to-ip = $GATEWAY_IP
interface = ${slap-network-information:network-interface}
EOF
echo "File ${buildout:directory}/.${slap-connection:partition-id}-request-update-route created"
fi
fi
\ No newline at end of file
......@@ -2,14 +2,17 @@
{% set use_tap = slapparameter_dict.get('use-tap', 'False').lower() -%}
{% set use_nat = slapparameter_dict.get('use-nat', 'True').lower() -%}
{% set nat_restrict = slapparameter_dict.get('nat-restrict-mode', 'False').lower() -%}
{% set name = slapparameter_dict.get('name', 'localhost') -%}
{% set name = slapparameter_dict.get('name', instance_name) -%}
{% set disable_ansible_promise = slapparameter_dict.get('disable-ansible-promise', 'True').lower() -%}
{% set instance_type = slapparameter_dict.get('type', 'standalone') -%}
{% set nat_rule_list = slapparameter_dict.get('nat-rules', '22 80 443') -%}
{% set frontend_software_type = 'default' -%}
{% set ca_url = slapparameter_dict.get('ca-url', '') -%}
{% set disk_number = len(storage_dict) -%}
{% set extends_list = [] -%}
{% set part_list = [] -%}
{% set monitor = str(slapparameter_dict.get('enable-monitor', True)).lower() == 'true' -%}
{% set monitor_interface_url = slapparameter_dict.get('monitor-interface-url', 'https://monitor.app.officejs.com') -%}
{% set bootstrap_url = '' -%}
{% set bootstrap_url_md5sum = '' -%}
......@@ -20,16 +23,38 @@
{% endif -%}
{% if instance_type == 'cluster' -%}
{% set nat_rule_list = slapparameter_dict.get('nat-rules', '') %}
{% set nat_rule_list = slapparameter_dict.get('nat-rules', '') -%}
{% if str(slapparameter_dict.get('allow-to-move-vm', True)).lower() == 'true' -%}
[before-server-ready-script]
# Script to run before allow to clone this VM (only for kvm-cluster)
recipe = slapos.recipe.template:jinja2
template = {{ template_before_clone_script }}
rendered = ${:output}
output = ${directory:bin}/sync-server-pre-ready
start-file = ${directory:var}/server-is-ready
context =
raw bang_script {{ template_bang_script }}
raw python_bin {{ python_executable }}
raw output_file ${directory:var}/request-bang-done
raw instance_guid {{ slapparameter_dict['root-instance-guid'] }}
raw software_type kvm-cluster
raw instance_name {{ name }}
section slapconnection_dict slap-connection
mode = 700
{% else -%}
{% do part_list.append('cleanup-status-files') -%}
{% endif -%}
{% endif -%}
{% if not nat_rule_list or not nat_rule_list.strip() -%}
{% set nat_rule_list = '' %}
{% set nat_rule_list = '' -%}
{% endif -%}
{% if monitor -%}
{% do extends_list.append(template_monitor) -%}
{% endif -%}
{% do extends_list.append(logrotate_cfg) -%}
{% do extends_list.extend([logrotate_cfg, template_instance_sshd, template_auth_httpd_server, template_server_sync, template_certificate_authority]) %}
[directory]
recipe = slapos.cookbook:mkdirectory
etc = ${buildout:directory}/etc
......@@ -138,7 +163,7 @@ cluster-doc-port = 0
netcat-binary = {{ netcat_bin }}
language = ${slap-parameter:keyboard-layout-language}
name = {{ slapparameter_dict.get('name', 'Single KVM') }}
name = {{ name }}
disk-cache = ${slap-parameter:disk-cache}
disk-aio = ${slap-parameter:disk-aio}
auto-ballooning = ${slap-parameter:auto-ballooning}
......@@ -146,6 +171,7 @@ machine-options = ${slap-parameter:machine-options}
cpu-options = ${slap-parameter:cpu-model}
log-file = ${directory:log}/qemu.log
sync-data = ${directory:srv}/sync-data
[kvm-run]
recipe = slapos.recipe.template:jinja2
......@@ -240,24 +266,15 @@ recipe = slapos.cookbook:signalwrapper
wrapper-path = ${directory:services}/websockify
wrapped-path = ${novnc-instance:path}
[certificate-authority]
recipe = slapos.cookbook:certificate_authority
openssl-binary = {{ openssl_executable_location }}
ca-dir = ${directory:ca-dir}
requests-directory = ${cadirectory:requests}
wrapper = ${directory:services}/certificate_authority
ca-private = ${cadirectory:private}
ca-certs = ${cadirectory:certs}
ca-newcerts = ${cadirectory:newcerts}
ca-crl = ${cadirectory:crl}
[cadirectory]
recipe = slapos.cookbook:mkdirectory
requests = ${directory:ca-dir}/requests/
private = ${directory:ca-dir}/private/
certs = ${directory:ca-dir}/certs/
newcerts = ${directory:ca-dir}/newcerts/
crl = ${directory:ca-dir}/crl/
{% if ca_url == '' -%}
{% do part_list.extend(['certificate-authority-web', 'certificate-authority-sign']) -%}
{% set ca_url = '${certificate-authority-web:url}' -%}
# Deploy CA
[certificate-authority-parameters]
server-port = 8009
frequency = * * * * *
cn-list = ${authenticated-server-parameters:common-name}
{% endif -%}
[ca-novnc]
<= certificate-authority
......@@ -273,25 +290,11 @@ path = ${directory:promises}/novnc_promise
hostname = ${novnc-instance:ip}
port = ${novnc-instance:port}
#----------------
#--
#-- Deploy cron.
[cron]
recipe = slapos.cookbook:cron
dcrond-binary = {{ dcron_executable_location }}
cron-entries = ${directory:cron-entries}
crontabs = ${directory:crontabs}
cronstamps = ${directory:cronstamps}
catcher = ${cron-simplelogger:wrapper}
binary = ${directory:services}/crond
[cron-simplelogger]
recipe = slapos.cookbook:simplelogger
wrapper = ${directory:bin}/cron_simplelogger
log = ${directory:log}/crond.log
# HTTPD AUTH
[authenticated-server-parameters]
ca-url = {{ ca_url }}
common-name = {{ 'instance@' ~ name }}
server-port = 8286
#----------------
#--
#-- Deploy frontend.
......@@ -341,7 +344,7 @@ port = ${httpd:port}
[monitor-instance-parameter]
monitor-httpd-port = 8026
monitor-title = {{ slapparameter_dict.get('name', 'KVM Standalone') }}
monitor-title = {{ name }}
cors-domains = {{ slapparameter_dict.get('monitor-cors-domains', 'monitor.app.officejs.com') }}
{% if slapparameter_dict.get('monitor-username', '') -%}
username = {{ slapparameter_dict['monitor-username'] }}
......@@ -357,7 +360,9 @@ recipe = slapos.cookbook:publish
ipv6 = ${slap-network-information:global-ipv6}
backend-url = https://[${novnc-instance:ip}]:${novnc-instance:port}/vnc_auto.html?host=[${novnc-instance:ip}]&port=${novnc-instance:port}&encrypt=1&password=${kvm-controller-parameter-dict:vnc-passwd}
url = ${request-slave-frontend:connection-url}/vnc_auto.html?host=${request-slave-frontend:connection-domainname}&port=${request-slave-frontend:connection-port}&encrypt=1&path=${request-slave-frontend:connection-resource}&password=${kvm-controller-parameter-dict:vnc-passwd}
{% set disk_number = len(storage_dict) -%}
ca-url = {{ ca_url }}
ssh-cmd = ${instance-sshd:ssh-command}
instance-server-url = ${authenticated-httpd-server:url}
maximum-extra-disk-amount = {{ disk_number }}
{% set iface = 'eth0' -%}
{% if use_nat == 'true' -%}
......@@ -383,30 +388,24 @@ tap-ipv4 = ${slap-network-information:tap-ipv4}
{% set kvm_http = 'http://10.0.2.100' -%}
{% endif %}
{% if slapparameter_dict.get('authorized-key', '') and slapparameter_dict.get('type', '') == 'cluster' -%}
7_info = Get the publick key file in your VM with the command: wget {{ kvm_http }}/authorized_keys
3_info = Get the publick key file in your VM with the command: wget {{ kvm_http }}/authorized_keys
{% endif %}
{% endif %}
{% if monitor -%}
monitor-base-url = ${publish:monitor-base-url}
{% set monitor_interface_url = slapparameter_dict.get('monitor-interface-url', 'https://monitor.app.officejs.com') -%}
{% if monitor_interface_url -%}
monitor-setup-url = {{ monitor_interface_url }}/#page=settings_configurator&url=${publish:monitor-url}&username=${publish:monitor-user}&password=${publish:monitor-password}
{% endif -%}
{% endif -%}
{% if use_tap == 'true' and tap_network_dict.has_key('ipv4') -%}
1_info = Use these configurations below to configure interface {{ iface }} in your VM.
2_info = ${network-config:ifconfig}
3_info = ${network-config:route-iface}
4_info = ${network-config:route-network}
5_info = ${network-config:route-default}
{% if enable_http == 'true' %}
6_info = Or run in your VM the command: wget -O- {{ kvm_http }}/netconfig.sh | /bin/sh -
1_info = Use these configurations below to configure interface {{ iface }} in your VM.
2_info = In your VM run the command: wget -O- ${network-config:url} | /bin/sh -
{% endif %}
[network-config]
recipe = plone.recipe.command
path = ${directory:public}/netconfig.sh
url = {{ kvm_http }}/netconfig.sh
ifconfig = ifconfig {{ iface }} ${slap-network-information:tap-ipv4} netmask ${slap-network-information:tap-netmask}
route-iface = route add ${slap-network-information:tap-gateway} dev {{ iface }}
route-network = route add -net ${slap-network-information:tap-network} netmask ${slap-network-information:tap-netmask} gw ${slap-network-information:tap-gateway}
......@@ -420,9 +419,17 @@ route-default = ip route add {{ global_ipv4_prefix }} via ${slap-network-informa
route-default =
{% endif -%}
command =
DATA_DIR=${directory:srv}/sync-data
echo "#!/bin/sh" > ${:path}
echo "" >> ${:path}
echo "${:ifconfig}" >> ${:path}
if [ -s "$DATA_DIR/ipv4" ]; then
echo "ifconfig {{ iface }} $(cat $DATA_DIR/ipv4) netmask ${slap-network-information:tap-netmask}" >> ${:path}
if [ -s "$DATA_DIR/network" ]; then
echo "route del -net $(cat $DATA_DIR/network) netmask ${slap-network-information:tap-netmask}" >> ${:path}
fi
else
echo "${:ifconfig}" >> ${:path}
fi
echo "${:route-iface}" >> ${:path}
echo "${:route-network}" >> ${:path}
echo "${:route-default}" >> ${:path}
......@@ -455,34 +462,42 @@ mode = {{ mode }}
[publish-host-config]
recipe = plone.recipe.command
name = {{ slapparameter_dict.get('name', 'localhost') }}
name = {{ name }}
{% if use_tap == 'true' and tap_network_dict.has_key('ipv4') -%}
local-ipv4 = ${slap-network-information:tap-ipv4}
gateway = ${slap-network-information:tap-gateway}
netmask = ${slap-network-information:tap-network}
network = ${slap-network-information:tap-netmask}
netmask = ${slap-network-information:tap-netmask}
network = ${slap-network-information:tap-network}
{% else -%}
local-ipv4 = 127.0.0.1
gateway =
netmask =
network =
{% endif -%}
path-host = ${directory:public}/hostname
path-ip = ${directory:public}/ipv4
path-gateway = ${directory:public}/gateway
path-network = ${directory:public}/network
path-netmask = ${directory:public}/netmask
command =
rm -f ${:path-host}
rm -f ${:path-ip}
rm -f ${:path-gateway}
rm -f ${:path-network}
rm -f ${:path-netmask}
echo "${:name}" > ${:path-host}
echo "${:local-ipv4}" > ${:path-ip}
echo "${:gateway}" > ${:path-gateway}
echo "${:network}" > ${:path-network}
echo "${:netmask}" > ${:path-netmask}
DATA_DIR=${directory:srv}/sync-data
BASE_DIR=${directory:public}
if [ -s "$DATA_DIR/ipv4" ]; then
IPv4=$(cat $DATA_DIR/ipv4)
cat << EOF > ${buildout:directory}/.${slap-connection:partition-id}-request-update-route
[${slap-connection:partition-id}-routes]
ip-to-interface = $IPv4
ip-to-interface-dnat = true
interface = ${slap-network-information:network-interface}
EOF
else
IPv4=${:local-ipv4}
fi
if [ -s "$DATA_DIR/hostname" ]; then
HOSTNAME=$(cat $DATA_DIR/hostname)
else
HOSTNAME=${:name}
fi
echo "$HOSTNAME" > $BASE_DIR/hostname
echo "$IPv4" > $BASE_DIR/ipv4
echo "${:gateway}" > $BASE_DIR/gateway
echo "${:network}" > $BASE_DIR/network
echo "${:netmask}" > $BASE_DIR/netmask
update-command = ${:command}
# To access documents of main instance (in case of kvm-cluster) through http
......@@ -524,23 +539,50 @@ command = {{ python_executable }} {{ file_download_script }} {{ bootstrap_url }}
update-command =
stop-on-error = true
[cron-entry-logrotate]
<= cron
recipe = slapos.cookbook:cron.d
name = logrotate
# One time per week
frequency = 0 0 * * *
command = ${logrotate:wrapper}
[logrotate-vm-bootstrap]
< = logrotate-entry-base
name = vm-bootstrap
log = ${directory:public}/ansible/vm-bootstrap.log
[logrotate-entry-base]
recipe = slapos.cookbook:logrotate.d
logrotate-entries = ${logrotate:logrotate-entries}
backup = ${logrotate:backup}
[cleanup-status-files]
recipe = plone.recipe.command
command =
rm -f ${directory:var}/request-bang-done
rm -f ${directory:var}/server-is-ready
rm -f ${buildout:directory}/.${slap-connection:partition-id}-request-update-route
update-command =
#############################
#
# Instance sync directories configuration (descript what should be synced
#
#############################
[sync-parameter-dict]
sources-info =
${directory:public}/*
${directory:etc}
destination-info = srv/sync-data/
excludes-info =
cluster.hash
sources-hard-drive = ${directory:srv}/virtual.qcow2
destination-hard-drive = srv/virtual.qcow2
excludes-hard-drive =
folder-section-list =
hard-drive
info
{% if disk_number > 0 and int(slapparameter_dict.get('external-disk-number', 0)) > 0 -%}
{{ ' '}}extra-storage
sources-extra-storage =
${buildout:directory}/DATA/*
destination-extra-storage = srv/sync-data/data/
excludes-extra-storage =
ignore-missing-extra-storage = true
follow-symlink-extra-storage = true
{% endif -%}
[slap-parameter]
# Default values if not specified
......@@ -563,7 +605,7 @@ cpu-options =
# list of numa options separate by space: node,nodeid=1,cpus=9-15 node,nodeid=2,cpus=1,3,7
numa =
disk-cache = writeback
disk-aio = native
disk-aio = threads
auto-ballooning = True
machine-options =
cpu-model =
......@@ -627,6 +669,8 @@ keyboard-layout-language = fr
[buildout]
parts =
certificate-authority
authenticated-httpd-server
instance-sshd
publish-connection-information
kvm-instance
kvm-contoller
......@@ -637,6 +681,7 @@ parts =
kvm-started-promise
cron
cron-entry-logrotate
cron-entry-instance-sync-server
frontend-promise
{% if monitor -%}
# monitor parts
......
......@@ -16,6 +16,8 @@ frontend = ${template-frontend:output}
kvm-resilient = $${dynamic-template-kvm-resilient:rendered}
kvm-import = $${dynamic-template-kvm-import:rendered}
kvm-export = $${dynamic-template-kvm-export:rendered}
kvm-clone = $${dynamic-template-kvm-clone:rendered}
kvm-moved = $${dynamic-template-kvm-moved:rendered}
# Used for the test of resiliency. The system wants a "test" software_type.
test = $${dynamic-template-kvm-resilient-test:rendered}
......@@ -46,16 +48,22 @@ extensions = jinja2.ext.do
mode = 0644
extra-context =
context =
key computer_id slap-configuration:computer
key develop_eggs_directory buildout:develop-eggs-directory
key eggs_directory buildout:eggs-directory
key ipv4 slap-configuration:ipv4
key ipv6 slap-configuration:ipv6
key instance_name slap-configuration:instance-title
key global_ipv4_prefix network-information:global-ipv4-network
key tap_network_dict slap-configuration:tap-network-information-dict
key storage_dict slap-configuration:storage-dict
key slapparameter_dict slap-configuration:configuration
key computer_id slap-configuration:computer
raw logrotate_cfg ${template-logrotate-base:rendered}
raw openssl_executable_location ${openssl:location}/bin/openssl
raw template_certificate_authority ${template-certificate-authority:rendered}
raw template_content ${template-content:location}/${template-content:filename}
raw template_httpd_cfg ${template-httpd:rendered}
raw template_monitor ${monitor2-template:rendered}
$${:extra-context}
[dynamic-template-kvm-cluster-parameters]
......@@ -65,44 +73,37 @@ context =
template = ${template-kvm-cluster:location}/instance-kvm-cluster.cfg.jinja2.in
filename = template-kvm-cluster.cfg
extra-context =
key instance_guid slap-configuration:instance-guid
key slave_instance_list slap-configuration:slave-instance-list
raw template_certificate_sign_bash ${template-certificate-sign-bash:location}/${template-certificate-sign-bash:filename}
raw certificate_authority_sign_bin ${buildout:directory}/bin/ca-sign
section parameter_dict dynamic-template-kvm-cluster-parameters
raw logrotate_cfg ${template-logrotate-base:rendered}
raw template_content ${template-content:location}/${template-content:filename}
raw template_httpd_cfg ${template-httpd:rendered}
raw template_monitor ${monitor2-template:rendered}
[dynamic-template-kvm]
recipe = slapos.recipe.template:jinja2
<= jinja2-template-base
template = ${template-kvm:location}/instance-kvm.cfg.jinja2
rendered = $${buildout:directory}/template-kvm.cfg
extensions = jinja2.ext.do
context =
key develop_eggs_directory buildout:develop-eggs-directory
key eggs_directory buildout:eggs-directory
key global_ipv4_prefix network-information:global-ipv4-network
key slapparameter_dict slap-configuration:configuration
key storage_dict slap-configuration:storage-dict
key tap_network_dict slap-configuration:tap-network-information-dict
extra-context =
raw ansible_promise_tpl ${template-ansible-promise:location}/${template-ansible-promise:filename}
raw curl_executable_location ${curl:location}/bin/curl
raw dash_executable_location ${dash:location}/bin/dash
raw dcron_executable_location ${dcron:location}/sbin/crond
raw debian_amd64_netinst_location ${debian-amd64-netinst.iso:location}/${debian-amd64-netinst.iso:filename}
raw file_download_script ${file-download-script:location}/${file-download-script:filename}
raw logrotate_cfg ${template-logrotate-base:rendered}
raw novnc_location ${noVNC:location}
raw netcat_bin ${netcat:location}/bin/netcat
raw openssl_executable_location ${openssl:location}/bin/openssl
raw python_executable ${buildout:executable}
raw python_executable ${buildout:bin-directory}/${eggs:interpreter}
raw qemu_executable_location ${kvm:location}/bin/qemu-system-x86_64
raw qemu_img_executable_location ${kvm:location}/bin/qemu-img
raw qemu_start_promise_tpl ${template-qemu-ready:location}/${template-qemu-ready:filename}
raw sixtunnel_executable_location ${6tunnel:location}/bin/6tunnel
raw template_httpd_cfg ${template-httpd:rendered}
raw template_content ${template-content:location}/${template-content:filename}
raw template_auth_httpd_server ${template-authenticated-server:rendered}
raw template_bang_script ${template-python-bang:location}/${template-python-bang:filename}
raw template_kvm_controller_run ${template-kvm-controller:location}/${template-kvm-controller:filename}
raw template_kvm_run ${template-kvm-run:location}/${template-kvm-run:filename}
raw template_monitor ${monitor2-template:rendered}
raw template_before_clone_script ${template-before-clone-script:location}/${template-before-clone-script:filename}
raw template_instance_sshd ${template-instance-sshd:rendered}
raw template_server_sync ${template-server-sync:rendered}
raw websockify_executable_location ${buildout:directory}/bin/websockify
template-parts-destination = ${template-parts:destination}
template-replicated-destination = ${template-replicated:destination}
......@@ -158,6 +159,31 @@ context =
raw gzip_binary ${gzip:location}/bin/gzip
mode = 0644
[dynamic-template-kvm-clone]
recipe = slapos.recipe.template:jinja2
template = ${template-instance-clone:output}
rendered = $${buildout:directory}/template-instance-clone.cfg
extensions = jinja2.ext.do
context =
key develop_eggs_directory buildout:develop-eggs-directory
key eggs_directory buildout:eggs-directory
key slapparameter_dict slap-configuration:configuration
raw template_monitor ${monitor2-template:rendered}
mode = 0644
[dynamic-template-kvm-moved]
recipe = slapos.recipe.template:jinja2
template = ${template-kvm-moved:location}/instance-kvm-moved.cfg.jinja2
rendered = $${buildout:directory}/template-kvm-moved.cfg
extensions = jinja2.ext.do
context =
key develop_eggs_directory buildout:develop-eggs-directory
key eggs_directory buildout:eggs-directory
key instance_name slap-configuration:instance-title
raw kvm_template $${dynamic-template-kvm:rendered}
key slapparameter_dict slap-configuration:configuration
mode = 0644
[dynamic-template-kvm-resilient-test]
recipe = slapos.recipe.template:jinja2
template = ${template-kvm-resilient-test:location}/instance-kvm-resilient-test.cfg.jinja2
......
#!/bin/bash
CA_SIGN="{{ ca_sign_script }}"
CA_DIR="{{ ca_directory }}"
CA_URL="{{ ca_url }}"
CN_LIST="{{ ca_cn_list }}"
HOST="{{ client_host }}"
KEY_LIST=""
for cn in $CN_LIST; do
KEY=$($CA_SIGN --ca_dir $CA_DIR --list | grep $cn | cut -d '|' -f6 | xargs)
REAL_CN=$($CA_SIGN --ca_dir $CA_DIR --list | grep $cn | cut -d '|' -f2 | xargs)
if [ -n "$KEY" ] && [ "$REAL_CN" == "$cn" ]; then
KEY_LIST="$KEY_LIST --key $KEY"
fi
done
if [ -n "$KEY_LIST" ]; then
$CA_SIGN --ca_dir $CA_DIR --ca_url $CA_URL --sign --host $HOST $KEY_LIST
fi
\ No newline at end of file
#!/bin/sh
set -x
OUTPUT_FILE={{ output_file }}
BANG_SCRIPT={{ bang_script }}
PYTHON_BIN={{ python_bin }}
INSTANCE_GUID="{{ instance_guid }}"
MY_INSTANCE_NAME="{{ instance_name }}"
INSTANCE_REFERENCE="$MY_INSTANCE_NAME-hibernate"
SOFTWARE_TYPE="{{ software_type }}"
CLIENT_NAME=$2
CLIENT_ID=$1
if [ -s "$OUTPUT_FILE" ]; then
echo "Request bang already called. Exiting...";
exit 0;
fi
exec $PYTHON_BIN $BANG_SCRIPT --server_url {{ slapconnection_dict["server-url"] }} \
--key_file "{{ slapconnection_dict["key-file"] }}" \
--cert_file "{{ slapconnection_dict["cert-file"] }}" \
--software_type $SOFTWARE_TYPE \
--computer_guid {{ slapconnection_dict["computer-id"] }} \
--partition_id {{ slapconnection_dict["partition-id"] }} \
--software_release {{ slapconnection_dict["software-release-url"] }} \
--output $OUTPUT_FILE --partition_reference "$INSTANCE_REFERENCE" \
--instance_guid $INSTANCE_GUID --message "Instance is going to be cloned" \
--parameter client="$CLIENT_NAME" --parameter software-type=kvm-moved \
--parameter source="$MY_INSTANCE_NAME" --return "instance-source" \
--return "software-type"
#!{{ parameter_dict.get('python-path') }}
# -*- coding: utf-8 -*-
# BEWARE: This file is operated by slapgrid
# BEWARE: It will be overwritten automatically
......@@ -73,12 +74,40 @@ machine_options = '{{ parameter_dict.get("machine-options", "") }}'.strip()
cpu_model = '{{ parameter_dict.get("cpu-model", "") }}'.strip()
logfile = '{{ parameter_dict.get("log-file") }}'
sync_data = '{{ parameter_dict.get("sync-data") }}'
if hasattr(ssl, '_create_unverified_context') and url_check_certificate == 'false':
opener = urllib.FancyURLopener(context=ssl._create_unverified_context())
else:
opener = urllib.FancyURLopener({})
def applySyncedData(disk_storage_dict):
if not os.path.exists(sync_data):
return
map_disk_file = os.path.join(sync_data, 'etc', '.data-disk-ids')
data_folder = os.path.join(sync_data, 'data')
if os.path.exists(map_disk_file):
map_disk_destination = os.path.join(etc_directory, '.data-disk-ids')
os.rename(map_disk_file, map_disk_destination)
if os.path.exists(data_folder):
for storage in os.listdir(data_folder):
if disk_storage_dict.has_key(storage):
storage_path = os.path.join(data_folder, storage)
for elt in os.listdir(storage_path):
destination = os.path.join(disk_storage_dict[storage], elt)
if os.path.isdir(destination):
if os.path.exists(destination):
shutil.rmtree(destination)
shutil.copytree(os.path.join(storage_path, elt), destination)
else:
if os.path.exists(destination):
os.remove(destination)
shutil.copy(os.path.join(storage_path, elt), destination)
# safely delete source data
os.rename(storage_path, '%s.back' % storage_path)
shutil.rmtree('%s.back' % storage_path)
def md5Checksum(file_path):
with open(file_path, 'rb') as fh:
m = hashlib.md5()
......@@ -193,6 +222,7 @@ for storage in disk_storage_list:
key, val = storage.split(' ')
disk_storage_dict[key.strip()] = val.strip()
applySyncedData(disk_storage_dict)
if not external_disk_format in ['qcow2', 'raw', 'vdi', 'vmdk', 'cloop', 'qed']:
external_disk_format = 'qcow2'
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment