diff --git a/Changelog b/Changelog
index 6c48e4b5..e76db610 100644
--- a/Changelog
+++ b/Changelog
@@ -1,6 +1,17 @@
+Next:
+ * bugfix: [CMS templates] Set description meta field of ungleich template (was missing before) and set ungleich glarus ag uniformly as author of various CMS pages (PR #653)
+ * #5473: Ping a VM before saving ssh key of the user (PR #655)
+2.1: 2018-08-21
+ * Bugfix: Increase CC brand name fields from 10 to 128 characters (PR #654)
+2.0.5: 2018-08-08
+ * Fix IPv6 VM name in the billing invoice
+2.0.4: 2018-08-07
+ * Add RSS feed link to the footer of the blog template (PR #651)
+ * #5308: [ipv6only] Fix - when creating a VM, the name begins with v6only (PR #649)
+ * #5293: Use `terminate-hard` action instead of `terminate` in the opennebula call to terminate a vm (PR #650)
2.0.3: 2018-07-18
* Remove unused /comic url (PR #644)
- * 5126: Allow dynamicweb sites to be iframed on other by setting `X_FRAME_OPTIONS_ALLOW_FROM_URI` (PR #645)
+ * #5126: Allow dynamicweb sites to be iframed on other by setting `X_FRAME_OPTIONS_ALLOW_FROM_URI` (PR #645)
2.0.2: 2018-07-14
* bugfix: [blog] Add missing content block in the blog_ungleich.html template file
2.0.1: 2018-07-14
diff --git a/datacenterlight/tasks.py b/datacenterlight/tasks.py
index 281d5f45..2779f79b 100644
--- a/datacenterlight/tasks.py
+++ b/datacenterlight/tasks.py
@@ -8,13 +8,16 @@ from django.core.mail import EmailMessage
from django.core.urlresolvers import reverse
from django.utils import translation
from django.utils.translation import ugettext_lazy as _
+from time import sleep
from dynamicweb.celery import app
from hosting.models import HostingOrder
from membership.models import CustomUser
from opennebula_api.models import OpenNebulaManager
from opennebula_api.serializers import VirtualMachineSerializer
-from utils.hosting_utils import get_all_public_keys, get_or_create_vm_detail
+from utils.hosting_utils import (
+ get_all_public_keys, get_or_create_vm_detail, ping_ok
+)
from utils.mailer import BaseEmail
from utils.stripe_utils import StripeUtils
from .models import VMPricing
@@ -203,12 +206,45 @@ def create_vm_task(self, vm_template_id, user, specs, template, order_id):
host=vm_ipv6, num_keys=len(keys)
)
)
- # Let's delay the task by 75 seconds to be sure
- # that we run the cdist configure after the host
- # is up
- manager.manage_public_key(
- keys, hosts=[vm_ipv6], countdown=75
- )
+ # Let's wait until the IP responds to ping before we
+ # run the cdist configure on the host
+ did_manage_public_key = False
+ for i in range(0, 15):
+ if ping_ok(vm_ipv6):
+ logger.debug(
+ "{} is pingable. Doing a "
+ "manage_public_key".format(vm_ipv6)
+ )
+ sleep(10)
+ manager.manage_public_key(
+ keys, hosts=[vm_ipv6]
+ )
+ did_manage_public_key = True
+ break
+ else:
+ logger.debug(
+ "Can't ping {}. Wait 5 secs".format(
+ vm_ipv6
+ )
+ )
+ sleep(5)
+ if not did_manage_public_key:
+ emsg = ("Waited for over 75 seconds for {} to be "
+ "pingable. But the VM was not reachable. "
+ "So, gave up manage_public_key. Please do "
+ "this manually".format(vm_ipv6))
+ logger.error(emsg)
+ email_data = {
+ 'subject': '{} CELERY TASK INCOMPLETE: {} not '
+ 'pingable for 75 seconds'.format(
+ settings.DCL_TEXT, vm_ipv6
+ ),
+ 'from_email': current_task.request.hostname,
+ 'to': settings.DCL_ERROR_EMAILS_TO_LIST,
+ 'body': emsg
+ }
+ email = EmailMessage(**email_data)
+ email.send()
except Exception as e:
logger.error(str(e))
try:
diff --git a/datacenterlight/templates/datacenterlight/cms/base.html b/datacenterlight/templates/datacenterlight/cms/base.html
index c155a55d..5e55ced1 100644
--- a/datacenterlight/templates/datacenterlight/cms/base.html
+++ b/datacenterlight/templates/datacenterlight/cms/base.html
@@ -8,8 +8,8 @@
-
+
{% page_attribute "page_title" %}
diff --git a/datacenterlight/utils.py b/datacenterlight/utils.py
index 1c54148e..8da408a0 100644
--- a/datacenterlight/utils.py
+++ b/datacenterlight/utils.py
@@ -1,3 +1,4 @@
+import logging
from django.contrib.sites.models import Site
from datacenterlight.tasks import create_vm_task
@@ -8,6 +9,8 @@ from utils.models import BillingAddress
from .cms_models import CMSIntegration
from .models import VMPricing, VMTemplate
+logger = logging.getLogger(__name__)
+
def get_cms_integration(name):
current_site = Site.objects.get_current()
diff --git a/dynamicweb/settings/base.py b/dynamicweb/settings/base.py
index 5a1cd2e4..00a74354 100644
--- a/dynamicweb/settings/base.py
+++ b/dynamicweb/settings/base.py
@@ -179,9 +179,7 @@ ROOT_URLCONF = 'dynamicweb.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
- 'DIRS': [os.path.join(PROJECT_DIR, 'cms_templates/'),
- os.path.join(PROJECT_DIR, 'cms_templates/djangocms_blog/'),
- os.path.join(PROJECT_DIR, 'membership'),
+ 'DIRS': [os.path.join(PROJECT_DIR, 'membership'),
os.path.join(PROJECT_DIR, 'hosting/templates/'),
os.path.join(PROJECT_DIR, 'nosystemd/templates/'),
os.path.join(PROJECT_DIR,
@@ -192,6 +190,8 @@ TEMPLATES = [
os.path.join(PROJECT_DIR,
'ungleich_page/templates/ungleich_page'),
os.path.join(PROJECT_DIR, 'templates/analytics'),
+ os.path.join(PROJECT_DIR, 'cms_templates/'),
+ os.path.join(PROJECT_DIR, 'cms_templates/djangocms_blog/'),
os.path.join(PROJECT_DIR, 'templates/gdpr'),
],
'APP_DIRS': True,
diff --git a/hosting/migrations/0047_auto_20180821_1240.py b/hosting/migrations/0047_auto_20180821_1240.py
new file mode 100644
index 00000000..7976c58d
--- /dev/null
+++ b/hosting/migrations/0047_auto_20180821_1240.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.4 on 2018-08-21 12:40
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('hosting', '0046_usercarddetail'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='hostingorder',
+ name='cc_brand',
+ field=models.CharField(max_length=128),
+ ),
+ migrations.AlterField(
+ model_name='usercarddetail',
+ name='brand',
+ field=models.CharField(max_length=128),
+ ),
+ ]
diff --git a/hosting/models.py b/hosting/models.py
index 3ae3b0a5..e9fcdc7e 100644
--- a/hosting/models.py
+++ b/hosting/models.py
@@ -69,7 +69,7 @@ class HostingOrder(AssignPermissionsMixin, models.Model):
created_at = models.DateTimeField(auto_now_add=True)
approved = models.BooleanField(default=False)
last4 = models.CharField(max_length=4)
- cc_brand = models.CharField(max_length=10)
+ cc_brand = models.CharField(max_length=128)
stripe_charge_id = models.CharField(max_length=100, null=True)
price = models.FloatField()
subscription_id = models.CharField(max_length=100, null=True)
@@ -212,7 +212,7 @@ class UserCardDetail(AssignPermissionsMixin, models.Model):
permissions = ('view_usercarddetail',)
stripe_customer = models.ForeignKey(StripeCustomer)
last4 = models.CharField(max_length=4)
- brand = models.CharField(max_length=10)
+ brand = models.CharField(max_length=128)
card_id = models.CharField(max_length=100, blank=True, default='')
fingerprint = models.CharField(max_length=100)
exp_month = models.IntegerField(null=False)
diff --git a/hosting/templates/hosting/base.html b/hosting/templates/hosting/base.html
index aca42e0f..681a9c8b 100644
--- a/hosting/templates/hosting/base.html
+++ b/hosting/templates/hosting/base.html
@@ -9,7 +9,7 @@
-
+
{{ domain }} - {{ hosting }} hosting as easy as possible
diff --git a/opennebula_api/models.py b/opennebula_api/models.py
index 29632009..3682c5da 100644
--- a/opennebula_api/models.py
+++ b/opennebula_api/models.py
@@ -315,7 +315,7 @@ class OpenNebulaManager():
return vm_id
def delete_vm(self, vm_id):
- TERMINATE_ACTION = 'terminate'
+ TERMINATE_ACTION = 'terminate-hard'
vm_terminated = False
try:
self.oneadmin_client.call(
diff --git a/opennebula_api/serializers.py b/opennebula_api/serializers.py
index 79f37ecd..c7418aa5 100644
--- a/opennebula_api/serializers.py
+++ b/opennebula_api/serializers.py
@@ -36,7 +36,10 @@ class VirtualMachineTemplateSerializer(serializers.Serializer):
return int(obj.template.memory) / 1024
def get_name(self, obj):
- return obj.name.lstrip('public-')
+ if obj.name.startswith('public-'):
+ return obj.name.lstrip('public-')
+ else:
+ return obj.name
class VirtualMachineSerializer(serializers.Serializer):
@@ -133,7 +136,10 @@ class VirtualMachineSerializer(serializers.Serializer):
def get_configuration(self, obj):
template_id = obj.template.template_id
template = OpenNebulaManager().get_template(template_id)
- return template.name.lstrip('public-')
+ if template.name.startswith('public-'):
+ return template.name.lstrip('public-')
+ else:
+ return template.name
def get_ipv4(self, obj):
"""
@@ -162,7 +168,10 @@ class VirtualMachineSerializer(serializers.Serializer):
return '-'
def get_name(self, obj):
- return obj.name.lstrip('public-')
+ if obj.name.startswith('public-'):
+ return obj.name.lstrip('public-')
+ else:
+ return obj.name
class VMTemplateSerializer(serializers.Serializer):
diff --git a/ungleich/templates/cms/ungleichch/_footer.html b/ungleich/templates/cms/ungleichch/_footer.html
index 81194f69..94832ed4 100644
--- a/ungleich/templates/cms/ungleichch/_footer.html
+++ b/ungleich/templates/cms/ungleichch/_footer.html
@@ -30,6 +30,14 @@
+
+
+
+
+
+
+
+
Copyright © ungleich GmbH {% now "Y" %}
diff --git a/ungleich_page/templates/ungleich_page/glasfaser_cms_page.html b/ungleich_page/templates/ungleich_page/glasfaser_cms_page.html
index e13cf7bf..57d266ce 100644
--- a/ungleich_page/templates/ungleich_page/glasfaser_cms_page.html
+++ b/ungleich_page/templates/ungleich_page/glasfaser_cms_page.html
@@ -7,7 +7,7 @@
-
+
{% page_attribute "page_title" %}
diff --git a/ungleich_page/templates/ungleich_page/ungleich_cms_page.html b/ungleich_page/templates/ungleich_page/ungleich_cms_page.html
index 2267d266..f58b6f40 100644
--- a/ungleich_page/templates/ungleich_page/ungleich_cms_page.html
+++ b/ungleich_page/templates/ungleich_page/ungleich_cms_page.html
@@ -7,8 +7,9 @@
-
-
+
+
+
{% page_attribute "page_title" %}
diff --git a/utils/hosting_utils.py b/utils/hosting_utils.py
index c0494b90..1859a82c 100644
--- a/utils/hosting_utils.py
+++ b/utils/hosting_utils.py
@@ -1,5 +1,6 @@
import decimal
import logging
+import subprocess
from oca.pool import WrongIdError
from datacenterlight.models import VMPricing
@@ -130,6 +131,23 @@ def get_vm_price_with_vat(cpu, memory, ssd_size, hdd_size=0,
return float(price), float(vat), float(vat_percent), discount
+def ping_ok(host_ipv6):
+ """
+ A utility method to check if a host responds to ping requests. Note: the
+ function relies on `ping6` utility of debian to check.
+
+ :param host_ipv6 str type parameter that represets the ipv6 of the host to
+ checked
+ :return True if the host responds to ping else returns False
+ """
+ try:
+ subprocess.check_output("ping6 -c 1 " + host_ipv6, shell=True)
+ except Exception as ex:
+ logger.debug(host_ipv6 + " not reachable via ping. Error = " + str(ex))
+ return False
+ return True
+
+
class HostingUtils:
@staticmethod
def clear_items_from_list(from_list, items_list):