Commit d4fffe49 authored by Christos Stavrakakis's avatar Christos Stavrakakis
Browse files

Merge branch 'hotfix-0.15.2'

parents 6642904e eeaef5ae
......@@ -6,6 +6,27 @@ Unified Changelog file for Synnefo versions >= 0.13
Since v0.13 most of the Synnefo components have been merged into a single
repository and have aligned versions.
.. _Changelog-0.15.2:
v0.15.2
=======
Released: Tue May 27 13:50:31 EEST 2014
Cyclades
--------
* Fix minor problem in network stats plugin of collectd
* Fix small issue in the 'stats-cyclades' command arising when Ganeti cannot
communicate with a node.
* Check max size of server metadata
* Add support for Ganeti 2.10
Cyclades UI
-----------
* Fix oraclelinux icon name
.. _Changelog-0.15.1:
v0.15.1
......
......@@ -5,6 +5,14 @@ Unified NEWS file for Synnefo versions >= 0.13
Since v0.13 all Synnefo components have been merged into a single repository.
.. _NEWS-0.15.2:
v0.15.2
=======
Released: Tue May 27 13:50:31 EEST 2014
* Bug fix version
.. _NEWS-0.15.1:
......
......@@ -2560,6 +2560,7 @@ Changelog, NEWS
===============
* v0.15.2 :ref:`Changelog <Changelog-0.15.1>`, :ref:`NEWS <NEWS-0.15.2>`
* v0.15.1 :ref:`Changelog <Changelog-0.15.1>`, :ref:`NEWS <NEWS-0.15.1>`
* v0.15 :ref:`Changelog <Changelog-0.15>`, :ref:`NEWS <NEWS-0.15>`
* v0.14.10 :ref:`Changelog <Changelog-0.14.10>`, :ref:`NEWS <NEWS-0.14.10>`
......
......@@ -40,6 +40,9 @@ In case you choose to follow a private installation you will need to
set up a private dns server, using dnsmasq for example. See node1 below for
more information on how to do so.
You should also disable ``SELinux``, until you get familiar with the Synnefo
stack and its dependencies.
General Prerequisites
=====================
......@@ -127,8 +130,8 @@ Now run:
# service postgresql-9.3 initdb
# chkconfig postgresql-9.3 on
For more information on install postgresql on CentOS, please see `this
https://wiki.postgresql.org/wiki/YUM_Installation`_.
For more information on how to install postgresql on CentOS, please see `this
<https://wiki.postgresql.org/wiki/YUM_Installation>`_.
To install gunicorn and gevent, run:
......@@ -1380,6 +1383,11 @@ Let's briefly explain each patch set:
* Change IP pool to support NAT instances
* Change RAPI to accept depends body argument and shutdown_timeout
.. note::
At the moment of writing this, the qemu package provided by CentOS
is ``0.12.1.2``. To use hotplug capabilities, qemu >= 1.0 is required.
To install Ganeti run:
.. code-block:: console
......@@ -2255,7 +2263,7 @@ skipped.
.. code-block:: console
node1 # snf-manage quota --sync
node1 # snf-manage quota-verify --sync
node1 # snf-manage reconcile-resources-astakos --fix
node2 # snf-manage reconcile-resources-pithos --fix
node1 # snf-manage reconcile-resources-cyclades --fix
......
......@@ -2291,7 +2291,7 @@ skipped.
.. code-block:: console
node1 # snf-manage quota --sync
node1 # snf-manage quota-verify --sync
node1 # snf-manage reconcile-resources-astakos --fix
node2 # snf-manage reconcile-resources-pithos --fix
node1 # snf-manage reconcile-resources-cyclades --fix
......
......@@ -83,7 +83,9 @@ class Command(ListCommand):
action='append',
dest='groups',
default=None,
help="Only show users that belong to the specified goups"),
metavar="GROUP",
help="Only show users that belong to the specified"
" group. Can be used multiple times."),
make_option('--active',
action='store_true',
dest='active',
......@@ -117,6 +119,9 @@ class Command(ListCommand):
if options['pending_verification']:
self.filters['email_verified'] = False
if options['groups']:
self.filters['groups__name__in'] = options['groups']
if options['auth_providers']:
self.fields.extend(['providers'])
......
......@@ -88,7 +88,7 @@ def _get_cluster_stats(bend):
"offline": node["offline"],
"vm_capable": node["vm_capable"],
"instances": node["pinst_cnt"],
"cpu": node["ctotal"],
"cpu": (node["ctotal"] or 0),
"ram": {
"total": (node["mtotal"] or 0) << 20,
"free": (node["mfree"] or 0) << 20
......
......@@ -63,7 +63,8 @@ def demux(request):
elif request.method == 'POST':
return create_port(request)
else:
return api.api_method_not_allowed(request)
return api.api_method_not_allowed(request, allowed_methods=['GET',
'POST'])
def port_demux(request, port_id):
......@@ -75,7 +76,9 @@ def port_demux(request, port_id):
elif request.method == 'PUT':
return update_port(request, port_id)
else:
return api.api_method_not_allowed(request)
return api.api_method_not_allowed(request, allowed_methods=['GET',
'DELETE',
'PUT'])
@api.api_method(http_method='GET', user_required=True, logger=log)
......
......@@ -62,7 +62,8 @@ def demux(request):
elif request.method == 'POST':
return create_subnet(request)
else:
return api.api_method_not_allowed(request)
return api.api_method_not_allowed(request, allowed_methods=['GET',
'POST'])
def subnet_demux(request, sub_id):
......@@ -73,7 +74,9 @@ def subnet_demux(request, sub_id):
elif request.method == 'PUT':
return update_subnet(request, sub_id)
else:
return api.api_method_not_allowed(request)
return api.api_method_not_allowed(request, allowed_methods=['GET',
'DELETE',
'PUT'])
@api.api_method(http_method='GET', user_required=True, logger=log)
......
......@@ -408,8 +408,10 @@ class VirtualMachine(models.Model):
class VirtualMachineMetadata(models.Model):
meta_key = models.CharField(max_length=50)
meta_value = models.CharField(max_length=500)
KEY_LENGTH = 50
VALUE_LENGTH = 500
meta_key = models.CharField(max_length=KEY_LENGTH)
meta_value = models.CharField(max_length=VALUE_LENGTH)
vm = models.ForeignKey(VirtualMachine, related_name='metadata',
on_delete=models.CASCADE)
......
......@@ -251,7 +251,6 @@ def pprint_clusters(clusters, stdout, detail=True):
"CPUs", "RAM (used/total)", "Disk (used/total)")
pprint_table(stdout, node_table, headers, separator=" | ",
title="Statistics per node for backend %s" % cluster_name)
stdout.write("\n")
total_table = (
("Backend", t_backend_cnt),
......@@ -280,8 +279,11 @@ def pprint_clusters(clusters, stdout, detail=True):
("V/P total disk", ("%.2f%%" % (100 * t_vdisk / t_dtotal)
if t_dtotal != 0 else "-")),
)
pprint_table(stdout, total_table, headers=None, separator=" | ",
title="Statistics for all backends")
if len(clusters) > 1:
stdout.write("\n")
pprint_table(stdout, total_table, headers=None, separator=" | ",
title="Statistics for all backends")
def pprint_servers(servers, stdout):
......
......@@ -205,6 +205,10 @@ def create(userid, name, password, flavor, image, metadata={},
port.save()
for key, val in metadata.items():
utils.check_name_length(key, VirtualMachineMetadata.KEY_LENGTH,
"Metadata key is too long")
utils.check_name_length(val, VirtualMachineMetadata.VALUE_LENGTH,
"Metadata value is too long")
VirtualMachineMetadata.objects.create(
meta_key=key,
meta_value=val,
......
......@@ -6,27 +6,27 @@ import collectd
from glob import glob
def read_int(file):
f = open(file, "r")
try:
val = int(f.read())
except ValueError:
val = None
finally:
f.close()
def read_int(filename):
with open(filename, "r") as f:
try:
val = int(f.read())
except ValueError:
val = None
return val
def netstats(data=None):
for dir in glob("/var/run/ganeti/kvm-hypervisor/nic/*"):
if not os.path.isdir(dir):
for dirname in glob("/var/run/ganeti/kvm-hypervisor/nic/*"):
if not os.path.isdir(dirname):
continue
hostname = os.path.basename(dir)
hostname = os.path.basename(dirname)
for nic in glob(os.path.join(dir, "*")):
idx = int(os.path.basename(nic))
for nic in glob(os.path.join(dirname, "*")):
try:
idx = int(os.path.basename(nic))
except ValueError:
continue
with open(nic) as nicfile:
try:
iface = nicfile.readline().strip()
......
......@@ -41,6 +41,9 @@ A daemon to monitor the Ganeti job queue and publish job progress
and Ganeti VM state notifications to the ganeti exchange
"""
OLD_GANETI_PATH = "/usr/share/ganeti"
NEW_GANETI_PATH = "/etc/ganeti/share"
import sys
import os
path = os.path.normpath(os.path.join(os.getcwd(), '..'))
......@@ -49,7 +52,22 @@ sys.path.append(path)
# a private module under '/usr/share/ganeti'. Add this directory to path
# in order to be able to import ganeti. Also, add it to the start of path
# to allow conflicts with Ganeti RAPI client.
sys.path.insert(0, "/usr/share/ganeti")
# Since Ganeti 2.10 the python module is installed (linked) under
# /etc/ganeti/share
# Favor latest ganeti if found
if os.path.exists(NEW_GANETI_PATH):
GANETI_PATH = NEW_GANETI_PATH
else:
GANETI_PATH = OLD_GANETI_PATH
sys.path.insert(0, GANETI_PATH)
try:
import ganeti
except ImportError:
raise Exception("Cannot import ganeti module. Please check if installed"
" under %s for 2.8 or under %s for 2.10 or later." %
(OLD_GANETI_PATH, NEW_GANETI_PATH))
import json
import logging
......
......@@ -56,7 +56,9 @@ def public_demux(request, v_public):
elif request.method == 'GET':
return public_read(request, v_public)
else:
return api.api_method_not_allowed(request)
return api.api_method_not_allowed(request,
allowed_methods=['HEAD',
'GET'])
@api_method(http_method="HEAD", token_required=False, user_required=False,
......
......@@ -74,6 +74,26 @@ class TestPublic(PithosAPITest):
p = re.compile('(attachment|inline); filename="(.+)"')
r = self.delete(public)
self.assertEqual(r.status_code, 405)
self.assertEqual(sorted(r['Allow'].split(',')), ['GET', 'HEAD'])
r = self.post(public)
self.assertEqual(r.status_code, 405)
self.assertEqual(sorted(r['Allow'].split(',')), ['GET', 'HEAD'])
r = self.put(public)
self.assertEqual(r.status_code, 405)
self.assertEqual(sorted(r['Allow'].split(',')), ['GET', 'HEAD'])
r = self.copy(public)
self.assertEqual(r.status_code, 405)
self.assertEqual(sorted(r['Allow'].split(',')), ['GET', 'HEAD'])
r = self.move(public)
self.assertEqual(r.status_code, 405)
self.assertEqual(sorted(r['Allow'].split(',')), ['GET', 'HEAD'])
r = self.get(public, user='user2', token=None)
self.assertEqual(r.status_code, 200)
self.assertTrue('X-Object-Public' not in r)
......
......@@ -252,7 +252,10 @@ available_graph_types = {'cpu-bar': draw_cpu_bar,
@api_method(http_method='GET', token_required=False, user_required=False,
format_allowed=False, logger=log)
def grapher(request, graph_type, hostname):
hostname = decrypt(uenc(hostname))
try:
hostname = decrypt(uenc(hostname))
except (ValueError, TypeError):
raise faults.BadRequest("Invalid encrypted virtual server name")
fname = uenc(os.path.join(settings.RRD_PREFIX, hostname))
if not os.path.isdir(fname):
raise faults.ItemNotFound('No such instance')
......
# This is a comment!
0.15.1
0.15.2
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