Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Daniel Baur
cloudify3
Commits
d0a345a1
Commit
d0a345a1
authored
Jun 16, 2015
by
Daniel Baur
Browse files
Initial draft of ghost blueprint
parent
727e8c51
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
753 additions
and
0 deletions
+753
-0
ghost-openstack/ghost.yaml
ghost-openstack/ghost.yaml
+271
-0
ghost-openstack/inputs.yaml
ghost-openstack/inputs.yaml
+3
-0
ghost-openstack/resources/nginx/nginx.default.template
ghost-openstack/resources/nginx/nginx.default.template
+33
-0
ghost-openstack/scripts/ghost/install-ubuntu.sh
ghost-openstack/scripts/ghost/install-ubuntu.sh
+4
-0
ghost-openstack/scripts/nginx/install-ubuntu.sh
ghost-openstack/scripts/nginx/install-ubuntu.sh
+9
-0
ghost-openstack/scripts/nginx/nginx.py
ghost-openstack/scripts/nginx/nginx.py
+124
-0
ghost-openstack/scripts/nodejs/install-ubuntu.sh
ghost-openstack/scripts/nodejs/install-ubuntu.sh
+11
-0
ghost-openstack/scripts/postgre/install-ubuntu.sh
ghost-openstack/scripts/postgre/install-ubuntu.sh
+9
-0
ghost-openstack/scripts/postgre/postgre.py
ghost-openstack/scripts/postgre/postgre.py
+124
-0
ghost-openstack/scripts/postgre/set-postgre-url.sh
ghost-openstack/scripts/postgre/set-postgre-url.sh
+5
-0
ghost-openstack/scripts/postgre/start-ubuntu.sh
ghost-openstack/scripts/postgre/start-ubuntu.sh
+8
-0
ghost-openstack/scripts/postgre/stop-ubuntu.sh
ghost-openstack/scripts/postgre/stop-ubuntu.sh
+8
-0
ghost-openstack/types/ghost.yaml
ghost-openstack/types/ghost.yaml
+91
-0
ghost-openstack/types/nginx.yaml
ghost-openstack/types/nginx.yaml
+53
-0
No files found.
ghost-openstack/ghost.yaml
0 → 100644
View file @
d0a345a1
########################################
# Ghost Blueprint
# - nginx as loadbalancer
# - ghost webapp on nodejs
# - postgresql as db backend
########################################
tosca_definitions_version
:
cloudify_dsl_1_0
imports
:
-
http://www.getcloudify.org/spec/cloudify/3.3m1/types.yaml
-
http://www.getcloudify.org/spec/openstack-plugin/1.3m1/plugin.yaml
-
http://www.getcloudify.org/spec/diamond-plugin/1.3m1/plugin.yaml
-
types/ghost.yaml
-
types/nginx.yaml
#####################################################################################
# inputs section allows the user to use same
# blueprint for creating different deployments, each one
# with its own parameters.
# to specify deployment inputs run:
# - cfy deployments create -b <blueprint_id> -d <deployment_id> -i inputs.yaml
#####################################################################################
inputs
:
image
:
description
:
>
Image to be used when launching agent VM's
flavor
:
description
:
>
Flavor of the agent VM's
agent_user
:
description
:
>
User for connecting to agent VM's
node_types
:
###########################################################
# We define a type that inherits openstack's default
# server, and adds monitoring capabillities on top of it.
###########################################################
ghost.nodes.MonitoredServer
:
derived_from
:
cloudify.openstack.nodes.Server
properties
:
cloudify_agent
:
default
:
user
:
{
get_input
:
agent_user
}
server
:
default
:
image
:
{
get_input
:
image
}
flavor
:
{
get_input
:
flavor
}
interfaces
:
###########################################################
# We are infact telling cloudify to install a diamond
# monitoring agent on the server.
#
# (see https://github.com/BrightcoveOS/Diamond)
###########################################################
cloudify.interfaces.monitoring_agent
:
install
:
implementation
:
diamond.diamond_agent.tasks.install
inputs
:
diamond_config
:
default
:
interval
:
1
start
:
diamond.diamond_agent.tasks.start
stop
:
diamond.diamond_agent.tasks.stop
uninstall
:
diamond.diamond_agent.tasks.uninstall
###########################################################
# Adding some collectors. These collectors are necessary
# for the Cloudify UI to display the deafult metrics.
###########################################################
cloudify.interfaces.monitoring
:
start
:
implementation
:
diamond.diamond_agent.tasks.add_collectors
inputs
:
collectors_config
:
default
:
CPUCollector
:
{}
MemoryCollector
:
{}
LoadAverageCollector
:
{}
DiskUsageCollector
:
config
:
devices
:
x?vd[a-z]+[0-9]*$
NetworkCollector
:
{}
node_templates
:
postgre_host
:
type
:
ghost.nodes.MonitoredServer
relationships
:
###########################################################
# Attaching the postgre security group to the postgre host
###########################################################
-
target
:
mongod_security_group
type
:
cloudify.openstack.server_connected_to_security_group
nodejs_host
:
type
:
ghost.nodes.MonitoredServer
###########################################################
# Setting the nodejs_host initial number of instances to 2.
# The default values for instances.deploy is 1.
###########################################################
instances
:
deploy
:
2
relationships
:
###########################################################
# Attaching the ghost security group to
# the ghost host
###########################################################
-
target
:
ghost_security_group
type
:
cloudify.openstack.server_connected_to_security_group
nginx_frontend_host
:
type
:
ghost.nodes.MonitoredServer
relationships
:
###########################################################
# Attaching a floating ip to the nginx frontend host
###########################################################
-
type
:
cloudify.openstack.server_connected_to_floating_ip
target
:
nginx_floatingip
###########################################################
# Attaching the nginx frontend security group to
# the nginx frontend host
###########################################################
-
type
:
cloudify.openstack.server_connected_to_security_group
target
:
nginx_frontend_security_group
postgre
:
type
:
ghost.nodes.PostgreSQL
properties
:
port
:
27017
interfaces
:
relationships
:
-
type
:
cloudify.relationships.contained_in
target
:
postgre_host
nodejs
:
type
:
ghost.nodes.NodeJSServer
relationships
:
-
type
:
cloudify.relationships.contained_in
target
:
nodejs_host
ghost
:
type
:
ghost.nodes.GhostApplicationModule
properties
:
port
:
8080
relationships
:
################################
# Setting the postgre connection
################################
-
type
:
node_connected_to_postgre
target
:
postgre
################################
# Setting the nodejs connection
################################
-
type
:
node_contained_in_nodejs
target
:
nodejs
################################
# Setting the haproxy connection
################################
-
type
:
app_connected_to_nginx
target
:
nginx
########################################
# Note: only ubuntu haproxy installation
# is supported.
########################################
nginx
:
type
:
nginx.nodes.Proxy
relationships
:
-
target
:
nginx_frontend_host
type
:
cloudify.relationships.contained_in
###########################################################
# A security group to enable access to the nodejs host
# using the port of the ghost application.
#
# This security group will be attached to the nodejs_host
###########################################################
ghost_security_group
:
type
:
cloudify.openstack.nodes.SecurityGroup
properties
:
security_group
:
name
:
ghost_security_group
rules
:
-
remote_ip_prefix
:
0.0.0.0/0
port
:
2368
###########################################################
# A security group to enable access to the postgre host
# using the port of the postgre node.
#
# We need this so that the ghost application can
# comminicate with PostgreSQL DB, since they are running on
# different hosts.
###########################################################
postgre_security_group
:
type
:
cloudify.openstack.nodes.SecurityGroup
properties
:
security_group
:
name
:
postgre_security_group
rules
:
-
remote_ip_prefix
:
0.0.0.0/0
port
:
5432
###########################################################
# A security group to enable access to the nginx frontend
# host.
#
# This security group will be attached to the
# nginx_frontend_host
###########################################################
nginx_frontend_security_group
:
type
:
cloudify.openstack.nodes.SecurityGroup
properties
:
security_group
:
name
:
nginx_frontend_security_group
rules
:
-
remote_ip_prefix
:
0.0.0.0/0
port
:
80
###########################################################
# A floating ip to be attached to the nginx frontend host,
# since eventually we want to be able to access the application
# from any machine, on any network.
###########################################################
frontend_floatingip
:
type
:
cloudify.openstack.nodes.FloatingIP
###########################################################
# This outputs section exposes the application endpoint.
# You can access it by running:
# - cfy deployments -d <deployment_id> outputs
###########################################################
outputs
:
endpoint
:
description
:
Web application endpoint
value
:
ip_address
:
{
get_attribute
:
[
frontend_floatingip
,
floating_ip_address
]
}
port
:
80
\ No newline at end of file
ghost-openstack/inputs.yaml
0 → 100644
View file @
d0a345a1
image
:
'
c404edc0-0b8f-4749-bd94-dc65338c41f5'
flavor
:
'
3'
agent_user
:
'
ubuntu'
\ No newline at end of file
ghost-openstack/resources/nginx/nginx.default.template
0 → 100644
View file @
d0a345a1
##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# http://wiki.nginx.org/Pitfalls
# http://wiki.nginx.org/QuickStart
# http://wiki.nginx.org/Configuration
#
# Generally, you will want to move this file somewhere, and start with a clean
# file but keep this around for reference. Or just disable in sites-enabled.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
root /usr/share/nginx/html;
index index.html index.htm;
upstream ghost {
{% for id, backend in backends.iteritems() %}
server {{ backend.address }}:2368
{% endfor %}
}
# Make site accessible from http://localhost/
server_name localhost;
location / {
proxy_pass http://ghost;
}
}
\ No newline at end of file
ghost-openstack/scripts/ghost/install-ubuntu.sh
0 → 100644
View file @
d0a345a1
sudo
apt-get
install
unzip
curl
-L
https://ghost.org/zip/ghost-latest.zip
-o
ghost.zip
unzip
-uo
ghost.zip
-d
ghost
cd
ghost
\ No newline at end of file
ghost-openstack/scripts/nginx/install-ubuntu.sh
0 → 100755
View file @
d0a345a1
#!/bin/bash -e
ctx logger info
"Installing nginx"
ctx logger debug
"
${
COMMAND
}
"
sudo
apt-get update
sudo
apt-get
-y
install
nginx
ctx logger info
"Installed nginx"
\ No newline at end of file
ghost-openstack/scripts/nginx/nginx.py
0 → 100644
View file @
d0a345a1
###############################################################################
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
###############################################################################
import
os
import
subprocess
import
tempfile
from
contextlib
import
contextmanager
from
jinja2
import
Template
from
cloudify_rest_client
import
exceptions
as
rest_exceptions
from
cloudify
import
ctx
from
cloudify.state
import
ctx_parameters
as
inputs
from
cloudify
import
exceptions
from
cloudify
import
utils
CONFIG_PATH
=
'/etc/nginx/sites-enabled/default'
TEMPLATE_RESOURCE_NAME
=
'resources/nginx/nginx.default.template'
def
configure
(
subject
=
None
):
subject
=
subject
or
ctx
ctx
.
logger
.
info
(
'Configuring nginx.'
)
template
=
Template
(
ctx
.
get_resource
(
TEMPLATE_RESOURCE_NAME
))
ctx
.
logger
.
debug
(
'Building a dict object that will contain variables '
'to write to the Jinja2 template.'
)
config
=
subject
.
node
.
properties
.
copy
()
config
.
update
(
dict
(
backends
=
subject
.
instance
.
runtime_properties
.
get
(
'backends'
,
{})))
ctx
.
logger
.
debug
(
'Rendering the Jinja2 template to {0}.'
.
format
(
CONFIG_PATH
))
ctx
.
logger
.
debug
(
'The config dict: {0}.'
.
format
(
config
))
with
tempfile
.
NamedTemporaryFile
(
delete
=
False
)
as
temp_config
:
temp_config
.
write
(
template
.
render
(
config
))
#_run('sudo /usr/sbin/haproxy -f {0} -c'.format(temp_config.name),
# error_message='Failed to Configure')
_run
(
'sudo mv {0} {1}'
.
format
(
temp_config
.
name
,
CONFIG_PATH
),
error_message
=
'Failed to write to {0}.'
.
format
(
CONFIG_PATH
))
def
add_backend
(
backend_address
=
None
):
with
_backends_update
()
as
backends
:
backends
[
ctx
.
source
.
instance
.
id
]
=
{
'address'
:
backend_address
or
ctx
.
source
.
instance
.
host_ip
}
def
remove_backend
():
with
_backends_update
()
as
backends
:
backends
.
pop
(
ctx
.
source
.
instance
.
id
,
None
)
@
contextmanager
def
_backends_update
():
backends
=
ctx
.
target
.
instance
.
runtime_properties
.
get
(
'backends'
,
{})
yield
backends
ctx
.
target
.
instance
.
runtime_properties
[
'backends'
]
=
backends
# being explict because errors in unlink are ignored and
# not retried without being explicit.
# also, this way, we make sure that configure/reload
# are only called with a fully update configuration
try
:
ctx
.
target
.
instance
.
update
()
configure
(
subject
=
ctx
.
target
)
_service
(
'reload'
)
except
rest_exceptions
.
CloudifyClientError
as
e
:
if
'conflict'
in
str
(
e
):
# cannot 'return' in contextmanager
ctx
.
operation
.
retry
(
message
=
'Backends updated concurrently, retrying.'
,
retry_after
=
1
)
else
:
raise
def
start
():
_service
(
'start'
)
def
stop
():
_service
(
'stop'
)
def
_service
(
state
):
_run
(
'sudo service nginx {0}'
.
format
(
state
),
error_message
=
'Failed setting state to {0}'
.
format
(
state
))
def
_run
(
command
,
error_message
):
runner
=
utils
.
LocalCommandRunner
(
logger
=
ctx
.
logger
)
try
:
runner
.
run
(
command
)
except
exceptions
.
CommandExecutionException
as
e
:
raise
NonRecoverableError
(
'{0}: {1}'
.
format
(
error_message
,
e
))
def
_main
():
invocation
=
inputs
[
'invocation'
]
function
=
invocation
[
'function'
]
args
=
invocation
.
get
(
'args'
,
[])
kwargs
=
invocation
.
get
(
'kwargs'
,
{})
globals
()[
function
](
*
args
,
**
kwargs
)
if
__name__
==
'__main__'
:
_main
()
\ No newline at end of file
ghost-openstack/scripts/nodejs/install-ubuntu.sh
0 → 100755
View file @
d0a345a1
#!/bin/bash -e
ctx logger info
"Installing nodejs"
ctx logger debug
"
${
COMMAND
}
"
sudo
apt-get update
curl
-sL
https://deb.nodesource.com/setup_0.12 |
sudo
bash -
sudo
apt-get
install
-y
nodejs
sudo
apt-get
install
-y
build-essential
ctx logger info
"Installed nodejs"
\ No newline at end of file
ghost-openstack/scripts/postgre/install-ubuntu.sh
0 → 100755
View file @
d0a345a1
#!/bin/bash -e
ctx logger info
"Installing postgre"
ctx logger debug
"
${
COMMAND
}
"
sudo
apt-get update
sudo
apt-get
-y
install
postgresql
ctx logger info
"Installed postgre"
\ No newline at end of file
ghost-openstack/scripts/postgre/postgre.py
0 → 100644
View file @
d0a345a1
###############################################################################
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
###############################################################################
import
os
import
subprocess
import
tempfile
from
contextlib
import
contextmanager
from
jinja2
import
Template
from
cloudify_rest_client
import
exceptions
as
rest_exceptions
from
cloudify
import
ctx
from
cloudify.state
import
ctx_parameters
as
inputs
from
cloudify
import
exceptions
from
cloudify
import
utils
CONFIG_PATH
=
'/etc/nginx/sites-enabled/default'
TEMPLATE_RESOURCE_NAME
=
'resources/nginx/nginx.default.template'
def
configure
(
subject
=
None
):
subject
=
subject
or
ctx
ctx
.
logger
.
info
(
'Configuring nginx.'
)
template
=
Template
(
ctx
.
get_resource
(
TEMPLATE_RESOURCE_NAME
))
ctx
.
logger
.
debug
(
'Building a dict object that will contain variables '
'to write to the Jinja2 template.'
)
config
=
subject
.
node
.
properties
.
copy
()
config
.
update
(
dict
(
backends
=
subject
.
instance
.
runtime_properties
.
get
(
'backends'
,
{})))
ctx
.
logger
.
debug
(
'Rendering the Jinja2 template to {0}.'
.
format
(
CONFIG_PATH
))
ctx
.
logger
.
debug
(
'The config dict: {0}.'
.
format
(
config
))
with
tempfile
.
NamedTemporaryFile
(
delete
=
False
)
as
temp_config
:
temp_config
.
write
(
template
.
render
(
config
))
#_run('sudo /usr/sbin/haproxy -f {0} -c'.format(temp_config.name),
# error_message='Failed to Configure')
_run
(
'sudo mv {0} {1}'
.
format
(
temp_config
.
name
,
CONFIG_PATH
),
error_message
=
'Failed to write to {0}.'
.
format
(
CONFIG_PATH
))
def
add_backend
(
backend_address
=
None
):
with
_backends_update
()
as
backends
:
backends
[
ctx
.
source
.
instance
.
id
]
=
{
'address'
:
backend_address
or
ctx
.
source
.
instance
.
host_ip
}
def
remove_backend
():
with
_backends_update
()
as
backends
:
backends
.
pop
(
ctx
.
source
.
instance
.
id
,
None
)
@
contextmanager
def
_backends_update
():
backends
=
ctx
.
target
.
instance
.
runtime_properties
.
get
(
'backends'
,
{})
yield
backends
ctx
.
target
.
instance
.
runtime_properties
[
'backends'
]
=
backends
# being explict because errors in unlink are ignored and
# not retried without being explicit.
# also, this way, we make sure that configure/reload
# are only called with a fully update configuration
try
:
ctx
.
target
.
instance
.
update
()
configure
(
subject
=
ctx
.
target
)
_service
(
'reload'
)
except
rest_exceptions
.
CloudifyClientError
as
e
:
if
'conflict'
in
str
(
e
):
# cannot 'return' in contextmanager
ctx
.
operation
.
retry
(
message
=
'Backends updated concurrently, retrying.'
,
retry_after
=
1
)
else
:
raise
def
start
():
_service
(
'start'
)
def
stop
():
_service
(
'stop'
)
def
_service
(
state
):
_run
(
'sudo service nginx {0}'
.
format
(
state
),
error_message
=
'Failed setting state to {0}'
.
format
(
state
))
def
_run
(
command
,
error_message
):
runner
=
utils
.
LocalCommandRunner
(
logger
=
ctx
.
logger
)
try
:
runner
.
run
(
command
)
except
exceptions
.
CommandExecutionException
as
e
:
raise
NonRecoverableError
(
'{0}: {1}'
.
format
(
error_message
,
e
))
def
_main
():
invocation
=
inputs
[
'invocation'
]
function
=
invocation
[
'function'
]
args
=
invocation
.
get
(
'args'
,
[])
kwargs
=
invocation
.
get
(
'kwargs'
,
{})
globals
()[
function
](
*
args
,
**
kwargs
)
if
__name__
==
'__main__'
:
_main
()
\ No newline at end of file
ghost-openstack/scripts/postgre/set-postgre-url.sh
0 → 100755
View file @
d0a345a1
#!/bin/bash
set
-e
ctx
source
instance runtime_properties postgre_ip_address
$(
ctx target instance host_ip
)
\ No newline at end of file
ghost-openstack/scripts/postgre/start-ubuntu.sh
0 → 100755
View file @
d0a345a1