Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
Gutyán Gábor
/
circlestack
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
e5e57a40
authored
Sep 18, 2013
by
Őry Máté
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
vm: reformat models
parent
31196920
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
161 additions
and
108 deletions
+161
-108
circle/circle/settings/base.py
+3
-4
circle/vm/models.py
+158
-104
No files found.
circle/circle/settings/base.py
View file @
e5e57a40
...
@@ -298,8 +298,7 @@ CRISPY_TEMPLATE_PACK = 'bootstrap3'
...
@@ -298,8 +298,7 @@ CRISPY_TEMPLATE_PACK = 'bootstrap3'
# format: id: (name, port, protocol)
# format: id: (name, port, protocol)
VM_ACCESS_PROTOCOLS
=
loads
(
get_env_variable
(
'DJANGO_VM_ACCESS_PROTOCOLS'
,
VM_ACCESS_PROTOCOLS
=
loads
(
get_env_variable
(
'DJANGO_VM_ACCESS_PROTOCOLS'
,
'''{"nx": ["nx", 22, "tcp"],
'''{"nx": ["NX", 22, "tcp"],
"rdp": ["rdp", 3389, "tcp"],
"rdp": ["RDP", 3389, "tcp"],
"ssh": ["ssh", 22, "tcp"]}'''
))
"ssh": ["SSH", 22, "tcp"]}'''
))
VM_SCHEDULER
=
'manager.scheduler'
VM_SCHEDULER
=
'manager.scheduler'
circle/vm/models.py
View file @
e5e57a40
...
@@ -4,7 +4,9 @@ import logging
...
@@ -4,7 +4,9 @@ import logging
import
django.conf
import
django.conf
from
django.contrib.auth.models
import
User
from
django.contrib.auth.models
import
User
from
django.db
import
models
from
django.db.models
import
(
Model
,
ForeignKey
,
ManyToManyField
,
IntegerField
,
DateTimeField
,
BooleanField
,
TextField
,
CharField
,
permalink
)
from
django.db.models.signals
import
pre_delete
from
django.db.models.signals
import
pre_delete
from
django.dispatch
import
receiver
from
django.dispatch
import
receiver
from
django.utils
import
timezone
from
django.utils
import
timezone
...
@@ -22,22 +24,34 @@ logger = logging.getLogger(__name__)
...
@@ -22,22 +24,34 @@ logger = logging.getLogger(__name__)
pwgen
=
User
.
objects
.
make_random_password
pwgen
=
User
.
objects
.
make_random_password
scheduler
=
import_module
(
name
=
django
.
conf
.
settings
.
VM_SCHEDULER
)
scheduler
=
import_module
(
name
=
django
.
conf
.
settings
.
VM_SCHEDULER
)
ACCESS_PROTOCOLS
=
django
.
conf
.
settings
.
VM_ACCESS_PROTOCOLS
ACCESS_PROTOCOLS
=
django
.
conf
.
settings
.
VM_ACCESS_PROTOCOLS
ACCESS_METHODS
=
[(
k
,
ap
[
0
])
for
k
,
ap
in
ACCESS_PROTOCOLS
.
iteritems
()]
ACCESS_METHODS
=
[(
key
,
name
)
for
key
,
(
name
,
port
,
transport
)
in
ACCESS_PROTOCOLS
.
iteritems
()]
ARCHITECTURES
=
((
'x86_64'
,
'x86-64 (64 bit)'
),
(
'i686'
,
'x86 (32 bit)'
))
class
BaseResourceConfigModel
(
models
.
Model
):
class
BaseResourceConfigModel
(
Model
):
"""Abstract base class for models with base resource configuration
"""Abstract base class for models with base resource configuration
parameters.
parameters.
"""
"""
num_cores
=
models
.
IntegerField
(
help_text
=
_
(
'Number of CPU cores.'
))
num_cores
=
IntegerField
(
verbose_name
=
_
(
'number of cores'
),
ram_size
=
models
.
IntegerField
(
help_text
=
_
(
'Mebibytes of memory.'
))
help_text
=
_
(
'Number of virtual CPU cores '
max_ram_size
=
models
.
IntegerField
(
help_text
=
_
(
'Upper memory size limit '
'available to the virtual machine.'
))
'for balloning.'
))
ram_size
=
IntegerField
(
verbose_name
=
_
(
'RAM size'
),
arch
=
models
.
CharField
(
max_length
=
10
,
verbose_name
=
_
(
'architecture'
))
help_text
=
_
(
'Mebibytes of memory.'
))
priority
=
models
.
IntegerField
(
help_text
=
_
(
'instance priority'
))
max_ram_size
=
IntegerField
(
verbose_name
=
_
(
'maximal RAM size'
),
boot_menu
=
models
.
BooleanField
(
default
=
False
)
help_text
=
_
(
'Upper memory size limit '
raw_data
=
models
.
TextField
(
blank
=
True
)
'for balloning.'
))
arch
=
CharField
(
max_length
=
10
,
verbose_name
=
_
(
'architecture'
),
choices
=
ARCHITECTURES
)
priority
=
IntegerField
(
verbose_name
=
_
(
'priority'
),
help_text
=
_
(
'CPU priority.'
))
boot_menu
=
BooleanField
(
verbose_name
=
_
(
'boot menu'
),
default
=
False
,
help_text
=
_
(
'Show boot device selection menu on boot.'
))
raw_data
=
TextField
(
verbose_name
=
_
(
'raw_data'
),
blank
=
True
,
help_text
=
_
(
'Additional libvirt domain parameters in XML format.'
))
class
Meta
:
class
Meta
:
abstract
=
True
abstract
=
True
...
@@ -47,8 +61,9 @@ class NamedBaseResourceConfig(BaseResourceConfigModel, TimeStampedModel):
...
@@ -47,8 +61,9 @@ class NamedBaseResourceConfig(BaseResourceConfigModel, TimeStampedModel):
"""Pre-created, named base resource configurations.
"""Pre-created, named base resource configurations.
"""
"""
name
=
models
.
CharField
(
max_length
=
50
,
unique
=
True
,
name
=
CharField
(
max_length
=
50
,
unique
=
True
,
verbose_name
=
_
(
'name'
))
verbose_name
=
_
(
'name'
),
help_text
=
_
(
'Name of base resource configuration.'
))
def
__unicode__
(
self
):
def
__unicode__
(
self
):
return
self
.
name
return
self
.
name
...
@@ -56,17 +71,23 @@ class NamedBaseResourceConfig(BaseResourceConfigModel, TimeStampedModel):
...
@@ -56,17 +71,23 @@ class NamedBaseResourceConfig(BaseResourceConfigModel, TimeStampedModel):
class
Node
(
TimeStampedModel
):
class
Node
(
TimeStampedModel
):
"""A VM host machine.
"""A VM host machine
, a hypervisor
.
"""
"""
name
=
models
.
CharField
(
max_length
=
50
,
unique
=
True
,
name
=
CharField
(
max_length
=
50
,
unique
=
True
,
verbose_name
=
_
(
'name'
))
verbose_name
=
_
(
'name'
),
num_cores
=
models
.
IntegerField
(
help_text
=
_
(
'Number of CPU cores.'
))
help_text
=
_
(
'Human readable name of node.'
))
ram_size
=
models
.
IntegerField
(
help_text
=
_
(
'Mebibytes of memory.'
))
num_cores
=
IntegerField
(
verbose_name
=
_
(
'number of cores'
),
priority
=
models
.
IntegerField
(
help_text
=
_
(
'node usage priority'
))
help_text
=
_
(
'Number of CPU threads '
host
=
models
.
ForeignKey
(
Host
)
'available to the virtual machines.'
))
enabled
=
models
.
BooleanField
(
default
=
False
,
ram_size
=
IntegerField
(
verbose_name
=
_
(
'RAM size'
),
help_text
=
_
(
'Indicates whether the node can '
help_text
=
_
(
'Mebibytes of memory.'
))
'be used for hosting.'
))
priority
=
IntegerField
(
verbose_name
=
_
(
'priority'
),
help_text
=
_
(
'Node usage priority.'
))
host
=
ForeignKey
(
Host
,
verbose_name
=
_
(
'host'
),
help_text
=
_
(
'Host in firewall.'
))
enabled
=
BooleanField
(
verbose_name
=
_
(
'enabled'
),
default
=
False
,
help_text
=
_
(
'Indicates whether the node can '
'be used for hosting.'
))
class
Meta
:
class
Meta
:
permissions
=
()
permissions
=
()
...
@@ -82,28 +103,39 @@ class Node(TimeStampedModel):
...
@@ -82,28 +103,39 @@ class Node(TimeStampedModel):
class
NodeActivity
(
TimeStampedModel
):
class
NodeActivity
(
TimeStampedModel
):
activity_code
=
models
.
CharField
(
max_length
=
100
)
activity_code
=
CharField
(
verbose_name
=
_
(
'activity code'
),
task_uuid
=
models
.
CharField
(
blank
=
True
,
max_length
=
50
,
null
=
True
,
max_length
=
100
)
# TODO
unique
=
True
)
task_uuid
=
CharField
(
verbose_name
=
_
(
'task_uuid'
),
blank
=
True
,
node
=
models
.
ForeignKey
(
Node
,
related_name
=
'activity_log'
)
max_length
=
50
,
null
=
True
,
unique
=
True
,
help_text
=
_
(
user
=
models
.
ForeignKey
(
User
,
blank
=
True
,
null
=
True
)
'Celery task unique identifier.'
))
started
=
models
.
DateTimeField
(
blank
=
True
,
null
=
True
)
node
=
ForeignKey
(
Node
,
verbose_name
=
_
(
'node'
),
finished
=
models
.
DateTimeField
(
blank
=
True
,
null
=
True
)
related_name
=
'activity_log'
,
result
=
models
.
TextField
(
blank
=
True
,
null
=
True
)
help_text
=
_
(
'Node this activity works on.'
))
status
=
models
.
CharField
(
default
=
'PENDING'
,
max_length
=
50
)
user
=
ForeignKey
(
User
,
verbose_name
=
_
(
'user'
),
blank
=
True
,
null
=
True
,
help_text
=
_
(
'The person who started this activity.'
))
started
=
DateTimeField
(
verbose_name
=
_
(
'started at'
),
class
Lease
(
models
.
Model
):
blank
=
True
,
null
=
True
,
help_text
=
_
(
'Time of activity initiation.'
))
finished
=
DateTimeField
(
verbose_name
=
_
(
'finished at'
),
blank
=
True
,
null
=
True
,
help_text
=
_
(
'Time of activity finalization.'
))
result
=
TextField
(
verbose_name
=
_
(
'result'
),
blank
=
True
,
null
=
True
,
help_text
=
_
(
'Human readable result of activity.'
))
status
=
CharField
(
verbose_name
=
_
(
'status'
),
default
=
'PENDING'
,
max_length
=
50
,
help_text
=
_
(
'Actual state of activity'
))
class
Lease
(
Model
):
"""Lease times for VM instances.
"""Lease times for VM instances.
Specifies a time duration until suspension and deletion of a VM
Specifies a time duration until suspension and deletion of a VM
instance.
instance.
"""
"""
name
=
models
.
CharField
(
max_length
=
100
,
unique
=
True
,
name
=
CharField
(
max_length
=
100
,
unique
=
True
,
verbose_name
=
_
(
'name'
))
verbose_name
=
_
(
'name'
))
suspend_interval_seconds
=
models
.
IntegerField
(
)
suspend_interval_seconds
=
IntegerField
(
verbose_name
=
_
(
'suspend interval'
)
)
delete_interval_seconds
=
models
.
IntegerField
(
)
delete_interval_seconds
=
IntegerField
(
verbose_name
=
_
(
'delete interval'
)
)
class
Meta
:
class
Meta
:
ordering
=
[
'name'
,
]
ordering
=
[
'name'
,
]
...
@@ -144,27 +176,31 @@ class InstanceTemplate(BaseResourceConfigModel, TimeStampedModel):
...
@@ -144,27 +176,31 @@ class InstanceTemplate(BaseResourceConfigModel, TimeStampedModel):
* lease times (suspension & deletion)
* lease times (suspension & deletion)
* time of creation and last modification
* time of creation and last modification
"""
"""
STATES
=
[(
'NEW'
,
_
(
'new'
)),
# template has just been created
STATES
=
[(
'NEW'
,
_
(
'new'
)),
# template has just been created
(
'SAVING'
,
_
(
'saving'
)),
# changes are being saved
(
'SAVING'
,
_
(
'saving'
)),
# changes are being saved
(
'READY'
,
_
(
'ready'
))]
# template is ready for instantiation
(
'READY'
,
_
(
'ready'
))]
# template is ready for instantiation
name
=
models
.
CharField
(
max_length
=
100
,
unique
=
True
,
name
=
CharField
(
max_length
=
100
,
unique
=
True
,
verbose_name
=
_
(
'name'
))
verbose_name
=
_
(
'name'
),
description
=
models
.
TextField
(
verbose_name
=
_
(
'description'
),
help_text
=
_
(
'Human readable name of template.'
))
blank
=
True
)
description
=
TextField
(
verbose_name
=
_
(
'description'
),
blank
=
True
)
parent
=
models
.
ForeignKey
(
'self'
,
null
=
True
,
blank
=
True
,
parent
=
ForeignKey
(
'self'
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'parent template'
))
verbose_name
=
_
(
'parent template'
),
system
=
models
.
TextField
(
verbose_name
=
_
(
'operating system'
),
help_text
=
_
(
'Template which this one is derived of.'
))
blank
=
True
,
system
=
TextField
(
verbose_name
=
_
(
'operating system'
),
help_text
=
(
_
(
'Name of operating system in '
blank
=
True
,
'format like "
%
s".'
)
%
help_text
=
(
_
(
'Name of operating system in '
'Ubuntu 12.04 LTS Desktop amd64'
))
'format like "
%
s".'
)
%
access_method
=
models
.
CharField
(
max_length
=
10
,
choices
=
ACCESS_METHODS
,
'Ubuntu 12.04 LTS Desktop amd64'
))
verbose_name
=
_
(
'access method'
))
access_method
=
CharField
(
max_length
=
10
,
choices
=
ACCESS_METHODS
,
state
=
models
.
CharField
(
max_length
=
10
,
choices
=
STATES
,
verbose_name
=
_
(
'access method'
),
default
=
'NEW'
)
help_text
=
_
(
'Primary remote access method.'
))
disks
=
models
.
ManyToManyField
(
Disk
,
verbose_name
=
_
(
'disks'
),
state
=
CharField
(
max_length
=
10
,
choices
=
STATES
,
default
=
'NEW'
)
related_name
=
'template_set'
)
disks
=
ManyToManyField
(
Disk
,
verbose_name
=
_
(
'disks'
),
lease
=
models
.
ForeignKey
(
Lease
,
related_name
=
'template_set'
)
related_name
=
'template_set'
,
help_text
=
_
(
'Disks which are to be mounted.'
))
lease
=
ForeignKey
(
Lease
,
related_name
=
'template_set'
,
verbose_name
=
_
(
'lease'
),
help_text
=
_
(
'Expiration times.'
))
class
Meta
:
class
Meta
:
ordering
=
[
'name'
,
]
ordering
=
[
'name'
,
]
...
@@ -190,16 +226,20 @@ class InstanceTemplate(BaseResourceConfigModel, TimeStampedModel):
...
@@ -190,16 +226,20 @@ class InstanceTemplate(BaseResourceConfigModel, TimeStampedModel):
return
'linux'
return
'linux'
class
InterfaceTemplate
(
models
.
Model
):
class
InterfaceTemplate
(
Model
):
"""Network interface template for an instance template.
"""Network interface template for an instance template.
If the interface is managed, a host will be created for it.
If the interface is managed, a host will be created for it.
"""
"""
vlan
=
models
.
ForeignKey
(
Vlan
)
vlan
=
ForeignKey
(
Vlan
,
verbose_name
=
_
(
'vlan'
),
managed
=
models
.
BooleanField
(
default
=
True
)
help_text
=
_
(
'Network the interface belongs to.'
))
template
=
models
.
ForeignKey
(
InstanceTemplate
,
managed
=
BooleanField
(
verbose_name
=
_
(
'managed'
),
default
=
True
,
related_name
=
'interface_set'
)
help_text
=
_
(
'If a firewall host (i.e. IP address '
'association) should be generated.'
))
template
=
ForeignKey
(
InstanceTemplate
,
verbose_name
=
_
(
'template'
),
related_name
=
'interface_set'
,
help_text
=
_
())
class
Meta
:
class
Meta
:
permissions
=
()
permissions
=
()
...
@@ -233,32 +273,42 @@ class Instance(BaseResourceConfigModel, TimeStampedModel):
...
@@ -233,32 +273,42 @@ class Instance(BaseResourceConfigModel, TimeStampedModel):
(
'SHUTOFF'
,
_
(
'shutoff'
)),
(
'SHUTOFF'
,
_
(
'shutoff'
)),
(
'CRASHED'
,
_
(
'crashed'
)),
(
'CRASHED'
,
_
(
'crashed'
)),
(
'PMSUSPENDED'
,
_
(
'pmsuspended'
))]
# libvirt domain states
(
'PMSUSPENDED'
,
_
(
'pmsuspended'
))]
# libvirt domain states
name
=
models
.
CharField
(
blank
=
True
,
max_length
=
100
,
verbose_name
=
_
(
'name'
))
name
=
CharField
(
blank
=
True
,
max_length
=
100
,
verbose_name
=
_
(
'name'
),
description
=
models
.
TextField
(
blank
=
True
,
verbose_name
=
_
(
'description'
))
help_text
=
_
(
'Human readable name of instance.'
))
template
=
models
.
ForeignKey
(
InstanceTemplate
,
blank
=
True
,
null
=
True
,
description
=
TextField
(
blank
=
True
,
verbose_name
=
_
(
'description'
))
related_name
=
'instance_set'
,
template
=
ForeignKey
(
InstanceTemplate
,
blank
=
True
,
null
=
True
,
verbose_name
=
_
(
'template'
))
related_name
=
'instance_set'
,
pw
=
models
.
CharField
(
help_text
=
_
(
'Original password of instance'
),
help_text
=
_
(
'Template the instance derives from.'
),
max_length
=
20
,
verbose_name
=
_
(
'password'
))
verbose_name
=
_
(
'template'
))
time_of_suspend
=
models
.
DateTimeField
(
blank
=
True
,
default
=
None
,
null
=
True
,
pw
=
CharField
(
help_text
=
_
(
'Original password of the instance.'
),
verbose_name
=
_
(
'time of suspend'
))
max_length
=
20
,
verbose_name
=
_
(
'password'
))
time_of_delete
=
models
.
DateTimeField
(
blank
=
True
,
default
=
None
,
null
=
True
,
time_of_suspend
=
DateTimeField
(
blank
=
True
,
default
=
None
,
null
=
True
,
verbose_name
=
_
(
'time of delete'
))
verbose_name
=
_
(
'time of suspend'
),
active_since
=
models
.
DateTimeField
(
blank
=
True
,
null
=
True
,
help_text
=
_
(
'Proposed time of automatic '
help_text
=
_
(
'Time stamp of successful '
'suspension.'
))
'boot report.'
),
time_of_delete
=
DateTimeField
(
blank
=
True
,
default
=
None
,
null
=
True
,
verbose_name
=
_
(
'active since'
))
verbose_name
=
_
(
'time of delete'
),
node
=
models
.
ForeignKey
(
Node
,
blank
=
True
,
null
=
True
,
help_text
=
_
(
'Proposed time of automatic '
related_name
=
'instance_set'
,
'suspension.'
))
verbose_name
=
_
(
'host node'
))
active_since
=
DateTimeField
(
blank
=
True
,
null
=
True
,
state
=
models
.
CharField
(
choices
=
STATES
,
default
=
'NOSTATE'
,
max_length
=
20
)
help_text
=
_
(
'Time stamp of successful '
disks
=
models
.
ManyToManyField
(
Disk
,
related_name
=
'instance_set'
,
'boot report.'
),
verbose_name
=
_
(
'disks'
))
verbose_name
=
_
(
'active since'
))
lease
=
models
.
ForeignKey
(
Lease
)
node
=
ForeignKey
(
Node
,
blank
=
True
,
null
=
True
,
access_method
=
models
.
CharField
(
max_length
=
10
,
choices
=
ACCESS_METHODS
,
related_name
=
'instance_set'
,
verbose_name
=
_
(
'access method'
))
help_text
=
_
(
'Current hypervisor of this instance.'
),
vnc_port
=
models
.
IntegerField
()
verbose_name
=
_
(
'host node'
))
owner
=
models
.
ForeignKey
(
User
)
state
=
CharField
(
choices
=
STATES
,
default
=
'NOSTATE'
,
max_length
=
20
)
disks
=
ManyToManyField
(
Disk
,
related_name
=
'instance_set'
,
help_text
=
_
(
'Set of mounted disks.'
),
verbose_name
=
_
(
'disks'
))
lease
=
ForeignKey
(
Lease
,
help_text
=
_
(
'Preferred expiration periods.'
))
access_method
=
CharField
(
max_length
=
10
,
choices
=
ACCESS_METHODS
,
help_text
=
_
(
'Primary remote access method.'
),
verbose_name
=
_
(
'access method'
))
vnc_port
=
IntegerField
(
verbose_name
=
_
(
'vnc_port'
),
help_text
=
_
(
'TCP port where VNC console listens.'
))
owner
=
ForeignKey
(
User
)
class
Meta
:
class
Meta
:
ordering
=
[
'pk'
,
]
ordering
=
[
'pk'
,
]
...
@@ -307,7 +357,7 @@ class Instance(BaseResourceConfigModel, TimeStampedModel):
...
@@ -307,7 +357,7 @@ class Instance(BaseResourceConfigModel, TimeStampedModel):
return
inst
return
inst
@
models.
permalink
@permalink
def
get_absolute_url
(
self
):
def
get_absolute_url
(
self
):
return
(
'dashboard.views.detail'
,
None
,
{
'id'
:
self
.
id
})
return
(
'dashboard.views.detail'
,
None
,
{
'id'
:
self
.
id
})
...
@@ -560,15 +610,17 @@ def delete_instance_pre(sender, instance, using, **kwargs):
...
@@ -560,15 +610,17 @@ def delete_instance_pre(sender, instance, using, **kwargs):
class
InstanceActivity
(
TimeStampedModel
):
class
InstanceActivity
(
TimeStampedModel
):
activity_code
=
models
.
CharField
(
max_length
=
100
)
activity_code
=
CharField
(
verbose_name
=
_
(
'activity_code'
),
max_length
=
100
)
task_uuid
=
models
.
CharField
(
blank
=
True
,
max_length
=
50
,
null
=
True
,
task_uuid
=
CharField
(
verbose_name
=
_
(
'task_uuid'
),
blank
=
True
,
unique
=
True
)
max_length
=
50
,
null
=
True
,
unique
=
True
)
instance
=
models
.
ForeignKey
(
Instance
,
related_name
=
'activity_log'
)
instance
=
ForeignKey
(
Instance
,
verbose_name
=
_
(
'instance'
),
user
=
models
.
ForeignKey
(
User
,
blank
=
True
,
null
=
True
)
related_name
=
'activity_log'
)
started
=
models
.
DateTimeField
(
blank
=
True
,
null
=
True
)
user
=
ForeignKey
(
User
,
verbose_name
=
_
(
'user'
),
blank
=
True
,
null
=
True
)
finished
=
models
.
DateTimeField
(
blank
=
True
,
null
=
True
)
started
=
DateTimeField
(
verbose_name
=
_
(
'started'
),
blank
=
True
,
null
=
True
)
result
=
models
.
TextField
(
blank
=
True
,
null
=
True
)
finished
=
DateTimeField
(
verbose_name
=
_
(
'finished'
),
blank
=
True
,
null
=
True
)
state
=
models
.
CharField
(
default
=
'PENDING'
,
max_length
=
50
)
result
=
TextField
(
verbose_name
=
_
(
'result'
),
blank
=
True
,
null
=
True
)
state
=
CharField
(
verbose_name
=
_
(
'state'
),
default
=
'PENDING'
,
max_length
=
50
)
def
update_state
(
self
,
new_state
):
def
update_state
(
self
,
new_state
):
self
.
state
=
new_state
self
.
state
=
new_state
...
@@ -581,13 +633,15 @@ class InstanceActivity(TimeStampedModel):
...
@@ -581,13 +633,15 @@ class InstanceActivity(TimeStampedModel):
self
.
save
()
self
.
save
()
class
Interface
(
models
.
Model
):
class
Interface
(
Model
):
"""Network interface for an instance.
"""Network interface for an instance.
"""
"""
vlan
=
models
.
ForeignKey
(
Vlan
,
related_name
=
"vm_interface"
)
vlan
=
ForeignKey
(
Vlan
,
verbose_name
=
_
(
'vlan'
),
host
=
models
.
ForeignKey
(
Host
,
blank
=
True
,
null
=
True
)
related_name
=
"vm_interface"
)
instance
=
models
.
ForeignKey
(
Instance
,
related_name
=
'interface_set'
)
host
=
ForeignKey
(
Host
,
verbose_name
=
_
(
'host'
),
blank
=
True
,
null
=
True
)
instance
=
ForeignKey
(
Instance
,
verbose_name
=
_
(
'instance'
),
related_name
=
'interface_set'
)
@property
@property
def
mac
(
self
):
def
mac
(
self
):
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment