common.py 5.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
# Copyright 2014 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#
# CIRCLE is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CIRCLE is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE.  If not, see <http://www.gnu.org/licenses/>.

18
from __future__ import absolute_import, unicode_literals
19
from datetime import timedelta, datetime
20

21
from django.core.validators import MinValueValidator
22
from django.db.models import Model, CharField, IntegerField, permalink
23
from django.utils.translation import ugettext_lazy as _
24
from django.utils.timesince import timeuntil
25 26 27

from model_utils.models import TimeStampedModel

Őry Máté committed
28 29
from acl.models import AclBase

30 31 32 33 34 35 36 37 38 39 40

ARCHITECTURES = (('x86_64', 'x86-64 (64 bit)'),
                 ('i686', 'x86 (32 bit)'))


class BaseResourceConfigModel(Model):

    """Abstract base for models with base resource configuration parameters.
    """
    num_cores = IntegerField(verbose_name=_('number of cores'),
                             help_text=_('Number of virtual CPU cores '
41 42
                                         'available to the virtual machine.'),
                             validators=[MinValueValidator(0)])
43
    ram_size = IntegerField(verbose_name=_('RAM size'),
44 45
                            help_text=_('Mebibytes of memory.'),
                            validators=[MinValueValidator(0)])
46 47
    max_ram_size = IntegerField(verbose_name=_('maximal RAM size'),
                                help_text=_('Upper memory size limit '
48 49
                                            'for balloning.'),
                                validators=[MinValueValidator(0)])
50 51 52
    arch = CharField(max_length=10, verbose_name=_('architecture'),
                     choices=ARCHITECTURES)
    priority = IntegerField(verbose_name=_('priority'),
53 54
                            help_text=_('CPU priority.'),
                            validators=[MinValueValidator(0)])
55 56 57 58 59 60 61 62 63 64

    class Meta:
        abstract = True


class NamedBaseResourceConfig(BaseResourceConfigModel, TimeStampedModel):

    """Pre-created, named base resource configurations.
    """
    name = CharField(max_length=50, unique=True,
Bach Dániel committed
65 66
                     verbose_name=_('name'),
                     help_text=_('Name of base resource configuration.'))
67 68 69 70 71 72 73 74 75

    class Meta:
        app_label = 'vm'
        db_table = 'vm_namedbaseresourceconfig'

    def __unicode__(self):
        return self.name


Őry Máté committed
76
class Lease(AclBase):
77 78 79 80 81 82

    """Lease times for VM instances.

    Specifies a time duration until suspension and deletion of a VM
    instance.
    """
Őry Máté committed
83 84
    ACL_LEVELS = (
        ('user', _('user')),          # use this lease
85
        ('operator', _('operator')),  # share this lease
Őry Máté committed
86 87
        ('owner', _('owner')),        # change this lease
    )
88 89
    name = CharField(max_length=100, unique=True,
                     verbose_name=_('name'))
90 91 92 93 94 95 96 97
    suspend_interval_seconds = IntegerField(
        verbose_name=_('suspend interval'), help_text=_(
            'Number of seconds after the an instance is suspended.'),
        null=True, blank=True)
    delete_interval_seconds = IntegerField(
        verbose_name=_('delete interval'), help_text=_(
            'Number of seconds after the an instance is deleted.'),
        null=True, blank=True)
98 99 100 101 102

    class Meta:
        app_label = 'vm'
        db_table = 'vm_lease'
        ordering = ['name', ]
Őry Máté committed
103 104 105
        permissions = (
            ('create_leases', _('Can create new leases.')),
        )
106 107 108

    @property
    def suspend_interval(self):
109 110 111 112 113
        v = self.suspend_interval_seconds
        if v is not None:
            return timedelta(seconds=v)
        else:
            return None
114 115 116

    @suspend_interval.setter
    def suspend_interval(self, value):
117 118 119 120
        if value is not None:
            self.suspend_interval_seconds = value.total_seconds()
        else:
            self.suspend_interval_seconds = None
121 122 123

    @property
    def delete_interval(self):
124 125 126 127 128
        v = self.delete_interval_seconds
        if v is not None:
            return timedelta(seconds=v)
        else:
            return None
129 130 131

    @delete_interval.setter
    def delete_interval(self, value):
132 133 134 135
        if value is not None:
            self.delete_interval_seconds = value.total_seconds()
        else:
            self.delete_interval_seconds = None
136

137
    def get_readable_suspend_time(self):
138 139 140 141 142 143
        v = self.suspend_interval
        if v is not None:
            n = datetime.utcnow()
            return timeuntil(n + v, n)
        else:
            return _("never")
144 145

    def get_readable_delete_time(self):
146 147 148 149 150 151
        v = self.delete_interval
        if v is not None:
            n = datetime.utcnow()
            return timeuntil(n + v, n)
        else:
            return _("never")
152

153
    def __unicode__(self):
154 155 156 157
        return _("%(name)s (suspend: %(s)s, remove: %(r)s)") % {
            'name': self.name,
            's': self.get_readable_suspend_time(),
            'r': self.get_readable_delete_time()}
158

159 160 161 162
    @permalink
    def get_absolute_url(self):
        return ('dashboard.views.lease-detail', None, {'pk': self.pk})

163 164 165 166 167 168 169 170 171 172

class Trait(Model):
    name = CharField(max_length=50, verbose_name=_('name'))

    class Meta:
        app_label = 'vm'
        db_table = 'vm_trait'

    def __unicode__(self):
        return self.name