Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
ansible
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenEdx
ansible
Commits
d227330a
Commit
d227330a
authored
Apr 11, 2014
by
Chris Conway
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Adds support for creating GCE persistent disks from snapshots
parent
0b45b125
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
183 additions
and
7 deletions
+183
-7
library/cloud/gce_pd
+24
-6
test/integration/Makefile
+5
-1
test/integration/cleanup_gce.py
+6
-0
test/integration/gce_credentials.py
+51
-0
test/integration/roles/test_gce_pd/tasks/main.yml
+57
-0
test/integration/setup_gce.py
+40
-0
No files found.
library/cloud/gce_pd
View file @
d227330a
...
...
@@ -24,9 +24,7 @@ short_description: utilize GCE persistent disk resources
description:
- This module can create and destroy unformatted GCE persistent disks
U(https://developers.google.com/compute/docs/disks#persistentdisks).
It also supports attaching and detaching disks from running instances
but does not support creating boot disks from images or snapshots. The
'gce' module supports creating instances with boot disks.
It also supports attaching and detaching disks from running instances.
Full install/configuration instructions for the gce* modules can
be found in the comments of ansible/test/gce_tests.py.
options:
...
...
@@ -68,6 +66,12 @@ options:
required: false
default: null
aliases: []
snapshot:
description:
- the source snapshot to use for the disk
required: false
default: null
aliases: []
state:
description:
- desired state of the persistent disk
...
...
@@ -139,6 +143,7 @@ def main():
name
=
dict
(
required
=
True
),
size_gb
=
dict
(
default
=
10
),
image
=
dict
(),
snapshot
=
dict
(),
state
=
dict
(
default
=
'present'
),
zone
=
dict
(
default
=
'us-central1-b'
),
service_account_email
=
dict
(),
...
...
@@ -155,6 +160,7 @@ def main():
name
=
module
.
params
.
get
(
'name'
)
size_gb
=
module
.
params
.
get
(
'size_gb'
)
image
=
module
.
params
.
get
(
'image'
)
snapshot
=
module
.
params
.
get
(
'snapshot'
)
state
=
module
.
params
.
get
(
'state'
)
zone
=
module
.
params
.
get
(
'zone'
)
...
...
@@ -212,11 +218,20 @@ def main():
instance_name
,
zone
),
changed
=
False
)
if
not
disk
:
if
image
is
not
None
and
snapshot
is
not
None
:
module
.
fail_json
(
msg
=
'Cannot give both image (
%
s) and snapshot (
%
s)'
%
(
image
,
snapshot
),
changed
=
False
)
lc_image
=
None
lc_snapshot
=
None
if
image
is
not
None
:
lc_image
=
gce
.
ex_get_image
(
image
)
lc_image
=
gce
.
ex_get_image
(
image
)
elif
snapshot
is
not
None
:
lc_snapshot
=
gce
.
ex_get_snapshot
(
snapshot
)
try
:
disk
=
gce
.
create_volume
(
size_gb
,
name
,
location
=
zone
,
image
=
lc_image
)
disk
=
gce
.
create_volume
(
size_gb
,
name
,
location
=
zone
,
image
=
lc_image
,
snapshot
=
lc_snapshot
)
except
ResourceExistsError
:
pass
except
QuotaExceededError
:
...
...
@@ -225,7 +240,10 @@ def main():
except
Exception
,
e
:
module
.
fail_json
(
msg
=
unexpected_error_msg
(
e
),
changed
=
False
)
json_output
[
'size_gb'
]
=
size_gb
json_output
[
'image'
]
=
image
if
image
is
not
None
:
json_output
[
'image'
]
=
image
if
snapshot
is
not
None
:
json_output
[
'snapshot'
]
=
snapshot
changed
=
True
if
inst
and
not
is_attached
:
try
:
...
...
test/integration/Makefile
View file @
d227330a
...
...
@@ -39,6 +39,9 @@ cloud_cleanup: amazon_cleanup rackspace_cleanup
amazon_cleanup
:
python cleanup_ec2.py
-y
--match
=
"^
$(CLOUD_RESOURCE_PREFIX)
"
gce_setup
:
python setup_gce.py
"
$(CLOUD_RESOURCE_PREFIX)
"
gce_cleanup
:
python cleanup_gce.py
-y
--match
=
"^
$(CLOUD_RESOURCE_PREFIX)
"
...
...
@@ -57,7 +60,8 @@ amazon: $(CREDENTIALS_FILE)
exit
$$
RC
;
gce
:
$(CREDENTIALS_FILE)
ansible-playbook gce.yml
-i
$(INVENTORY)
-e
@
$(VARS_FILE)
$(CREDENTIALS_ARG)
-e
"resource_prefix=
$(CLOUD_RESOURCE_PREFIX)
"
-v
$(TEST_FLAGS)
;
\
CLOUD_RESOURCE_PREFIX
=
"
$(CLOUD_RESOURCE_PREFIX)
"
make gce_setup
;
\
ansible-playbook gce.yml
-i
$(INVENTORY)
-e
@
$(VARS_FILE)
$(CREDENTIALS_ARG)
-e
"resource_prefix=
$(CLOUD_RESOURCE_PREFIX)
"
-v
$(TEST_FLAGS)
;
\
RC
=
$$
?
;
\
CLOUD_RESOURCE_PREFIX
=
"
$(CLOUD_RESOURCE_PREFIX)
"
make gce_cleanup
;
\
exit
$$
RC
;
...
...
test/integration/cleanup_gce.py
View file @
d227330a
...
...
@@ -98,6 +98,12 @@ if __name__ == '__main__':
try
:
# Delete matching instances
delete_gce_resources
(
gce
.
list_nodes
,
'name'
,
opts
)
# Delete matching snapshots
def
get_snapshots
():
for
volume
in
gce
.
list_volumes
():
for
snapshot
in
gce
.
list_volume_snapshots
(
volume
):
yield
snapshot
delete_gce_resources
(
get_snapshots
,
'name'
,
opts
)
# Delete matching disks
delete_gce_resources
(
gce
.
list_volumes
,
'name'
,
opts
)
except
KeyboardInterrupt
,
e
:
...
...
test/integration/gce_credentials.py
0 → 100644
View file @
d227330a
import
collections
import
os
import
yaml
try
:
from
libcloud.compute.types
import
Provider
from
libcloud.compute.providers
import
get_driver
_
=
Provider
.
GCE
except
ImportError
:
print
(
"failed=True "
+
\
"msg='libcloud with GCE support (0.13.3+) required for this module'"
)
sys
.
exit
(
1
)
def
add_credentials_options
(
parser
):
default_service_account_email
=
None
default_pem_file
=
None
default_project_id
=
None
# Load details from credentials.yml
if
os
.
path
.
isfile
(
'credentials.yml'
):
credentials
=
yaml
.
load
(
open
(
'credentials.yml'
,
'r'
))
default_service_account_email
=
credentials
[
'gce_service_account_email'
]
default_pem_file
=
credentials
[
'gce_pem_file'
]
default_project_id
=
credentials
[
'gce_project_id'
]
parser
.
add_option
(
"--service_account_email"
,
action
=
"store"
,
dest
=
"service_account_email"
,
default
=
default_service_account_email
,
help
=
"GCE service account email. Default is loaded from credentials.yml."
)
parser
.
add_option
(
"--pem_file"
,
action
=
"store"
,
dest
=
"pem_file"
,
default
=
default_pem_file
,
help
=
"GCE client key. Default is loaded from credentials.yml."
)
parser
.
add_option
(
"--project_id"
,
action
=
"store"
,
dest
=
"project_id"
,
default
=
default_project_id
,
help
=
"Google Cloud project ID. Default is loaded from credentials.yml."
)
def
check_required
(
opts
,
parser
):
for
required
in
[
'service_account_email'
,
'pem_file'
,
'project_id'
]:
if
getattr
(
opts
,
required
)
is
None
:
parser
.
error
(
"Missing required parameter: --
%
s"
%
required
)
def
get_gce_driver
(
opts
):
# Connect to GCE
gce_cls
=
get_driver
(
Provider
.
GCE
)
return
gce_cls
(
opts
.
service_account_email
,
opts
.
pem_file
,
project
=
opts
.
project_id
)
test/integration/roles/test_gce_pd/tasks/main.yml
View file @
d227330a
...
...
@@ -161,3 +161,60 @@
-
'
result.changed'
-
'
result.name
==
"{{
instance_name
}}"'
-
'
result.state
==
"absent"'
# ============================================================
-
name
:
test snapshot given (state=present)
gce_pd
:
name
:
"
{{
instance_name
}}"
snapshot
:
"
{{
instance_name
}}-snapshot"
service_account_email
:
"
{{
service_account_email
}}"
pem_file
:
"
{{
pem_file
}}"
project_id
:
"
{{
project_id
}}"
state
:
present
register
:
result
-
name
:
assert image given (state=present)
assert
:
that
:
-
'
result.changed'
-
'
result.name
==
"{{
instance_name
}}"'
-
'
result.snapshot
==
"{{
instance_name
}}-snapshot"'
-
'
result.state
==
"present"'
# ============================================================
-
name
:
test snapshot given (state=absent)
gce_pd
:
name
:
"
{{
instance_name
}}"
snapshot
:
"
{{
instance_name
}}-snapshot"
service_account_email
:
"
{{
service_account_email
}}"
pem_file
:
"
{{
pem_file
}}"
project_id
:
"
{{
project_id
}}"
state
:
absent
register
:
result
-
name
:
assert image given (state=absent)
assert
:
that
:
-
'
result.changed'
-
'
result.name
==
"{{
instance_name
}}"'
-
'
result.state
==
"absent"'
# ============================================================
-
name
:
test both image and snapshot given
gce_pd
:
name
:
"
{{
instance_name
}}"
image
:
"
debian-7"
snapshot
:
"
{{
instance_name
}}-snapshot"
service_account_email
:
"
{{
service_account_email
}}"
pem_file
:
"
{{
pem_file
}}"
project_id
:
"
{{
project_id
}}"
state
:
present
register
:
result
ignore_errors
:
true
-
name
:
assert image given (state=present)
assert
:
that
:
-
'
result.failed'
-
'
result.msg
==
"Cannot
give
both
image
(debian-7)
and
snapshot
({{
instance_name
}}-snapshot)"'
test/integration/setup_gce.py
0 → 100644
View file @
d227330a
'''
Create GCE resources for use in integration tests.
Takes a prefix as a command-line argument and creates a persistent disk
named ${prefix}-base and a snapshot of it named ${prefix}-snapshot.
prefix will be forced to lowercase, to ensure the names are legal GCE
resource names.
'''
import
sys
import
optparse
import
gce_credentials
def
parse_args
():
parser
=
optparse
.
OptionParser
(
usage
=
"
%
s [options] <prefix>"
%
(
sys
.
argv
[
0
],),
description
=
__doc__
)
gce_credentials
.
add_credentials_options
(
parser
)
parser
.
add_option
(
"--prefix"
,
action
=
"store"
,
dest
=
"prefix"
,
help
=
"String used to prefix GCE resource names (default:
%
default)"
)
(
opts
,
args
)
=
parser
.
parse_args
()
gce_credentials
.
check_required
(
opts
,
parser
)
if
not
args
:
parser
.
error
(
"Missing required argument: name prefix"
)
return
(
opts
,
args
)
if
__name__
==
'__main__'
:
(
opts
,
args
)
=
parse_args
()
gce
=
gce_credentials
.
get_gce_driver
(
opts
)
prefix
=
args
[
0
]
.
lower
()
try
:
base_volume
=
gce
.
create_volume
(
size
=
10
,
name
=
prefix
+
'-base'
,
location
=
'us-central1-a'
)
gce
.
create_volume_snapshot
(
base_volume
,
name
=
prefix
+
'-snapshot'
)
except
KeyboardInterrupt
,
e
:
print
"
\n
Exiting on user command."
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