Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
CIRCLE3
/
cloud
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
5
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
A prog2-höz tartozó friss repo anyagok itt elérhetőek:
https://git.iit.bme.hu/
Commit
6d803ade
authored
Oct 06, 2022
by
Karsa Zoltán István
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
network config for cloud-init
parent
b2ed9564
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
142 additions
and
14 deletions
+142
-14
circle/dashboard/forms.py
+6
-2
circle/dashboard/static/dashboard/dashboard.css
+6
-0
circle/dashboard/static/dashboard/dashboard.less
+7
-0
circle/dashboard/static/dashboard/vm-details.js
+12
-1
circle/dashboard/templates/dashboard/_template-create.html
+1
-0
circle/dashboard/templates/dashboard/vm-detail/cloudinit.html
+3
-0
circle/dashboard/validators.py
+17
-0
circle/storage/models.py
+2
-2
circle/storage/tasks/storage_tasks.py
+1
-1
circle/vm/migrations/0012_auto_20221006_1433.py
+23
-0
circle/vm/migrations/0013_auto_20221006_1509.py
+23
-0
circle/vm/models/instance.py
+32
-4
circle/vm/operations.py
+9
-4
No files found.
circle/dashboard/forms.py
View file @
6d803ade
...
@@ -60,7 +60,7 @@ from vm.models import (
...
@@ -60,7 +60,7 @@ from vm.models import (
InstanceTemplate
,
Lease
,
InterfaceTemplate
,
Node
,
Trait
,
Instance
InstanceTemplate
,
Lease
,
InterfaceTemplate
,
Node
,
Trait
,
Instance
)
)
from
.models
import
Profile
,
GroupProfile
,
Message
from
.models
import
Profile
,
GroupProfile
,
Message
from
.validators
import
domain_validator
,
meta_data_validator
,
user_data_validator
from
.validators
import
domain_validator
,
meta_data_validator
,
user_data_validator
,
network_data_validator
LANGUAGES_WITH_CODE
=
((
l
[
0
],
format_lazy
(
"{} ({})"
,
l
[
1
],
l
[
0
]))
LANGUAGES_WITH_CODE
=
((
l
[
0
],
format_lazy
(
"{} ({})"
,
l
[
1
],
l
[
0
]))
for
l
in
LANGUAGES
)
for
l
in
LANGUAGES
)
...
@@ -1540,16 +1540,20 @@ class CIDataForm(forms.ModelForm):
...
@@ -1540,16 +1540,20 @@ class CIDataForm(forms.ModelForm):
ci_user_data
=
forms
.
CharField
(
ci_user_data
=
forms
.
CharField
(
widget
=
forms
.
Textarea
(
attrs
=
{
'rows'
:
12
,
'style'
:
'display:none;'
}),
widget
=
forms
.
Textarea
(
attrs
=
{
'rows'
:
12
,
'style'
:
'display:none;'
}),
required
=
False
)
required
=
False
)
ci_network_config
=
forms
.
CharField
(
widget
=
forms
.
Textarea
(
attrs
=
{
'rows'
:
5
,
'style'
:
'display:none;'
}),
required
=
False
)
def
clean
(
self
):
def
clean
(
self
):
data
=
self
.
cleaned_data
data
=
self
.
cleaned_data
meta_data_validator
(
self
.
instance
,
data
[
'ci_meta_data'
])
meta_data_validator
(
self
.
instance
,
data
[
'ci_meta_data'
])
user_data_validator
(
self
.
instance
,
data
[
'ci_user_data'
])
user_data_validator
(
self
.
instance
,
data
[
'ci_user_data'
])
network_data_validator
(
self
.
instance
,
data
[
'ci_network_config'
])
return
super
()
.
clean
()
return
super
()
.
clean
()
class
Meta
:
class
Meta
:
model
=
Instance
model
=
Instance
fields
=
(
'ci_meta_data'
,
'ci_user_data'
,)
fields
=
(
'ci_meta_data'
,
'ci_user_data'
,
'ci_network_config'
,
)
class
GroupPermissionForm
(
forms
.
ModelForm
):
class
GroupPermissionForm
(
forms
.
ModelForm
):
...
...
circle/dashboard/static/dashboard/dashboard.css
View file @
6d803ade
...
@@ -1374,3 +1374,8 @@ textarea[name="new_members"] {
...
@@ -1374,3 +1374,8 @@ textarea[name="new_members"] {
width
:
95%
;
width
:
95%
;
height
:
350px
;
height
:
350px
;
}
}
#ace-network-data
{
position
:
absolute
;
width
:
95%
;
height
:
150px
;
}
\ No newline at end of file
circle/dashboard/static/dashboard/dashboard.less
View file @
6d803ade
...
@@ -1607,4 +1607,10 @@ textarea[name="new_members"] {
...
@@ -1607,4 +1607,10 @@ textarea[name="new_members"] {
position: absolute;
position: absolute;
width: 95%;
width: 95%;
height: 350px;
height: 350px;
}
#ace-network-data {
position: absolute;
width: 95%;
height: 150px;
}
}
\ No newline at end of file
circle/dashboard/static/dashboard/vm-details.js
View file @
6d803ade
var
Websock_native
;
// not sure
var
Websock_native
;
// not sure
$
(
function
()
{
$
(
function
()
{
if
(
$
(
"#ace-meta-data"
).
length
&&
$
(
"#ace-user-data"
).
length
)
{
if
(
$
(
"#ace-meta-data"
).
length
&&
$
(
"#ace-user-data"
).
length
&&
$
(
"#ace-network-data"
).
length
)
{
var
meta_data
=
ace
.
edit
(
'ace-meta-data'
,
{
var
meta_data
=
ace
.
edit
(
'ace-meta-data'
,
{
mode
:
"ace/mode/yaml"
,
useWorker
:
false
,
mode
:
"ace/mode/yaml"
,
useWorker
:
false
,
selectionStyle
:
"text"
});
selectionStyle
:
"text"
});
...
@@ -18,12 +18,23 @@ $(function() {
...
@@ -18,12 +18,23 @@ $(function() {
user_data
.
getSession
().
on
(
"change"
,
function
()
{
user_data
.
getSession
().
on
(
"change"
,
function
()
{
textarea_user
.
val
(
user_data
.
getSession
().
getValue
());
textarea_user
.
val
(
user_data
.
getSession
().
getValue
());
});
});
var
network_data
=
ace
.
edit
(
'ace-network-data'
,
{
mode
:
"ace/mode/yaml"
,
useWorker
:
false
,
selectionStyle
:
"text"
});
var
textarea_network
=
$
(
'textarea[name="ci_network_config"]'
);
network_data
.
getSession
().
setValue
(
textarea_network
.
val
())
network_data
.
getSession
().
on
(
"change"
,
function
()
{
textarea_network
.
val
(
network_data
.
getSession
().
getValue
());
});
meta_data
.
session
.
setTabSize
(
4
);
meta_data
.
session
.
setTabSize
(
4
);
meta_data
.
session
.
setUseSoftTabs
(
true
);
meta_data
.
session
.
setUseSoftTabs
(
true
);
user_data
.
session
.
setTabSize
(
4
);
user_data
.
session
.
setTabSize
(
4
);
user_data
.
session
.
setUseSoftTabs
(
true
);
user_data
.
session
.
setUseSoftTabs
(
true
);
network_data
.
session
.
setTabSize
(
4
);
network_data
.
session
.
setUseSoftTabs
(
true
);
document
.
getElementById
(
'ace-meta-data'
).
style
.
fontSize
=
'14px'
;
document
.
getElementById
(
'ace-meta-data'
).
style
.
fontSize
=
'14px'
;
document
.
getElementById
(
'ace-user-data'
).
style
.
fontSize
=
'14px'
;
document
.
getElementById
(
'ace-user-data'
).
style
.
fontSize
=
'14px'
;
document
.
getElementById
(
'ace-network-data'
).
style
.
fontSize
=
'14px'
;
/* */
/* */
$
(
'#vm-details-cidata-save'
).
click
(
function
(
e
)
{
$
(
'#vm-details-cidata-save'
).
click
(
function
(
e
)
{
$
.
ajax
({
$
.
ajax
({
...
...
circle/dashboard/templates/dashboard/_template-create.html
View file @
6d803ade
...
@@ -34,6 +34,7 @@
...
@@ -34,6 +34,7 @@
</div>
</div>
{{ form.cloud_init|as_crispy_field }}
{{ form.cloud_init|as_crispy_field }}
{{ form.ci_meta_data|as_crispy_field }}
{{ form.ci_meta_data|as_crispy_field }}
{{ form.ci_network_config|as_crispy_field }}
{{ form.ci_user_data|as_crispy_field }}
{{ form.ci_user_data|as_crispy_field }}
</fieldset>
</fieldset>
...
...
circle/dashboard/templates/dashboard/vm-detail/cloudinit.html
View file @
6d803ade
...
@@ -16,6 +16,9 @@
...
@@ -16,6 +16,9 @@
{{ ci_data.ci_meta_data|as_crispy_field }}
{{ ci_data.ci_meta_data|as_crispy_field }}
<div
id=
"ace-meta-data"
style=
"border: 1px solid #ccc;"
></div>
<div
id=
"ace-meta-data"
style=
"border: 1px solid #ccc;"
></div>
<div
style=
"height: 160px;"
></div>
<div
style=
"height: 160px;"
></div>
{{ ci_data.ci_network_config|as_crispy_field }}
<div
id=
"ace-network-data"
style=
"border: 1px solid #ccc;"
></div>
<div
style=
"height: 160px;"
></div>
{{ ci_data.ci_user_data|as_crispy_field }}
{{ ci_data.ci_user_data|as_crispy_field }}
<div
id=
"ace-user-data"
style=
"border: 1px solid #ccc;"
></div>
<div
id=
"ace-user-data"
style=
"border: 1px solid #ccc;"
></div>
<div
style=
"height: 360px;"
></div>
<div
style=
"height: 360px;"
></div>
...
...
circle/dashboard/validators.py
View file @
6d803ade
...
@@ -90,6 +90,23 @@ def user_data_validator(instance, value):
...
@@ -90,6 +90,23 @@ def user_data_validator(instance, value):
except
jinja2
.
exceptions
.
TemplateError
as
exc
:
except
jinja2
.
exceptions
.
TemplateError
as
exc
:
raise
ValidationError
(
exc
.
message
)
raise
ValidationError
(
exc
.
message
)
def
network_data_validator
(
instance
,
value
):
try
:
instance
.
validate_ci_data
(
value
)
except
yaml
.
YAMLError
as
exc
:
if
hasattr
(
exc
,
'problem_mark'
):
if
exc
.
context
!=
None
:
raise
ValidationError
(
' parser says
\n
'
+
str
(
exc
.
problem_mark
)
+
'
\n
'
+
str
(
exc
.
problem
)
+
' '
+
str
(
exc
.
context
)
+
'
\n
Please correct data and retry.'
)
else
:
raise
ValidationError
(
' parser says
\n
'
+
str
(
exc
.
problem_mark
)
+
'
\n
'
+
str
(
exc
.
problem
)
+
'
\n
Please correct data and retry.'
)
else
:
raise
ValidationError
(
"Something went wrong while parsing yaml file"
)
except
jinja2
.
exceptions
.
TemplateError
as
exc
:
raise
ValidationError
(
exc
.
message
)
def
connect_command_template_validator
(
value
):
def
connect_command_template_validator
(
value
):
"""Validate value as a connect command template.
"""Validate value as a connect command template.
...
...
circle/storage/models.py
View file @
6d803ade
...
@@ -448,14 +448,14 @@ class Disk(TimeStampedModel):
...
@@ -448,14 +448,14 @@ class Disk(TimeStampedModel):
return
result
return
result
@classmethod
@classmethod
def
create_ci_disk
(
cls
,
meta_data
,
user_data
,
user
=
None
,
**
params
):
def
create_ci_disk
(
cls
,
meta_data
,
user_data
,
network_data
,
user
=
None
,
**
params
):
params
.
setdefault
(
'name'
,
'ci-disk'
)
params
.
setdefault
(
'name'
,
'ci-disk'
)
params
.
setdefault
(
'type'
,
'raw-ro'
)
params
.
setdefault
(
'type'
,
'raw-ro'
)
params
.
setdefault
(
'size'
,
None
)
params
.
setdefault
(
'size'
,
None
)
disk
=
cls
.
__create
(
params
=
params
,
user
=
user
)
disk
=
cls
.
__create
(
params
=
params
,
user
=
user
)
queue_name
=
disk
.
get_remote_queue_name
(
'storage'
,
priority
=
"fast"
)
queue_name
=
disk
.
get_remote_queue_name
(
'storage'
,
priority
=
"fast"
)
disk_desc
=
disk
.
get_disk_desc
()
disk_desc
=
disk
.
get_disk_desc
()
result
=
storage_tasks
.
create_ci_disk
.
apply_async
(
args
=
[
disk_desc
,
meta_data
,
user_data
],
result
=
storage_tasks
.
create_ci_disk
.
apply_async
(
args
=
[
disk_desc
,
meta_data
,
user_data
,
network_data
],
queue
=
queue_name
queue
=
queue_name
)
.
get
(
timeout
=
15
)
)
.
get
(
timeout
=
15
)
disk
.
size
=
result
[
'size'
]
disk
.
size
=
result
[
'size'
]
...
...
circle/storage/tasks/storage_tasks.py
View file @
6d803ade
...
@@ -34,7 +34,7 @@ def create(disk_desc):
...
@@ -34,7 +34,7 @@ def create(disk_desc):
@celery.task
(
name
=
'storagedriver.create_ci_disk'
)
@celery.task
(
name
=
'storagedriver.create_ci_disk'
)
def
create_ci_disk
(
disk_desc
,
meta_data
,
user_data
):
def
create_ci_disk
(
disk_desc
,
meta_data
,
user_data
,
network_data
):
pass
pass
...
...
circle/vm/migrations/0012_auto_20221006_1433.py
0 → 100644
View file @
6d803ade
# Generated by Django 3.2.3 on 2022-10-06 14:33
from
django.db
import
migrations
,
models
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'vm'
,
'0011_instance_hookurl'
),
]
operations
=
[
migrations
.
AddField
(
model_name
=
'instance'
,
name
=
'ci_network_config'
,
field
=
models
.
TextField
(
blank
=
True
,
default
=
'#cloud-config
\n\n
users:
\n
- name: {{ sysuser }}
\n
sudo: [
\'
ALL=(ALL) NOPASSWD:ALL
\'
]
\n
groups: sudo
\n
shell: /bin/bash
\n
ssh_pwauth: True
\n
chpasswd: { expire: False }
\n
lock-passwd: false
\n
passwd: "{{ password | hash }}"'
,
help_text
=
'When cloud-init is active, set network-config(YAML format)'
,
verbose_name
=
'CI Network Data'
),
),
migrations
.
AddField
(
model_name
=
'instancetemplate'
,
name
=
'ci_network_config'
,
field
=
models
.
TextField
(
blank
=
True
,
default
=
'#cloud-config
\n\n
users:
\n
- name: {{ sysuser }}
\n
sudo: [
\'
ALL=(ALL) NOPASSWD:ALL
\'
]
\n
groups: sudo
\n
shell: /bin/bash
\n
ssh_pwauth: True
\n
chpasswd: { expire: False }
\n
lock-passwd: false
\n
passwd: "{{ password | hash }}"'
,
help_text
=
'When cloud-init is active, set network-config(YAML format)'
,
verbose_name
=
'CI Network Data'
),
),
]
circle/vm/migrations/0013_auto_20221006_1509.py
0 → 100644
View file @
6d803ade
# Generated by Django 3.2.3 on 2022-10-06 15:09
from
django.db
import
migrations
,
models
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'vm'
,
'0012_auto_20221006_1433'
),
]
operations
=
[
migrations
.
AlterField
(
model_name
=
'instance'
,
name
=
'ci_network_config'
,
field
=
models
.
TextField
(
blank
=
True
,
default
=
"network:
\n
version: 2
\n
ethernets:
\n
ens3:
\n
match:
\n
macaddress: 'mac'
\n
addresses:
\n
- ipv4/24
\n
gateway4: ipv4
\n
nameservers:
\n
addresses:
\n
- 8.8.8.8"
,
help_text
=
'When cloud-init is active, set network-config(YAML format)'
,
verbose_name
=
'CI Network Data'
),
),
migrations
.
AlterField
(
model_name
=
'instancetemplate'
,
name
=
'ci_network_config'
,
field
=
models
.
TextField
(
blank
=
True
,
default
=
"network:
\n
version: 2
\n
ethernets:
\n
ens3:
\n
match:
\n
macaddress: 'mac'
\n
addresses:
\n
- ipv4/24
\n
gateway4: ipv4
\n
nameservers:
\n
addresses:
\n
- 8.8.8.8"
,
help_text
=
'When cloud-init is active, set network-config(YAML format)'
,
verbose_name
=
'CI Network Data'
),
),
]
circle/vm/models/instance.py
View file @
6d803ade
...
@@ -88,15 +88,34 @@ platform: circle3
...
@@ -88,15 +88,34 @@ platform: circle3
CI_USER_DATA_DEF
=
"""
CI_USER_DATA_DEF
=
"""
#cloud-config
#cloud-config
ssh_pwauth: 1
users:
users:
- name: {{ sysuser }}
- name: {{ sysuser }}
sudo: ['ALL=(ALL) NOPASSWD:ALL']
sudo: ['ALL=(ALL) NOPASSWD:ALL']
groups: sudo
groups: sudo
shell: /bin/bash
shell: /bin/bash
ssh_pwauth: True
chpasswd: { expire: False }
chpasswd: { expire: False }
lock-passwd: false
lock-passwd: false
passwd: "{{ password | hash }}"
chpasswd:
list: |
{{ sysuser }}:{{ password }}
expire: False
"""
.
strip
()
CI_NETWORK_CONFIG_DEF
=
"""
network:
version: 2
ethernets:
ens3:
match:
macaddress: 'mac'
addresses:
- ipv4/24
gateway4: ipv4
nameservers:
addresses:
- 8.8.8.8
"""
.
strip
()
"""
.
strip
()
try
:
try
:
...
@@ -151,6 +170,8 @@ class VirtualMachineDescModel(BaseResourceConfigModel):
...
@@ -151,6 +170,8 @@ class VirtualMachineDescModel(BaseResourceConfigModel):
'When cloud-init is active, set meta-data (YAML format)'
),
default
=
CI_META_DATA_DEF
)
'When cloud-init is active, set meta-data (YAML format)'
),
default
=
CI_META_DATA_DEF
)
ci_user_data
=
TextField
(
verbose_name
=
_
(
'CI User Data'
),
blank
=
True
,
help_text
=
_
(
ci_user_data
=
TextField
(
verbose_name
=
_
(
'CI User Data'
),
blank
=
True
,
help_text
=
_
(
'When cloud-init is active, set user-data (YAML format)'
),
default
=
CI_USER_DATA_DEF
)
'When cloud-init is active, set user-data (YAML format)'
),
default
=
CI_USER_DATA_DEF
)
ci_network_config
=
TextField
(
verbose_name
=
_
(
'CI Network Data'
),
blank
=
True
,
help_text
=
_
(
'When cloud-init is active, set network-config(YAML format)'
),
default
=
CI_NETWORK_CONFIG_DEF
)
req_traits
=
ManyToManyField
(
Trait
,
blank
=
True
,
req_traits
=
ManyToManyField
(
Trait
,
blank
=
True
,
help_text
=
_
(
"A set of traits required for a "
help_text
=
_
(
"A set of traits required for a "
"node to declare to be suitable "
"node to declare to be suitable "
...
@@ -450,6 +471,13 @@ class Instance(AclBase, VirtualMachineDescModel, StatusModel, OperatedMixin,
...
@@ -450,6 +471,13 @@ class Instance(AclBase, VirtualMachineDescModel, StatusModel, OperatedMixin,
template
=
env
.
from_string
(
data
)
template
=
env
.
from_string
(
data
)
return
template
.
render
(
ci_datas
)
return
template
.
render
(
ci_datas
)
@property
def
get_network_config
(
self
):
data
=
str
(
self
.
ci_network_config
)
ci_datas
=
self
.
get_ci_data_dict
()
template
=
env
.
from_string
(
data
)
return
template
.
render
(
ci_datas
)
def
validate_ci_data
(
self
,
data
):
def
validate_ci_data
(
self
,
data
):
ci_datas
=
self
.
get_ci_data_dict
()
ci_datas
=
self
.
get_ci_data_dict
()
template
=
env
.
from_string
(
data
)
template
=
env
.
from_string
(
data
)
...
@@ -460,8 +488,8 @@ class Instance(AclBase, VirtualMachineDescModel, StatusModel, OperatedMixin,
...
@@ -460,8 +488,8 @@ class Instance(AclBase, VirtualMachineDescModel, StatusModel, OperatedMixin,
def
callhookurl
(
self
):
def
callhookurl
(
self
):
import
requests
as
req
import
requests
as
req
if
self
.
hookurl
:
if
self
.
hookurl
:
logger
.
info
(
"notify remote host (callhookurl)
"
)
logger
.
info
(
"notify remote host (callhookurl)
: "
+
str
(
self
.
hookurl
)
)
req
.
post
(
url
=
s
elf
.
hookurl
)
req
.
post
(
url
=
s
tr
(
self
.
hookurl
)
)
def
_update_status
(
self
):
def
_update_status
(
self
):
...
...
circle/vm/operations.py
View file @
6d803ade
...
@@ -539,14 +539,16 @@ class DeployOperation(InstanceOperation):
...
@@ -539,14 +539,16 @@ class DeployOperation(InstanceOperation):
import
json
import
json
logger
.
info
(
'create ci image'
)
logger
.
info
(
'create ci image'
)
disk
=
Disk
.
create_ci_disk
(
meta_data
=
self
.
instance
.
get_meta_data
,
disk
=
Disk
.
create_ci_disk
(
meta_data
=
self
.
instance
.
get_meta_data
,
user_data
=
self
.
instance
.
get_user_data
)
user_data
=
self
.
instance
.
get_user_data
,
network_data
=
self
.
instance
.
get_network_config
)
disk
.
full_clean
()
disk
.
full_clean
()
disk
.
save
()
disk
.
save
()
self
.
instance
.
disks
.
add
(
disk
)
self
.
instance
.
disks
.
add
(
disk
)
return
create_readable
(
ugettext_noop
(
return
create_readable
(
ugettext_noop
(
" ---- META-DATA ----
\n
%(meta_data)
s
\n\n
---- USER-DATA ----
\n
%(user_data)
s"
),
" ---- META-DATA ----
\n
%(meta_data)
s
\n\n
----
NETWORK-CONFIG ----
\n
%(network_data)
s
\n\n
----
USER-DATA ----
\n
%(user_data)
s"
),
meta_data
=
self
.
instance
.
get_meta_data
,
meta_data
=
self
.
instance
.
get_meta_data
,
user_data
=
self
.
instance
.
get_user_data
)
user_data
=
self
.
instance
.
get_user_data
,
network_data
=
self
.
instance
.
get_network_config
)
@register_operation
@register_operation
class
DeployDisksOperation
(
SubOperationMixin
,
InstanceOperation
):
class
DeployDisksOperation
(
SubOperationMixin
,
InstanceOperation
):
...
@@ -616,6 +618,7 @@ class DestroyOperation(InstanceOperation):
...
@@ -616,6 +618,7 @@ class DestroyOperation(InstanceOperation):
self
.
instance
.
destroyed_at
=
timezone
.
now
()
self
.
instance
.
destroyed_at
=
timezone
.
now
()
self
.
instance
.
save
()
self
.
instance
.
save
()
logger
.
info
(
'destroy vm operation '
+
str
(
system
))
if
system
:
if
system
:
self
.
instance
.
callhookurl
()
self
.
instance
.
callhookurl
()
...
@@ -1029,6 +1032,7 @@ class SleepOperation(InstanceOperation):
...
@@ -1029,6 +1032,7 @@ class SleepOperation(InstanceOperation):
self
.
instance
.
shutdown_net
()
self
.
instance
.
shutdown_net
()
self
.
instance
.
_suspend_vm
(
parent_activity
=
activity
)
self
.
instance
.
_suspend_vm
(
parent_activity
=
activity
)
self
.
instance
.
yield_node
()
self
.
instance
.
yield_node
()
logger
.
info
(
'sleep vm operation '
+
str
(
system
))
if
system
:
if
system
:
self
.
instance
.
callhookurl
()
self
.
instance
.
callhookurl
()
...
@@ -1502,7 +1506,7 @@ class CIDataChangeOperation(InstanceOperation):
...
@@ -1502,7 +1506,7 @@ class CIDataChangeOperation(InstanceOperation):
accept_states
=
(
'STOPPED'
,
'PENDING'
)
accept_states
=
(
'STOPPED'
,
'PENDING'
)
def
_operation
(
self
,
user
,
activity
,
def
_operation
(
self
,
user
,
activity
,
ci_meta_data
,
ci_user_data
,
ci_meta_data
,
ci_user_data
,
ci_network_config
,
with_shutdown
=
False
,
task
=
None
):
with_shutdown
=
False
,
task
=
None
):
logger
.
debug
(
'save cloud-init:
%
s
\n
%
s'
,
ci_meta_data
,
ci_user_data
)
logger
.
debug
(
'save cloud-init:
%
s
\n
%
s'
,
ci_meta_data
,
ci_user_data
)
if
self
.
instance
.
status
==
'RUNNING'
and
not
with_shutdown
:
if
self
.
instance
.
status
==
'RUNNING'
and
not
with_shutdown
:
...
@@ -1517,6 +1521,7 @@ class CIDataChangeOperation(InstanceOperation):
...
@@ -1517,6 +1521,7 @@ class CIDataChangeOperation(InstanceOperation):
self
.
instance
.
ci_meta_data
=
ci_meta_data
self
.
instance
.
ci_meta_data
=
ci_meta_data
self
.
instance
.
ci_user_data
=
ci_user_data
self
.
instance
.
ci_user_data
=
ci_user_data
self
.
instance
.
ci_network_config
=
ci_network_config
self
.
instance
.
full_clean
()
self
.
instance
.
full_clean
()
self
.
instance
.
save
()
self
.
instance
.
save
()
...
...
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