Commit 0922f8ec by Karsa Zoltán István

cloud init integration init

parent 4d9aea69
......@@ -544,7 +544,7 @@ class TemplateForm(forms.ModelForm):
else:
self.allowed_fields = (
'name', 'access_method', 'description', 'system', 'tags',
'arch', 'lease', 'has_agent')
'arch', 'lease', 'has_agent', 'cloud_init', 'ci_user_data', 'ci_meta_data')
if (self.user.has_perm('vm.change_template_resources') or
not self.instance.pk):
self.allowed_fields += tuple(set(self.fields.keys()) -
......@@ -1533,6 +1533,25 @@ class RawDataForm(forms.ModelForm):
return helper
class CIDataForm(forms.ModelForm):
ci_meta_data = forms.CharField(disabled=True, help_text='meta-data',
widget=forms.Textarea(attrs={'rows': 5}),
required=False)
ci_user_data = forms.CharField(disabled=True, help_text='user-data',
widget=forms.Textarea(attrs={'rows': 5}),
required=False)
class Meta:
model = Instance
fields = ('ci_meta_data', 'ci_user_data',)
@property
def helper(self):
helper = FormHelper()
helper.form_show_labels = False
return helper
class GroupPermissionForm(forms.ModelForm):
permissions = forms.ModelMultipleChoiceField(
queryset=None,
......
......@@ -26,6 +26,11 @@
{{ form.req_traits|as_crispy_field }}
{{ form.description|as_crispy_field }}
{{ form.system|as_crispy_field }}
<hr/>
{{ form.cloud_init|as_crispy_field }}
{{ form.ci_meta_data|as_crispy_field }}
{{ form.ci_user_data|as_crispy_field }}
</fieldset>
<fieldset>
<legend>{% trans "External resources" %}</legend>
......
......@@ -79,6 +79,22 @@
</div>
{% endif %}
<hr />
{% if instance.cloud_init %}
<div class="row">
<div class="col-sm-12">
<h3>
{% trans "Cloud-init" %}
</h3>
{% crispy ci_data %}
</div>
</div>
{% endif %}
{% if user.is_superuser %}
<hr/>
......
......@@ -164,10 +164,18 @@ class TemplateCreate(SuccessMessageMixin, CreateView):
tags = post.pop("tags")
post['pw'] = User.objects.make_random_password()
post['is_base'] = True
inst = Instance.create(params=post, disks=[],
networks=networks,
tags=tags, req_traits=req_traits)
if post['cloud_init']:
disk = Disk.create_ci_disk(meta_data=post['ci_meta_data'], user_data=post['ci_user_data'], user=request.user)
disk.full_clean()
disk.save()
inst.disks.add(disk)
return HttpResponseRedirect("%s#resources" %
inst.get_absolute_url())
......
......@@ -60,7 +60,7 @@ from .util import (
TransferOwnershipConfirmView, TransferOwnershipView,
)
from ..forms import (
AclUserOrGroupAddForm, VmResourcesForm, TraitsForm, RawDataForm,
AclUserOrGroupAddForm, CIDataForm, VmResourcesForm, TraitsForm, RawDataForm,
VmAddInterfaceForm, VmCreateDiskForm, VmDownloadDiskForm,
VmImportDiskForm, VmSaveForm,
VmRenewForm, VmStateChangeForm, VmListSearchForm, VmCustomizeForm,
......@@ -204,6 +204,8 @@ class VmDetailView(GraphMixin, CheckedDetailView):
"PENDING",
)
context['ci_data'] = CIDataForm(instance=instance)
return context
def post(self, request, *args, **kwargs):
......
# Generated by Django 3.2.3 on 2022-07-20 12:54
from django.db import migrations, models
import firewall.fields
class Migration(migrations.Migration):
dependencies = [
('firewall', '0007_auto_20211102_1331'),
]
operations = [
migrations.AlterField(
model_name='vlan',
name='ipv6_template',
field=models.TextField(blank=True, help_text='Template for translating IPv4 addresses to IPv6. Automatically generated hosts in dual-stack networks will get this address. The template can contain four tokens: "%(a)d", "%(b)d", "%(c)d", and "%(d)d", representing the four unicode of the IPv4 address, respectively, in decimal notation. Moreover you can use any standard printf format specification like %(a)02x to get the first byte as two hexadecimal digits. Usual choices for mapping 198.51.100.0/24 to 2001:0DB8:1:1::/64 would be "2001:db8:1:1:%(d)d::" and "2001:db8:1:1:%(d)02x00::".', validators=[firewall.fields.val_ipv6_template], verbose_name='ipv6 template'),
),
migrations.AlterField(
model_name='vlan',
name='reverse_domain',
field=models.TextField(default='%(d)d.%(c)d.%(b)d.%(a)d.in-addr.arpa', help_text='Template of the IPv4 reverse domain name that should be generated for each host. The template should contain four tokens: "%(a)d", "%(b)d", "%(c)d", and "%(d)d", representing the four unicode of the address, respectively, in decimal notation. For example, the template for the standard reverse address is: "%(d)d.%(c)d.%(b)d.%(a)d.in-addr.arpa".', validators=[firewall.fields.val_reverse_domain], verbose_name='reverse domain'),
),
]
......@@ -448,6 +448,21 @@ class Disk(TimeStampedModel):
return result
@classmethod
def create_ci_disk(cls, meta_data, user_data, user = None, **params):
params.setdefault('name', 'ci-disk')
params.setdefault('type', 'iso')
params.setdefault('size', 200)
disk = cls.__create(params=params, user=user)
queue_name = disk.get_remote_queue_name('storage', priority="fast")
disk_desc = disk.get_disk_desc()
storage_tasks.create_ci_disk.apply_async(args=[disk_desc, user_data, meta_data],
queue=queue_name
).get(timeout=15)
disk.is_ready = True
disk.save()
return disk
@classmethod
def download(cls, url, task, user=None, **params):
"""Create disk object and download data from url synchronusly.
......
......@@ -33,6 +33,11 @@ def create(disk_desc):
pass
@celery.task(name='storagedriver.create_ci_disk')
def create_ci_disk(disk_desc, meta_data, user_data):
pass
@celery.task(name='storagedriver.download')
def download(disk_desc, url):
pass
......
# Generated by Django 3.2.3 on 2022-07-20 12:54
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('vm', '0005_auto_20211119_1017'),
]
operations = [
migrations.AddField(
model_name='instance',
name='ci_meta_data',
field=models.TextField(blank=True, help_text='When cloud-init is active, set meta-data oprtions (YAML format)', verbose_name='ci_meta_data'),
),
migrations.AddField(
model_name='instance',
name='ci_user_data',
field=models.TextField(blank=True, help_text='When cloud-init is active, set user-data oprtions (YAML format)', verbose_name='ci_user_data'),
),
migrations.AddField(
model_name='instancetemplate',
name='ci_meta_data',
field=models.TextField(blank=True, help_text='When cloud-init is active, set meta-data oprtions (YAML format)', verbose_name='ci_meta_data'),
),
migrations.AddField(
model_name='instancetemplate',
name='ci_user_data',
field=models.TextField(blank=True, help_text='When cloud-init is active, set user-data oprtions (YAML format)', verbose_name='ci_user_data'),
),
]
# Generated by Django 3.2.3 on 2022-07-20 13:12
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('vm', '0006_auto_20220720_1254'),
]
operations = [
migrations.AddField(
model_name='instance',
name='cloud_init',
field=models.BooleanField(default=True, help_text='VM use cloud-init, set user- and meta-data below', verbose_name='Use Cloud-init'),
),
migrations.AddField(
model_name='instancetemplate',
name='cloud_init',
field=models.BooleanField(default=True, help_text='VM use cloud-init, set user- and meta-data below', verbose_name='Use Cloud-init'),
),
migrations.AlterField(
model_name='instance',
name='ci_meta_data',
field=models.TextField(blank=True, help_text='When cloud-init is active, set meta-data (YAML format)', verbose_name='ci_meta_data'),
),
migrations.AlterField(
model_name='instance',
name='ci_user_data',
field=models.TextField(blank=True, help_text='When cloud-init is active, set user-data (YAML format)', verbose_name='ci_user_data'),
),
migrations.AlterField(
model_name='instancetemplate',
name='ci_meta_data',
field=models.TextField(blank=True, help_text='When cloud-init is active, set meta-data (YAML format)', verbose_name='ci_meta_data'),
),
migrations.AlterField(
model_name='instancetemplate',
name='ci_user_data',
field=models.TextField(blank=True, help_text='When cloud-init is active, set user-data (YAML format)', verbose_name='ci_user_data'),
),
]
......@@ -22,6 +22,7 @@ from functools import partial
from importlib import import_module
from logging import getLogger
from warnings import warn
from xml.dom.minidom import Text
import django.conf
from django.contrib.auth.models import User
......@@ -112,6 +113,13 @@ class VirtualMachineDescModel(BaseResourceConfigModel):
verbose_name=_("Lease"), on_delete=models.CASCADE)
raw_data = TextField(verbose_name=_('raw_data'), blank=True, help_text=_(
'Additional libvirt domain parameters in XML format.'))
cloud_init = BooleanField(verbose_name=_('Use Cloud-init'), default=False,
help_text=_(
'VM use cloud-init, set user- and meta-data below'))
ci_meta_data = TextField(verbose_name=_('ci_meta_data'), blank=True, help_text=_(
'When cloud-init is active, set meta-data (YAML format)'))
ci_user_data = TextField(verbose_name=_('ci_user_data'), blank=True, help_text=_(
'When cloud-init is active, set user-data (YAML format)'))
req_traits = ManyToManyField(Trait, blank=True,
help_text=_("A set of traits required for a "
"node to declare to be suitable "
......
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 sign in to comment