Merge branch 'master' of https://github.com/open-cloud/xos
diff --git a/xos/configurations/cord/cord.yaml b/xos/configurations/cord/cord.yaml
index 9d850b2..c66f7bc 100644
--- a/xos/configurations/cord/cord.yaml
+++ b/xos/configurations/cord/cord.yaml
@@ -40,7 +40,7 @@
# generate a URL from its IP address
# vbng_url: http://10.11.10.24:8181/onos/virtualbng/
- service_ONOS:
+ service_ONOS_vBNG:
type: tosca.nodes.ONOSService
requirements:
properties:
@@ -54,30 +54,33 @@
type: tosca.nodes.ONOSvBNGApp
requirements:
- onos_tenant:
- node: service_ONOS
+ node: service_ONOS_vBNG
relationship: tosca.relationships.TenantOfService
- vbng_service:
node: service_vbng
relationship: tosca.relationships.UsedByService
properties:
dependencies: org.onosproject.proxyarp, org.onosproject.virtualbng, org.onosproject.openflow, org.onosproject.fwd
- config_addresses.json: >
+ config_network-cfg.json: >
{
- "addresses" : [
- {
- "dpid" : "00:00:00:00:00:00:00:a1",
- "port" : "1",
- "ips" : [10.0.1.253/24"],
- "mac" : "00:00:00:00:00:99"
-
- },
- {
- "dpid" : "00:00:00:00:00:00:00:a5",
- "port" : "2",
- "ips" : ["10.254.0.1/24"],
- "mac" : "00:00:00:00:00:98"
- }
- ]
+ "ports" : {
+ "of:00000000000000a1/1" : {
+ "interfaces" : [
+ {
+ "ips" : [ "10.0.1.253/24" ],
+ "mac" : "00:00:00:00:00:99"
+ }
+ ]
+ },
+ "of:00000000000000a5/2" : {
+ "interfaces" : [
+ {
+ "ips" : [ "10.254.0.1/24" ],
+ "mac" : "00:00:00:00:00:98"
+ }
+ ]
+ }
+ }
}
config_virtualbng.json: >
{
@@ -90,6 +93,27 @@
"xosRestPort" : "9999"
}
+ service_ONOS_vOLT:
+ type: tosca.nodes.ONOSService
+ requirements:
+ properties:
+ kind: onos
+ view_url: /admin/onos/onosservice/$id$/
+ public_key: { get_artifact: [ SELF, pubkey, LOCAL_FILE] }
+ artifacts:
+ pubkey: /opt/xos/observers/onos/onos_key.pub
+
+ vOLT_ONOS_app:
+ type: tosca.nodes.ONOSvOLTApp
+ requirements:
+ - onos_tenant:
+ node: service_ONOS_vOLT
+ relationship: tosca.relationships.TenantOfService
+ - volt_service:
+ node: service_volt
+ relationship: tosca.relationships.UsedByService
+ properties:
+ dependencies: org.onosproject.olt
# Network templates
Private:
@@ -189,12 +213,23 @@
node: mysite
relationship: tosca.relationships.MemberOfSite
- mysite_onos:
- description: ONOS Controller Slice
+ mysite_onos_vbng:
+ description: ONOS Controller Slice for vBNG
type: tosca.nodes.Slice
requirements:
- ONOS:
- node: service_ONOS
+ node: service_ONOS_vBNG
+ relationship: tosca.relationships.MemberOfService
+ - site:
+ node: mysite
+ relationship: tosca.relationships.MemberOfSite
+
+ mysite_onos_volt:
+ description: ONOS Controller Slice for vOLT
+ type: tosca.nodes.Slice
+ requirements:
+ - ONOS:
+ node: service_ONOS_vOLT
relationship: tosca.relationships.MemberOfService
- site:
node: mysite
@@ -217,7 +252,7 @@
relationship: tosca.relationships.MemberOfSite
mysite_clients:
- description: slice for clients at the subscriber
+ description: slice for clients at the subscriber
type: tosca.nodes.Slice
requirements:
- site:
@@ -245,7 +280,7 @@
version: 14.10
requirements:
- slice:
- node: mysite_onos
+ node: mysite_onos_vbng
relationship: tosca.relationships.MemberOfSlice
onos_app_2:
@@ -267,7 +302,7 @@
version: 14.10
requirements:
- slice:
- node: mysite_onos
+ node: mysite_onos_volt
relationship: tosca.relationships.MemberOfSlice
# VM for running the OVS controlled by vBNG
diff --git a/xos/configurations/opencloud/Dockerfile b/xos/configurations/opencloud/Dockerfile
index 5b09507..5a4db61 100644
--- a/xos/configurations/opencloud/Dockerfile
+++ b/xos/configurations/opencloud/Dockerfile
@@ -3,7 +3,6 @@
# Set environment variables.
ENV HOME /root
-ENV TOSCA_CONFIG_PATH=/opt/xos/configurations/opencloud/opencloud.tosca
# XXX Workaround for docker bug:
# https://github.com/docker/docker/issues/6345
@@ -14,23 +13,20 @@
# Install.
RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y \
+ curl \
git \
- postgresql \
+ geoip-database \
graphviz \
graphviz-dev \
+ libgeoip1 \
libxslt1.1 \
libxslt1-dev \
- tar \
- gcc \
- geoip-database \
- libgeoip1 \
- openssh-client \
- wget \
- curl \
- python-dev \
libyaml-dev \
+ nginx \
+ openssh-client \
+ python-dev \
pkg-config \
- supervisor \
+ postgresql \
python-crypto \
python-httplib2>=0.9.1 \
python-jinja2 \
@@ -44,7 +40,10 @@
python-novaclient \
python-neutronclient \
python-glanceclient \
- python-ceilometerclient
+ python-ceilometerclient \
+ supervisor \
+ tar \
+ wget
RUN pip install \
django==1.7 \
@@ -67,7 +66,8 @@
django_rest_swagger \
python-keyczar \
pygraphviz \
- dnslib
+ dnslib \
+ uwsgi
RUN easy_install --upgrade httplib2
@@ -84,11 +84,15 @@
RUN git clone -b release1.8.2 git://github.com/ansible/ansible-modules-extras.git /opt/ansible/v2/ansible/modules/extras
RUN git clone git://github.com/sb98052/ansible-modules-core.git /opt/ansible/lib/ansible/modules/core
RUN git clone git://github.com/sb98052/ansible-modules-core.git /opt/ansible/v2/ansible/modules/core
+# git clone uses cached copy, doesn't pick up latest
+RUN git -C /opt/ansible pull
+RUN git -C /opt/ansible/lib/ansible/modules/core pull
+RUN git -C /opt/ansible/v2/ansible/modules/core pull
ADD ansible-hosts /etc/ansible/hosts
-ADD http://code.jquery.com/jquery-1.9.1.min.js /usr/local/lib/python2.7/dist-packages/suit/static/suit/js/
# For Observer
+ADD http://code.jquery.com/jquery-1.9.1.min.js /usr/local/lib/python2.7/dist-packages/suit/static/suit/js/
RUN git clone git://git.planet-lab.org/fofum.git /tmp/fofum
RUN cd /tmp/fofum; python setup.py install
RUN rm -rf /tmp/fofum
@@ -100,16 +104,11 @@
RUN ln -s /usr/local/share/phantomjs-1.7.0-linux-x86_64 /usr/local/share/phantomjs
RUN ln -s /usr/local/share/phantomjs/bin/phantomjs /bin/phantomjs
-# Supervisor
-ADD observer.conf /etc/supervisor/conf.d/
-
# Get XOS
RUN git clone git://github.com/open-cloud/xos.git /tmp/xos && mv /tmp/xos/xos /opt/
-# Initscript is broken in Ubuntu
-#ADD observer-initscript /etc/init.d/xosobserver
-
RUN chmod +x /opt/xos/scripts/opencloud
+
RUN /opt/xos/scripts/opencloud genkeys
# Workaround for AUFS issue
@@ -126,24 +125,19 @@
# Cruft to workaround problems with migrations, should go away...
RUN /opt/xos/scripts/opencloud remigrate
-# git clone uses cached copy, doesn't pick up latest
-RUN git -C /opt/ansible pull
-RUN git -C /opt/ansible/lib/ansible/modules/core pull
-RUN git -C /opt/ansible/v2/ansible/modules/core pull
# install Tosca engine
RUN apt-get install -y m4
RUN pip install python-dateutil
RUN bash /opt/xos/tosca/install_tosca.sh
+# configure nginx
+RUN cp /opt/xos/nginx/xos.conf /etc/nginx/sites-enabled/default
+
+# Supervisor configuration
+RUN cp /opt/xos/configurations/opencloud/supervisord.conf /etc/supervisor/conf.d/xos-all.conf
+
EXPOSE 8000
-# Set environment variables.
-ENV HOME /root
-
-# Define working directory.
-WORKDIR /root
-
# Define default command.
-#CMD ["/bin/bash"]
-CMD /opt/xos/scripts/docker_start_xos
+CMD /usr/bin/supervisord -c /etc/supervisor/conf.d/xos-all.conf
diff --git a/xos/configurations/opencloud/Makefile b/xos/configurations/opencloud/Makefile
index 863f2b7..ab88aea 100644
--- a/xos/configurations/opencloud/Makefile
+++ b/xos/configurations/opencloud/Makefile
@@ -1,16 +1,16 @@
-RUNNING_CONTAINER:=$(shell sudo docker ps|grep "opencloud_server"|awk '{print $$NF}')
+RUNNING_CONTAINER:=$(shell sudo docker ps|grep "opencloud-server"|awk '{print $$NF}')
.PHONY: build
build: ; docker build --rm -t opencloud .
.PHONY: run
-run: ; docker run --rm --name opencloud_server opencloud
+run: ; docker run --rm --name opencloud-server opencloud
.PHONY: runtosca
runtosca: ; docker exec -it $RUNNING_CONTAINER /usr/bin/python /opt/xos/tosca/run.py padmin@vicci.org $TOSCA_CONFIG_PATH
.PHONY: stop
-stop: ; docker stop opencloud_server
+stop: ; docker stop opencloud-server
.PHONY: rmcontainer
-rmcontainer: ; docker rm opencloud_server
+rmcontainer: ; docker rm opencloud-server
diff --git a/xos/configurations/opencloud/supervisord.conf b/xos/configurations/opencloud/supervisord.conf
new file mode 100644
index 0000000..1fe737d
--- /dev/null
+++ b/xos/configurations/opencloud/supervisord.conf
@@ -0,0 +1,21 @@
+[supervisord]
+nodaemon=true
+logfile=/var/log/supervisord.log
+
+[program:observer]
+autorestart=true
+command=python /opt/xos/xos-observer.py
+stderr_logfile=/var/log/supervisor/observer.err.log
+stdout_logfile=/var/log/supervisor/observer.out.log
+
+program:uwsgi]
+autorestart=true
+command=uwsgi --ini /opt/xos/uwsgi/xos.ini
+stderr_logfile=/var/log/supervisor/uwsgi.err.log
+stdout_logfile=/var/log/supervisor/uwsgi.out.log
+
+[program:nginx]
+command=/usr/sbin/nginx
+autorestart=true
+stderr_logfile=/var/log/supervisor/nginx.err.log
+stdout_logfile=/var/log/supervisor/nginx.out.log
diff --git a/xos/core/admin.py b/xos/core/admin.py
index a5b89be..338f993 100644
--- a/xos/core/admin.py
+++ b/xos/core/admin.py
@@ -1372,6 +1372,39 @@
# obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
# obj.delete()
+class ContainerPortInline(XOSTabularInline):
+ fields = ['backend_status_icon', 'network', 'container', 'ip', 'mac', 'segmentation_id']
+ readonly_fields = ("backend_status_icon", "ip", "mac", "segmentation_id")
+ model = Port
+ selflink_fieldname = "network"
+ extra = 0
+ verbose_name_plural = "Ports"
+ verbose_name = "Port"
+ suit_classes = 'suit-tab suit-tab-ports'
+
+class ContainerAdmin(XOSBaseAdmin):
+ fieldsets = [
+ ('Instance Details', {'fields': ['backend_status_text', 'slice', 'node', 'docker_image', 'no_sync'], 'classes': ['suit-tab suit-tab-general'], })
+ ]
+ readonly_fields = ('backend_status_text', )
+ list_display = ['backend_status_icon', 'id']
+ list_display_links = ('backend_status_icon', 'id', )
+
+ suit_form_tabs =(('general', 'Instance Details'), ('ports', 'Ports'))
+
+ inlines = [TagInline, ContainerPortInline]
+
+ def formfield_for_foreignkey(self, db_field, request, **kwargs):
+ if db_field.name == 'slice':
+ kwargs['queryset'] = Slice.select_by_user(request.user)
+
+ return super(ContainerAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
+
+ def queryset(self, request):
+ # admins can see all instances. Users can only see instances of
+ # the slices they belong to.
+ return Container.select_by_user(request.user)
+
class UserCreationForm(forms.ModelForm):
"""A form for creating new users. Includes all the required
fields, plus a repeated password."""
@@ -1727,7 +1760,7 @@
readonly_fields = ('backend_status_icon', )
class NetworkPortInline(XOSTabularInline):
- fields = ['backend_status_icon', 'network', 'instance', 'ip', 'mac']
+ fields = ['backend_status_icon', 'network', 'instance', 'container', 'ip', 'mac']
readonly_fields = ("backend_status_icon", "ip", "mac")
model = Port
selflink_fieldname = "instance"
@@ -2024,4 +2057,5 @@
admin.site.register(TenantRoot, TenantRootAdmin)
admin.site.register(TenantRootRole, TenantRootRoleAdmin)
admin.site.register(TenantAttribute, TenantAttributeAdmin)
+ admin.site.register(Container, ContainerAdmin)
diff --git a/xos/core/models/__init__.py b/xos/core/models/__init__.py
index c380e9c..bc97dab 100644
--- a/xos/core/models/__init__.py
+++ b/xos/core/models/__init__.py
@@ -24,6 +24,7 @@
from .node import Node
from .slicetag import SliceTag
from .instance import Instance
+from .container import Container
from .reservation import ReservedResource
from .reservation import Reservation
from .network import Network, NetworkParameterType, NetworkParameter, Port, NetworkTemplate, Router, NetworkSlice, ControllerNetwork
diff --git a/xos/core/models/container.py b/xos/core/models/container.py
new file mode 100644
index 0000000..151b576
--- /dev/null
+++ b/xos/core/models/container.py
@@ -0,0 +1,83 @@
+import os
+from django.db import models
+from django.db.models import Q
+from django.core import exceptions
+from core.models import PlCoreBase,PlCoreBaseManager,PlCoreBaseDeletionManager
+from core.models.plcorebase import StrippedCharField
+from core.models import Image
+from core.models import Slice, SlicePrivilege
+from core.models import Node
+from core.models import Site
+from core.models import Deployment
+from core.models import Controller
+from core.models import User
+from core.models import Tag
+from core.models import Flavor
+from django.contrib.contenttypes import generic
+from xos.config import Config
+from monitor import driver as monitor
+from django.core.exceptions import PermissionDenied, ValidationError
+
+config = Config()
+
+
+# Create your models here.
+class Container(PlCoreBase):
+ name = StrippedCharField(max_length=200, help_text="Container name")
+ slice = models.ForeignKey(Slice, related_name='containers')
+ node = models.ForeignKey(Node, related_name='containers')
+ creator = models.ForeignKey(User, related_name='containers', blank=True, null=True)
+ docker_image = StrippedCharField(null=True, blank=True, max_length=200, help_text="name of docker container to instantiate")
+
+ def __unicode__(self):
+ return u'container-%s' % str(self.id)
+
+ def save(self, *args, **kwds):
+ if not self.name:
+ self.name = self.slice.name
+ if not self.creator and hasattr(self, 'caller'):
+ self.creator = self.caller
+ if not self.creator:
+ raise ValidationError('container has no creator')
+
+ if (self.slice.creator != self.creator):
+ # Check to make sure there's a slice_privilege for the user. If there
+ # isn't, then keystone will throw an exception inside the observer.
+ slice_privs = SlicePrivilege.objects.filter(slice=self.slice, user=self.creator)
+ if not slice_privs:
+ raise ValidationError('container creator has no privileges on slice')
+
+# XXX smbaker - disabled for now, was causing fault in tenant view create slice
+# if not self.controllerNetwork.test_acl(slice=self.slice):
+# raise exceptions.ValidationError("Deployment %s's ACL does not allow any of this slice %s's users" % (self.controllerNetwork.name, self.slice.name))
+
+ super(Container, self).save(*args, **kwds)
+
+ def can_update(self, user):
+ return True
+
+ @staticmethod
+ def select_by_user(user):
+ if user.is_admin:
+ qs = Container.objects.all()
+ else:
+ slices = Slice.select_by_user(user)
+ qs = Container.objects.filter(slice__in=slices)
+ return qs
+
+ def get_public_keys(self):
+ slice_memberships = SlicePrivilege.objects.filter(slice=self.slice)
+ pubkeys = set([sm.user.public_key for sm in slice_memberships if sm.user.public_key])
+
+ if self.creator.public_key:
+ pubkeys.add(self.creator.public_key)
+
+ if self.slice.creator.public_key:
+ pubkeys.add(self.slice.creator.public_key)
+
+ if self.slice.service and self.slice.service.public_key:
+ pubkeys.add(self.slice.service.public_key)
+
+ return pubkeys
+
+
diff --git a/xos/core/models/network.py b/xos/core/models/network.py
index 2bdf17f..48af5a6 100644
--- a/xos/core/models/network.py
+++ b/xos/core/models/network.py
@@ -2,7 +2,7 @@
import socket
import sys
from django.db import models
-from core.models import PlCoreBase, Site, Slice, Instance, Controller
+from core.models import PlCoreBase, Site, Slice, Instance, Controller, Container
from core.models import ControllerLinkManager,ControllerLinkDeletionManager
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
@@ -158,7 +158,7 @@
router_id = models.CharField(null=True, blank=True, max_length=256, help_text="Quantum router id")
subnet_id = models.CharField(null=True, blank=True, max_length=256, help_text="Quantum subnet id")
subnet = models.CharField(max_length=32, blank=True)
-
+
class Meta:
unique_together = ('network', 'controller')
@@ -211,9 +211,12 @@
class Port(PlCoreBase):
network = models.ForeignKey(Network,related_name='links')
instance = models.ForeignKey(Instance, null=True, blank=True, related_name='ports')
+ container = models.ForeignKey(Container, null=True, blank=True, related_name='ports')
ip = models.GenericIPAddressField(help_text="Instance ip address", blank=True, null=True)
port_id = models.CharField(null=True, blank=True, max_length=256, help_text="Quantum port id")
mac = models.CharField(null=True, blank=True, max_length=256, help_text="MAC address associated with this port")
+ #unattached = models.BooleanField(default=False, help_text="create this port even if no Instance is attached")
+ segmentation_id = models.CharField(null=True, blank=True, max_length=256, help_text="GRE segmentation id for port")
class Meta:
unique_together = ('network', 'instance')
diff --git a/xos/nginx/xos.conf b/xos/nginx/xos.conf
index 9b5d996..64d9d5e 100644
--- a/xos/nginx/xos.conf
+++ b/xos/nginx/xos.conf
@@ -6,8 +6,9 @@
server {
- listen 80;
- server_name 128.112.139.48;
+ listen 80;
+ listen [::]:80 default ipv6only=on; ## listen for ipv6
+ server_name 127.0.0.1;
location /static/ {
alias /opt/xos/core/static/;
diff --git a/xos/observers/onos/steps/sync_onosapp.yaml b/xos/observers/onos/steps/sync_onosapp.yaml
index 2c5eb0f..ad3718c 100644
--- a/xos/observers/onos/steps/sync_onosapp.yaml
+++ b/xos/observers/onos/steps/sync_onosapp.yaml
@@ -11,39 +11,44 @@
tasks:
- name: Config file directory
- file:
- path=/home/ubuntu/{{ appname }}/
- state=directory
-
- - name: Copy over configuration files
- copy:
- src={{ files_dir }}/{{ '{{' }} item {{ '}}' }}
- dest=/home/ubuntu/{{ appname }}/{{ '{{' }} item {{ '}}' }}
- with_items:
- {% for config_fn in config_fns %}
+ file:
+ path=/home/ubuntu/{{ appname }}/
+ state=directory
+
+{% if config_fns %}
+ - name: Copy over configuration files
+ copy:
+ src={{ files_dir }}/{{ '{{' }} item {{ '}}' }}
+ dest=/home/ubuntu/{{ appname }}/{{ '{{' }} item {{ '}}' }}
+ with_items:
+ {% for config_fn in config_fns %}
- {{ config_fn }}
- {% endfor %}
-
- - name: Copy config files into container
- shell: docker cp {{ appname }}/{{ '{{' }} item {{ '}}' }} {{ ONOS_container }}:/root/onos/config/
- sudo: yes
- with_items:
- {% for config_fn in config_fns %}
+ {% endfor %}
+
+ - name: Make sure config directory exists
+ shell: docker exec {{ ONOS_container }} mkdir -p /root/onos/config/
+ sudo: yes
+
+ - name: Copy config files into container
+ shell: docker cp {{ appname }}/{{ '{{' }} item {{ '}}' }} {{ ONOS_container }}:/root/onos/config/
+ sudo: yes
+ with_items:
+ {% for config_fn in config_fns %}
- {{ config_fn }}
- {% endfor %}
-
- # Don't know how to check for this condition, just wait
- - name: Wait for ONOS to install the apps
- wait_for: timeout=15
-
- - name: Add dependencies to ONOS
- uri:
- url: http://localhost:8181/onos/v1/applications/{{ '{{' }} item {{ '}}' }}/active
- method: POST
- user: karaf
- password: karaf
- with_items:
- {% for dependency in dependencies %}
+ {% endfor %}
+{% endif %}
+
+ # Don't know how to check for this condition, just wait
+ - name: Wait for ONOS to install the apps
+ wait_for: timeout=15
+
+ - name: Add dependencies to ONOS
+ uri:
+ url: http://localhost:8181/onos/v1/applications/{{ '{{' }} item {{ '}}' }}/active
+ method: POST
+ user: karaf
+ password: karaf
+ with_items:
+ {% for dependency in dependencies %}
- {{ dependency }}
- {% endfor %}
-
+ {% endfor %}
diff --git a/xos/observers/vcpe/vcpe_stats_notifier.py b/xos/observers/vcpe/vcpe_stats_notifier.py
index f4bb923..d726e3c 100644
--- a/xos/observers/vcpe/vcpe_stats_notifier.py
+++ b/xos/observers/vcpe/vcpe_stats_notifier.py
@@ -14,7 +14,11 @@
level=logging.INFO
logger=logging.getLogger('vcpe_stats_notifier')
logger.setLevel(level)
+# create formatter
+formatter = logging.Formatter("%(asctime)s;%(levelname)s;%(message)s")
handler=logging.handlers.RotatingFileHandler(logfile,maxBytes=1000000, backupCount=1)
+# add formatter to handler
+handler.setFormatter(formatter)
logger.addHandler(handler)
def extract_dns_stats_from_all_vcpes():
@@ -105,6 +109,9 @@
def publish_cpe_stats():
global producer
global keystone_tenant_id, keystone_user_id, cpe_publisher_id
+
+ logger.debug('publish_cpe_stats invoked')
+
cpe_container_stats = extract_dns_stats_from_all_vcpes()
for k,v in cpe_container_stats.iteritems():
@@ -119,6 +126,8 @@
}
}
producer.publish(msg)
+ logger.debug('Publishing vcpe event: %s', msg)
+
if 'cache_size' in v:
msg = {'event_type': 'vcpe.dns.cache.size',
'message_id':six.text_type(uuid.uuid4()),
@@ -132,6 +141,8 @@
}
}
producer.publish(msg)
+ logger.debug('Publishing vcpe.dns.cache.size event: %s', msg)
+
if 'total_inserted_entries' in v:
msg = {'event_type': 'vcpe.dns.total_inserted_entries',
'message_id':six.text_type(uuid.uuid4()),
@@ -145,6 +156,8 @@
}
}
producer.publish(msg)
+ logger.debug('Publishing vcpe.dns.total_inserted_entries event: %s', msg)
+
if 'replaced_unexpired_entries' in v:
msg = {'event_type': 'vcpe.dns.replaced_unexpired_entries',
'message_id':six.text_type(uuid.uuid4()),
@@ -158,6 +171,7 @@
}
}
producer.publish(msg)
+ logger.debug('Publishing vcpe.dns.replaced_unexpired_entries event: %s', msg)
if 'queries_forwarded' in v:
msg = {'event_type': 'vcpe.dns.queries_forwarded',
@@ -172,6 +186,7 @@
}
}
producer.publish(msg)
+ logger.debug('Publishing vcpe.dns.queries_forwarded event: %s', msg)
if 'queries_answered_locally' in v:
msg = {'event_type': 'vcpe.dns.queries_answered_locally',
@@ -186,6 +201,7 @@
}
}
producer.publish(msg)
+ logger.debug('Publishing vcpe.dns.queries_answered_locally event: %s', msg)
if 'server_stats' in v:
for server in v['server_stats']:
@@ -202,6 +218,7 @@
}
}
producer.publish(msg)
+ logger.debug('Publishing vcpe.dns.server.queries_sent event: %s', msg)
msg = {'event_type': 'vcpe.dns.server.queries_failed',
'message_id':six.text_type(uuid.uuid4()),
@@ -216,6 +233,7 @@
}
}
producer.publish(msg)
+ logger.debug('Publishing vcpe.dns.server.queries_failed event: %s', msg)
def periodic_publish():
publish_cpe_stats()
diff --git a/xos/openstack_observer/ansible.py b/xos/openstack_observer/ansible.py
index ee110c9..94b09bd 100644
--- a/xos/openstack_observer/ansible.py
+++ b/xos/openstack_observer/ansible.py
@@ -144,16 +144,21 @@
return ok_results
def run_template_ssh(name, opts, path='', expected_num=None):
- instance_id = opts["instance_id"]
instance_name = opts["instance_name"]
hostname = opts["hostname"]
private_key = opts["private_key"]
- nat_ip = opts["nat_ip"]
-
- try:
- proxy_ssh = Config().observer_proxy_ssh
- except:
- proxy_ssh = True
+ baremetal_ssh = opts.get("baremetal_ssh",False)
+ if baremetal_ssh:
+ # no instance_id or nat_ip for baremetal
+ # we never proxy to baremetal
+ proxy_ssh = False
+ else:
+ instance_id = opts["instance_id"]
+ nat_ip = opts["nat_ip"]
+ try:
+ proxy_ssh = Config().observer_proxy_ssh
+ except:
+ proxy_ssh = True
(opts, fqp) = get_playbook_fn(opts, path)
private_key_pathname = fqp + ".key"
@@ -177,7 +182,7 @@
f = open(hosts_pathname, "w")
f.write("[%s]\n" % instance_name)
- if proxy_ssh:
+ if proxy_ssh or baremetal_ssh:
f.write("%s ansible_ssh_private_key_file=%s\n" % (hostname, private_key_pathname))
else:
# acb: Login user is hardcoded, this is not great
diff --git a/xos/openstack_observer/steps/sync_container.py b/xos/openstack_observer/steps/sync_container.py
new file mode 100644
index 0000000..c6ac936
--- /dev/null
+++ b/xos/openstack_observer/steps/sync_container.py
@@ -0,0 +1,90 @@
+import hashlib
+import os
+import socket
+import sys
+import base64
+import time
+from django.db.models import F, Q
+from xos.config import Config
+from observer.syncstep import SyncStep
+from observer.ansible import run_template_ssh
+from core.models import Service, Slice, Container
+from services.onos.models import ONOSService, ONOSApp
+from util.logger import Logger, logging
+
+# hpclibrary will be in steps/..
+parentdir = os.path.join(os.path.dirname(__file__),"..")
+sys.path.insert(0,parentdir)
+
+logger = Logger(level=logging.INFO)
+
+class SyncContainer(SyncStep):
+ provides=[Container]
+ observes=Container
+ requested_interval=0
+ template_name = "sync_container.yaml"
+
+ def __init__(self, *args, **kwargs):
+ super(SyncContainer, self).__init__(*args, **kwargs)
+
+# def fetch_pending(self, deleted):
+# if (not deleted):
+# objs = ONOSService.get_service_objects().filter(Q(enacted__lt=F('updated')) | Q(enacted=None),Q(lazy_blocked=False))
+# else:
+# objs = ONOSService.get_deleted_service_objects()
+#
+# return objs
+
+ def get_node(self,o):
+ return o.node
+
+ def get_node_key(self, node):
+ return "/opt/xos/node-key"
+
+ def get_extra_attributes(self, o):
+ fields={}
+ fields["ansible_tag"] = "container-%s" % str(o.id)
+ fields["baremetal_ssh"] = True
+ fields["instance_name"] = "rootcontext"
+ fields["container_name"] = o.name
+ fields["docker_image"] = o.docker_image
+ fields["username"] = "xos"
+ return fields
+
+ def sync_fields(self, o, fields):
+ self.run_playbook(o, fields)
+
+ def sync_record(self, o):
+ logger.info("sync'ing object %s" % str(o))
+
+ node = self.get_node(o)
+ node_key_name = self.get_node_key(node)
+
+ if not os.path.exists(node_key_name):
+ raise Exception("Node key %s does not exist" % node_key_name)
+
+ node_key = file(node_key_name).read()
+
+ fields = { "hostname": node.name,
+ "private_key": node_key,
+ }
+
+ # If 'o' defines a 'sync_attributes' list, then we'll copy those
+ # attributes into the Ansible recipe's field list automatically.
+ if hasattr(o, "sync_attributes"):
+ for attribute_name in o.sync_attributes:
+ fields[attribute_name] = getattr(o, attribute_name)
+
+ fields.update(self.get_extra_attributes(o))
+
+ self.sync_fields(o, fields)
+
+ o.save()
+
+ def run_playbook(self, o, fields):
+ tStart = time.time()
+ run_template_ssh(self.template_name, fields, path="container")
+ logger.info("playbook execution time %d" % int(time.time()-tStart))
+
+ def delete_record(self, m):
+ pass
diff --git a/xos/openstack_observer/steps/sync_container.yaml b/xos/openstack_observer/steps/sync_container.yaml
new file mode 100644
index 0000000..d97f0df
--- /dev/null
+++ b/xos/openstack_observer/steps/sync_container.yaml
@@ -0,0 +1,48 @@
+---
+- hosts: {{ instance_name }}
+ gather_facts: False
+ connection: ssh
+ user: {{ username }}
+ sudo: yes
+
+ tasks:
+
+# - name: Fix /etc/hosts
+# lineinfile:
+# dest=/etc/hosts
+# regexp="127.0.0.1 localhost"
+# line="127.0.0.1 localhost {{ instance_hostname }}"
+
+ - name: Add repo key
+ apt_key:
+ keyserver=hkp://pgp.mit.edu:80
+ id=58118E89F3A912897C070ADBF76221572C52609D
+
+ - name: Install Docker repo
+ apt_repository:
+ repo="deb https://apt.dockerproject.org/repo ubuntu-trusty main"
+ state=present
+
+ - name: Install Docker
+ apt:
+ name={{ '{{' }} item {{ '}}' }}
+ state=latest
+ update_cache=yes
+ with_items:
+ - docker-engine
+ - python-pip
+ - python-httplib2
+
+ - name: Install docker-py
+ pip:
+ name=docker-py
+ state=latest
+
+ - name: Start Container
+ docker:
+ docker_api_version: "1.18"
+ name: {{ container_name }}
+ # was: reloaded
+ state: running
+ image: {{ docker_image }}
+
diff --git a/xos/openstack_observer/steps/sync_ports.py b/xos/openstack_observer/steps/sync_ports.py
index 967bef9..7b20d29 100644
--- a/xos/openstack_observer/steps/sync_ports.py
+++ b/xos/openstack_observer/steps/sync_ports.py
@@ -144,9 +144,14 @@
# For ports that were created by the user, find that ones
# that don't have neutron ports, and create them.
- for port in Port.objects.filter(port_id__isnull=True, instance__isnull=False):
- #logger.info("XXX working on port %s" % port)
- controller = port.instance.node.site_deployment.controller
+ for port in Port.objects.filter(Q(port_id__isnull=True), Q(instance__isnull=False) | Q(container__isnull=False)):
+ logger.info("XXX working on port %s" % port)
+ if port.instance:
+ controller = port.instance.node.site_deployment.controller
+ slice = port.instance.slice
+ else:
+ controller = port.container.node.site_deployment.controller
+ slice = port.container.slice
if controller:
cn=port.network.controllernetworks.filter(controller=controller)
if not cn:
@@ -174,7 +179,7 @@
caller = port.network.owner.creator
auth = {'username': caller.email,
'password': caller.remote_password,
- 'tenant': port.instance.slice.name} # port.network.owner.name}
+ 'tenant': slice.name}
client = OpenStackClient(controller=controller, **auth) # cacert=self.config.nova_ca_ssl_cert,
driver = OpenStackDriver(client=client)
@@ -183,6 +188,10 @@
if neutron_port["fixed_ips"]:
port.ip = neutron_port["fixed_ips"][0]["ip_address"]
port.mac = neutron_port["mac_address"]
+
+ neutron_network = driver.shell.quantum.list_networks(cn.net_id)["networks"][0]
+ if "provider:segmentation_id" in neutron_network:
+ port.segmentation_id = neutron_network["provider:segmentation_id"]
except:
logger.log_exc("failed to create neutron port for %s" % port)
continue
diff --git a/xos/tosca/custom_types/xos.m4 b/xos/tosca/custom_types/xos.m4
index 055817d..039b433 100644
--- a/xos/tosca/custom_types/xos.m4
+++ b/xos/tosca/custom_types/xos.m4
@@ -120,6 +120,9 @@
config_addresses.json:
type: string
required: false
+ config_network-cfg.json:
+ type: string
+ required: false
config_virtualbng.json:
type: string
required: false
@@ -686,4 +689,3 @@
tosca.capabilities.xos.Image:
derived_from: tosca.capabilities.Root
description: An XOS Image
-
diff --git a/xos/tosca/custom_types/xos.yaml b/xos/tosca/custom_types/xos.yaml
index 409e86b..3cbe4b2 100644
--- a/xos/tosca/custom_types/xos.yaml
+++ b/xos/tosca/custom_types/xos.yaml
@@ -131,6 +131,9 @@
config_addresses.json:
type: string
required: false
+ config_network-cfg.json:
+ type: string
+ required: false
config_virtualbng.json:
type: string
required: false
@@ -869,4 +872,3 @@
tosca.capabilities.xos.Image:
derived_from: tosca.capabilities.Root
description: An XOS Image
-
diff --git a/xos/uwsgi/xos.ini b/xos/uwsgi/xos.ini
index da7f7dd..4c3f62c 100644
--- a/xos/uwsgi/xos.ini
+++ b/xos/uwsgi/xos.ini
@@ -2,9 +2,9 @@
chdir = /opt/xos
module = xos.wsgi:application
env = DJANGO_SETTINGS_MODULE=xos.settings
-socket = /var/run/uwsgi/xos.sock
+socket = /var/run/uwsgi.xos.sock
socket = 127.0.0.1:9001
-http = 128.112.139.48:9002
+http = 127.0.0.1:9002
stats = 127.0.0.1:9003
workers = 3
master = true
@@ -12,7 +12,7 @@
uid = uwsgi
gid = webserver
harakiri = 20
-daemonize=/var/log/uwsgi/xos.log
+daemonize=/var/log/uwsgi.xos.log
static-map = /static=/var/www/xos/static
-pidfile = /var/run/uwsgi/uwsgi.pid
+pidfile = /var/run/uwsgi.xos.pid
buffer-size = 8192
diff --git a/xos/xos/settings.py b/xos/xos/settings.py
index e660352..3e64d15 100644
--- a/xos/xos/settings.py
+++ b/xos/xos/settings.py
@@ -120,6 +120,12 @@
# Python dotted path to the WSGI application used by Django's runserver.
WSGI_APPLICATION = 'xos.wsgi.application'
+# Default: 'csrftoken'
+CSRF_COOKIE_NAME = 'xoscsrftoken'
+# Default: 'django_language'
+LANGUAGE_COOKIE_NAME = 'xos_django_language'
+# Default: 'sessionid'
+SESSION_COOKIE_NAME = 'xossessionid'
TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".