{% trans "Internal Server Error... Please leave the server alone..." %}
{% endblock content %}
cloud-a8c081dc34c0e07b6655a89d68b2af3758203481-a8c081dc34c0e07b6655a89d68b2af3758203481/circle/vm/ 0000775 0000000 0000000 00000000000 12211653074 0026506 5 ustar 00root root 0000000 0000000 __init__.py 0000664 0000000 0000000 00000000000 12211653074 0030526 0 ustar 00root root 0000000 0000000 cloud-a8c081dc34c0e07b6655a89d68b2af3758203481-a8c081dc34c0e07b6655a89d68b2af3758203481/circle/vm models.py 0000775 0000000 0000000 00000046316 12211653074 0030301 0 ustar 00root root 0000000 0000000 cloud-a8c081dc34c0e07b6655a89d68b2af3758203481-a8c081dc34c0e07b6655a89d68b2af3758203481/circle/vm #!/usr/bin/env python
from datetime import timedelta
import logging
from . import tasks
from manager import manager, scheduler
from django.contrib.auth.models import User
from django.db import models
from django.db.models.signals import pre_delete
from django.dispatch import receiver
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from model_utils.models import TimeStampedModel
from firewall.models import Vlan, Host
from storage.models import Disk
logger = logging.getLogger(__name__)
pwgen = User.objects.make_random_password
# TODO get this from config
ACCESS_PROTOCOLS = {
# format: id: (name, port, protocol)
'rdp': ('rdp', 3389, 'tcp'),
'nx': ('nx', 22, 'tcp'),
'ssh': ('ssh', 22, 'tcp'),
}
ACCESS_METHODS = [(k, ap[0]) for k, ap in ACCESS_PROTOCOLS.iteritems()]
class BaseResourceConfigModel(models.Model):
"""Abstract base class for models with base resource configuration
parameters.
"""
num_cores = models.IntegerField(help_text=_('Number of CPU cores.'))
ram_size = models.IntegerField(help_text=_('Mebibytes of memory.'))
max_ram_size = models.IntegerField(help_text=_('Upper memory size limit '
'for balloning.'))
arch = models.CharField(max_length=10, verbose_name=_('architecture'))
priority = models.IntegerField(help_text=_('instance priority'))
boot_menu = models.BooleanField(default=False)
raw_data = models.TextField(blank=True, null=True)
class Meta:
abstract = True
class NamedBaseResourceConfig(BaseResourceConfigModel, TimeStampedModel):
"""Pre-created, named base resource configurations.
"""
name = models.CharField(max_length=50, unique=True,
verbose_name=_('name'))
def __unicode__(self):
return self.name
class Node(TimeStampedModel):
"""A VM host machine.
"""
name = models.CharField(max_length=50, unique=True,
verbose_name=_('name'))
num_cores = models.IntegerField(help_text=_('Number of CPU cores.'))
ram_size = models.IntegerField(help_text=_('Mebibytes of memory.'))
priority = models.IntegerField(help_text=_('node usage priority'))
host = models.ForeignKey(Host)
enabled = models.BooleanField(default=False,
help_text=_('Indicates whether the node can '
'be used for hosting.'))
class Meta:
permissions = ()
@property
def online(self):
"""Indicates whether the node is connected and functional.
"""
pass # TODO implement check
class NodeActivity(TimeStampedModel):
activity_code = models.CharField(max_length=100)
task_uuid = models.CharField(
max_length=50, unique=True, null=True, blank=True)
node = models.ForeignKey(Node, related_name='activity_log')
user = models.ForeignKey(User, blank=True, null=True)
started = models.DateTimeField(blank=True, null=True)
finished = models.DateTimeField(blank=True, null=True)
result = models.TextField(blank=True, null=True)
status = models.CharField(default='PENDING', max_length=50)
class Lease(models.Model):
"""Lease times for VM instances.
Specifies a time duration until suspension and deletion of a VM
instance.
"""
name = models.CharField(max_length=100, unique=True,
verbose_name=_('name'))
suspend_interval_seconds = models.IntegerField()
delete_interval_seconds = models.IntegerField()
class Meta:
ordering = ['name', ]
@property
def suspend_interval(self):
return timedelta(seconds=self.suspend_interval_seconds)
@suspend_interval.setter
def suspend_interval(self, value):
self.suspend_interval_seconds = value.seconds
@property
def delete_interval(self):
return timedelta(seconds=self.delete_interval_seconds)
@delete_interval.setter
def delete_interval(self, value):
self.delete_interval_seconds = value.seconds
class InstanceTemplate(BaseResourceConfigModel, TimeStampedModel):
"""Virtual machine template.
Every template has:
* a name and a description
* an optional parent template
* state of the template
* an OS name/description
* a method of access to the system
* default values of base resource configuration
* list of attached images
* set of interfaces
* lease times (suspension & deletion)
* time of creation and last modification
"""
STATES = [('NEW', _('new')), # template has just been created
('SAVING', _('saving')), # changes are being saved
('READY', _('ready'))] # template is ready for instantiation
name = models.CharField(max_length=100, unique=True,
verbose_name=_('name'))
description = models.TextField(verbose_name=_('description'),
blank=True)
parent = models.ForeignKey('self', null=True, blank=True,
verbose_name=_('parent template'))
system = models.TextField(verbose_name=_('operating system'),
blank=True,
help_text=(_('Name of operating system in '
'format like "%s".') %
'Ubuntu 12.04 LTS Desktop amd64'))
access_method = models.CharField(max_length=10, choices=ACCESS_METHODS,
verbose_name=_('access method'))
state = models.CharField(max_length=10, choices=STATES,
default='NEW')
disks = models.ManyToManyField(Disk, verbose_name=_('disks'),
related_name='template_set')
lease = models.ForeignKey(Lease, related_name='template_set')
class Meta:
ordering = ['name', ]
permissions = ()
verbose_name = _('template')
verbose_name_plural = _('templates')
def __unicode__(self):
return self.name
def running_instances(self):
"""Returns the number of running instances of the template.
"""
return self.instance_set.filter(state='RUNNING').count()
@property
def os_type(self):
"""Get the type of the template's operating system.
"""
if self.access_method == 'rdp':
return 'win'
else:
return 'linux'
class InterfaceTemplate(models.Model):
"""Network interface template for an instance template.
If the interface is managed, a host will be created for it.
"""
vlan = models.ForeignKey(Vlan)
managed = models.BooleanField(default=True)
template = models.ForeignKey(InstanceTemplate,
related_name='interface_set')
class Meta:
permissions = ()
verbose_name = _('interface template')
verbose_name_plural = _('interface templates')
class Instance(BaseResourceConfigModel, TimeStampedModel):
"""Virtual machine instance.
Every instance has:
* a name and a description
* an optional parent template
* associated share
* a generated password for login authentication
* time of deletion and time of suspension
* lease times (suspension & deletion)
* last boot timestamp
* host node
* current state (libvirt domain state)
* time of creation and last modification
* base resource configuration values
* owner and privilege information
"""
STATES = [('NOSTATE', _('nostate')),
('RUNNING', _('running')),
('BLOCKED', _('blocked')),
('PAUSED', _('paused')),
('SHUTDOWN', _('shutdown')),
('SHUTOFF', _('shutoff')),
('CRASHED', _('crashed')),
('PMSUSPENDED', _('pmsuspended'))] # libvirt domain states
name = models.CharField(blank=True, max_length=100, verbose_name=_('name'))
description = models.TextField(blank=True, verbose_name=_('description'))
template = models.ForeignKey(InstanceTemplate, blank=True, null=True,
related_name='instance_set',
verbose_name=_('template'))
pw = models.CharField(help_text=_('Original password of instance'),
max_length=20, verbose_name=_('password'))
time_of_suspend = models.DateTimeField(blank=True, default=None, null=True,
verbose_name=_('time of suspend'))
time_of_delete = models.DateTimeField(blank=True, default=None, null=True,
verbose_name=_('time of delete'))
active_since = models.DateTimeField(blank=True, null=True,
help_text=_('Time stamp of successful '
'boot report.'),
verbose_name=_('active since'))
node = models.ForeignKey(Node, blank=True, null=True,
related_name='instance_set',
verbose_name=_('host nose'))
state = models.CharField(choices=STATES, default='NOSTATE', max_length=20)
disks = models.ManyToManyField(Disk, related_name='instance_set',
verbose_name=_('disks'))
lease = models.ForeignKey(Lease)
access_method = models.CharField(max_length=10, choices=ACCESS_METHODS,
verbose_name=_('access method'))
owner = models.ForeignKey(User)
class Meta:
ordering = ['pk', ]
permissions = ()
verbose_name = _('instance')
verbose_name_plural = _('instances')
def __unicode__(self):
return self.name
@classmethod
def create_from_template(cls, template, owner, **kwargs):
"""Create a new instance based on an InstanceTemplate.
Can also specify parameters as keyword arguments which should override
template settings.
"""
# prepare parameters
kwargs['template'] = template
kwargs['owner'] = owner
kwargs.setdefault('name', template.name)
kwargs.setdefault('description', template.description)
kwargs.setdefault('pw', pwgen())
kwargs.setdefault('num_cores', template.num_cores)
kwargs.setdefault('ram_size', template.ram_size)
kwargs.setdefault('max_ram_size', template.max_ram_size)
kwargs.setdefault('arch', template.arch)
kwargs.setdefault('priority', template.priority)
kwargs.setdefault('lease', template.lease)
kwargs.setdefault('access_method', template.access_method)
# create instance and do additional setup
inst = cls(**kwargs)
for disk in template.disks:
inst.disks.add(disk.get_exclusive())
# save instance
inst.save()
# create related entities
for iftmpl in template.interface_set.all():
i = Interface.create_from_template(instance=inst, template=iftmpl)
if i.host:
i.host.enable_net()
port, proto = ACCESS_PROTOCOLS[i.access_method][1:3]
i.host.add_port(proto, i.get_port(), port)
return inst
@models.permalink
def get_absolute_url(self):
# TODO is this obsolete?
return ('one.views.vm_show', None, {'iid': self.id})
@property
def primary_host(self):
interfaces = self.interface_set.select_related('host')
hosts = [i.host for i in interfaces if i.host]
if not hosts:
return None
hs = [h for h in hosts if h.ipv6]
if hs:
return hs[0]
hs = [h for h in hosts if not h.shared_ip]
if hs:
return hs[0]
return hosts[0]
@property
def ipv4(self):
"""Primary IPv4 address of the instance.
"""
return self.primary_host.ipv4 if self.primary_host else None
@property
def ipv6(self):
"""Primary IPv6 address of the instance.
"""
return self.primary_host.ipv6 if self.primary_host else None
@property
def mac(self):
"""Primary MAC address of the instance.
"""
return self.primary_host.mac if self.primary_host else None
@property
def uptime(self):
"""Uptime of the instance.
"""
if self.active_since:
return timezone.now() - self.active_since
else:
return timedelta() # zero
def get_age(self):
"""Deprecated. Use uptime instead.
Get age of VM in seconds.
"""
return self.uptime.seconds
@property
def waiting(self):
"""Indicates whether the instance's waiting for an operation to finish.
"""
return self.activity_log.filter(finished__isnull=True).exists()
def get_connect_port(self, use_ipv6=False):
"""Get public port number for default access method.
"""
port, proto = ACCESS_PROTOCOLS[self.access_method][1:3]
if self.primary_host:
endpoints = self.primary_host.get_public_endpoints(port, proto)
endpoint = endpoints['ipv6'] if use_ipv6 else endpoints['ipv4']
return endpoint[1] if endpoint else None
else:
return None
def get_connect_host(self, use_ipv6=False):
"""Get public hostname.
"""
if not self.firewall_host:
return _('None')
proto = 'ipv6' if use_ipv6 else 'ipv4'
return self.firewall_host.get_hostname(proto=proto)
def get_connect_uri(self, use_ipv6=False):
"""Get access parameters in URI format.
"""
try:
port = self.get_connect_port(use_ipv6=use_ipv6)
host = self.get_connect_host(use_ipv6=use_ipv6)
proto = self.access_method
if proto == 'ssh':
proto = 'sshterm'
return ('%(proto)s:cloud:%(pw)s:%(host)s:%(port)d' %
{'port': port, 'proto': proto, 'pw': self.pw,
'host': host})
except:
return
def get_vm_desc(self):
return {
'name': 'cloud-' + self.id,
'vcpu': self.num_cores,
'memory': self.ram_size,
'memory_max': self.max_ram_size,
'cpu_share': self.priority,
'arch': self.arch,
'boot_menu': self.boot_menu,
'network_list': [n.get_vmnetwork_desc()
for n in self.interface_set.all()],
'disk_list': [n.get_vmdisk_desc() for n in self.disks.all()],
'graphics': {'type': 'vnc',
'listen': '0.0.0.0',
'passwd': '',
'port': self.get_vnc_port()},
'raw_data': self.raw_data
}
def deploy_async(self):
''' Launch celery task to handle asyncron jobs.
'''
manager.deploy.apply_async(self)
def deploy(self, user, task_uuid=None):
''' Deploy new virtual machine with network
1. Schedule
'''
act = InstanceActivity(user=user, task_uuid=task_uuid)
# Schedule
act.update_state("PENDING")
self.node = scheduler.get_node()
# Create virtual images
act.update_state("PREPARING DISKS")
for disk in self.disks:
disk.deploy()
# Deploy VM on remote machine
act.update_state("DEPLOYING VM")
tasks.create.apply_async(
self.get_vm_desc, queue=self.node + ".vm").get()
# Estabilish network connection (vmdriver)
act.update_state("DEPLOYING NET")
for net in self.interface_set.all():
net.deploy()
# Resume vm
act.update_state("BOOTING")
tasks.resume.apply_async(
"cloud-" + self.id, queue=self.node + ".vm").get()
act.finish()
def stop(self):
# TODO implement
pass
def resume(self):
# TODO implement
pass
def poweroff(self):
# TODO implement
pass
def restart(self):
# TODO implement
pass
def renew(self, which='both'):
"""Renew virtual machine instance leases.
"""
if which not in ['suspend', 'delete', 'both']:
raise ValueError('No such expiration type.')
if which in ['suspend', 'both']:
self.time_of_suspend = timezone.now() + self.lease.suspend_interval
if which in ['delete', 'both']:
self.time_of_delete = timezone.now() + self.lease.delete_interval
self.save()
def save_as(self):
"""Save image and shut down."""
imgname = "template-%d-%d" % (self.template.id, self.id)
from .tasks import SaveAsTask
SaveAsTask.delay(one_id=self.one_id, new_img=imgname)
self._change_state("SHUTDOWN")
self.save()
t = self.template
t.state = 'SAVING'
t.save()
def check_if_is_save_as_done(self):
if self.state != 'DONE':
return False
Disk.update(delete=False)
imgname = "template-%d-%d" % (self.template.id, self.id)
disks = Disk.objects.filter(name=imgname)
if len(disks) != 1:
return False
self.template.disk_id = disks[0].id
self.template.state = 'READY'
self.template.save()
self.firewall_host_delete()
return True
@receiver(pre_delete, sender=Instance, dispatch_uid='delete_instance_pre')
def delete_instance_pre(sender, instance, using, **kwargs):
# TODO implement
pass
class InstanceActivity(TimeStampedModel):
activity_code = models.CharField(max_length=100)
task_uuid = models.CharField(
max_length=50, unique=True, null=True, blank=True)
instance = models.ForeignKey(Instance, related_name='activity_log')
user = models.ForeignKey(User, blank=True, null=True)
started = models.DateTimeField(blank=True, null=True)
finished = models.DateTimeField(blank=True, null=True)
result = models.TextField(blank=True, null=True)
status = models.CharField(default='PENDING', max_length=50)
def __init__(self):
# TODO
pass
def update_state(self):
# TODO
pass
def finish(self):
# TODO
pass
class Interface(models.Model):
"""Network interface for an instance.
"""
vlan = models.ForeignKey(Vlan, related_name="vm_interface")
host = models.ForeignKey(Host, blank=True, null=True)
instance = models.ForeignKey(Instance, related_name='interface_set')
def mac_generator(self):
# MAC 02:XX:XX:X:VID
pass
def get_vmnetwork_desc(self):
return {
'name': 'cloud-' + self.instance.id + '-' + self.vlan.vid,
'bridge': 'cloud',
'mac': self.mac_generator(),
'ipv4': self.host.ipv4 if self.host is not None else None,
'ipv6': self.host.ipv6 if self.host is not None else None,
'vlan': self.vlan.vid,
'managed': self.host is not None
}
@classmethod
def create_from_template(cls, instance, template):
"""Create a new interface for an instance based on an
InterfaceTemplate.
"""
host = Host(vlan=template.vlan) if template.managed else None
iface = cls(vlan=template.vlan, host=host, instance=instance)
iface.save()
return iface
tasks.py 0000664 0000000 0000000 00000000153 12211653074 0030125 0 ustar 00root root 0000000 0000000 cloud-a8c081dc34c0e07b6655a89d68b2af3758203481-a8c081dc34c0e07b6655a89d68b2af3758203481/circle/vm from manager.manager import celery
@celery.task(name='vmdriver.create')
def create(parameters):
pass
tests/ 0000775 0000000 0000000 00000000000 12211653074 0027571 5 ustar 00root root 0000000 0000000 cloud-a8c081dc34c0e07b6655a89d68b2af3758203481-a8c081dc34c0e07b6655a89d68b2af3758203481/circle/vm __init__.py 0000664 0000000 0000000 00000000000 12211653074 0031670 0 ustar 00root root 0000000 0000000 cloud-a8c081dc34c0e07b6655a89d68b2af3758203481-a8c081dc34c0e07b6655a89d68b2af3758203481/circle/vm/tests test_models.py 0000664 0000000 0000000 00000000412 12211653074 0032462 0 ustar 00root root 0000000 0000000 cloud-a8c081dc34c0e07b6655a89d68b2af3758203481-a8c081dc34c0e07b6655a89d68b2af3758203481/circle/vm/tests from django.test import TestCase
from .models import Template
class TemplateTestCase(TestCase):
def test_template_creation(self):
template = Template(name='My first template',
access_method='ssh', ) # TODO add images & net
views.py 0000664 0000000 0000000 00000000032 12211653074 0030131 0 ustar 00root root 0000000 0000000 cloud-a8c081dc34c0e07b6655a89d68b2af3758203481-a8c081dc34c0e07b6655a89d68b2af3758203481/circle/vm # Create your views here.
cloud-a8c081dc34c0e07b6655a89d68b2af3758203481-a8c081dc34c0e07b6655a89d68b2af3758203481/docs/ 0000775 0000000 0000000 00000000000 12211653074 0025553 5 ustar 00root root 0000000 0000000 Makefile 0000664 0000000 0000000 00000012754 12211653074 0027145 0 ustar 00root root 0000000 0000000 cloud-a8c081dc34c0e07b6655a89d68b2af3758203481-a8c081dc34c0e07b6655a89d68b2af3758203481/docs # Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = _build
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
help:
@echo "Please use \`make ' where is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " texinfo to make Texinfo files"
@echo " info to make Texinfo files and run them through makeinfo"
@echo " gettext to make PO message catalogs"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
clean:
-rm -rf $(BUILDDIR)/*
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/{{ project_name }}.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/{{ project_name }}.qhc"
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/{{ project_name }}"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/{{ project_name }}"
@echo "# devhelp"
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
@echo "Run \`make' in that directory to run these through makeinfo" \
"(use \`make info' here to do that automatically)."
info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C $(BUILDDIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."
__init__.py 0000664 0000000 0000000 00000000121 12211653074 0027577 0 ustar 00root root 0000000 0000000 cloud-a8c081dc34c0e07b6655a89d68b2af3758203481-a8c081dc34c0e07b6655a89d68b2af3758203481/docs # Included so that Django's startproject comment runs against the docs directory
cloud-a8c081dc34c0e07b6655a89d68b2af3758203481-a8c081dc34c0e07b6655a89d68b2af3758203481/docs/conf.py0000664 0000000 0000000 00000017046 12211653074 0027062 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
#
# circle documentation build configuration file, created by
# sphinx-quickstart on Sun Feb 17 11:46:20 2013.
#
# This file is execfile()d with the current directory set to its containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys, os
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))
# -- General configuration -----------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = []
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'circle'
copyright = u'2013, ChangeMyName'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '0.1'
# The full version, including alpha/beta/rc tags.
release = '0.1'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['_build']
# The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# -- Options for HTML output ---------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = 'default'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# " v documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_domain_indices = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None
# Output file base name for HTML help builder.
htmlhelp_basename = 'circledoc'
# -- Options for LaTeX output --------------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#'preamble': '',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
('index', 'circle.tex', u'circle Documentation',
u'ChangeToMyName', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# If true, show page references after internal links.
#latex_show_pagerefs = False
# If true, show URL addresses after external links.
#latex_show_urls = False
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_domain_indices = True
# -- Options for manual page output --------------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'circle', u'circle Documentation',
[u'ChangeToMyName'], 1)
]
# If true, show URL addresses after external links.
#man_show_urls = False
# -- Options for Texinfo output ------------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
('index', 'circle', u'circle Documentation',
u'ChangeToMyName', 'circle', 'One line description of project.',
'Miscellaneous'),
]
# Documents to append as an appendix to all manuals.
#texinfo_appendices = []
# If false, no module index is generated.
#texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'
deploy.rst 0000664 0000000 0000000 00000000127 12211653074 0027522 0 ustar 00root root 0000000 0000000 cloud-a8c081dc34c0e07b6655a89d68b2af3758203481-a8c081dc34c0e07b6655a89d68b2af3758203481/docs Deploy
========
This is where you describe how the project is deployed in production.
index.rst 0000664 0000000 0000000 00000000676 12211653074 0027346 0 ustar 00root root 0000000 0000000 cloud-a8c081dc34c0e07b6655a89d68b2af3758203481-a8c081dc34c0e07b6655a89d68b2af3758203481/docs .. circle documentation master file, created by
sphinx-quickstart on Sun Feb 17 11:46:20 2013.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to circle's documentation!
====================================
Contents:
.. toctree::
:maxdepth: 2
install
deploy
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
install.rst 0000664 0000000 0000000 00000003014 12211653074 0027672 0 ustar 00root root 0000000 0000000 cloud-a8c081dc34c0e07b6655a89d68b2af3758203481-a8c081dc34c0e07b6655a89d68b2af3758203481/docs Install
=========
[ ! -e "$SSH_AUTH_SOCK" ] && echo "Please forward the SSH agent." && exit 1
# rabbitmq does not work with hostnames beginning w numbers
hostname=$(hostname)
case "$hostname" in
[0-9]*)
sudo tee /etc/hostname <<< c$hostname
sudo hostname c$hostname
sudo sed -i /etc/hosts -e "s/$hostname/c$hostname/g"
esac
sudo apt-get update
sudo apt-get install --yes virtualenvwrapper postgresql git \
python-pip rabbitmq-server libpq-dev python-dev
sudo sed -i /etc/postgresql/9.1/main/postgresql.conf -e '/#listen_addresses/ s/^#//'
sudo /etc/init.d/postgresql restart
sudo sed -i /etc/ssh/sshd_config -e '$ a AcceptEnv GIT_*'
sudo /etc/init.d/ssh reload
sudo -u postgres createuser -S -D -R circle
sudo -u postgres psql <<<"ALTER USER circle WITH PASSWORD 'circle';"
sudo -u postgres createdb circle -O circle
source /etc/bash_completion.d/virtualenvwrapper
git clone -b ng git@git.cloud.ik.bme.hu:circle/cloud.git circle
mkvirtualenv circle
cat >>/home/cloud/.virtualenvs/circle/bin/postactivate <