Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'develop'

  • Loading branch information...
commit 1f18d30356ef9784903bd330787c3d32f3e7de24 2 parents 3c73e18 + 9a79973
@thatch45 thatch45 authored
View
2  doc/Makefile
@@ -3,7 +3,7 @@
# You can set these variables from the command line.
SPHINXOPTS =
-SPHINXBUILD = sphinx-build2
+SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = _build
View
22 doc/conf.py
@@ -18,6 +18,9 @@
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))
+from sphinx.directives import TocTree
+
+
class Mock(object):
'''
Mock out specified imports
@@ -43,6 +46,7 @@ def __getattr__(self, name):
return Mock()
MOCK_MODULES = [
+ 'paramiko',
'salt',
'salt.crypt',
'yaml',
@@ -337,3 +341,21 @@ def __getattr__(self, name):
# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {'http://docs.python.org/': None}
+
+def _normalize_version(args):
+ _, path = args
+ return '.'.join([x.zfill(4) for x in (path.split('/')[-1].split('.'))])
+
+
+class ReleasesTree(TocTree):
+ option_spec = dict(TocTree.option_spec)
+
+ def run(self):
+ rst = super(ReleasesTree, self).run()
+ entries = rst[0][0]['entries'][:]
+ entries.sort(key=_normalize_version, reverse=True)
+ rst[0][0]['entries'][:] = entries
+ return rst
+
+def setup(app):
+ app.add_directive('releasestree', ReleasesTree)
View
3  doc/contents.rst
@@ -15,4 +15,5 @@ Salt Cloud Table of Contents
ref/cli/man/salt-cloud
topics/releases/index
- topicstopics/releases/0.6.0
+ topics/releases/0.6.0
+ topics/releases/0.7.0
View
32 doc/man/salt-cloud.1
@@ -1,4 +1,4 @@
-.TH "SALT-CLOUD" "1" "August 13, 2012" "0.7.0" "salt-cloud"
+.TH "SALT-CLOUD" "1" "September 25, 2012" "0.8.0" "salt-cloud"
.SH NAME
salt-cloud \- Salt Cloud Command
.
@@ -28,7 +28,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
-.\" Man page generated from reStructuredText.
+.\" Man page generated from reStructeredText.
.
.sp
Copy a file to a set of systems
@@ -131,6 +131,33 @@ minion RSA keys. Default location is /etc/salt/master.
Specify an alternative location for the salt cloud profiles file.
Default location is /etc/salt/cloud.profiles.
.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-raw\-out
+Print the output from the salt command in raw python
+form, this is suitable for re\-reading the output into
+an executing python script with eval.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-text\-out
+Print the output from the salt command in the same form the shell would.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-yaml\-out
+Print the output from the salt command in yaml.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-json\-out
+Print the output from the salt command in json.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-no\-color
+Disable all colored output.
+.UNINDENT
.SH EXAMPLES
.sp
To create 4 vms named web1, web2, db1 and db2 from specified profiles:
@@ -159,4 +186,5 @@ Thomas S. Hatch <thatch45@gmail.com> and many others, please see the Authors fil
.SH COPYRIGHT
2012, Thomas S Hatch
.\" Generated by docutils manpage writer.
+.\"
.
View
690 doc/man/salt-cloud.7
@@ -1,4 +1,4 @@
-.TH "SALT-CLOUD" "7" "August 13, 2012" "0.7.0" "salt-cloud"
+.TH "SALT-CLOUD" "7" "September 25, 2012" "0.8.0" "salt-cloud"
.SH NAME
salt-cloud \- Salt Cloud Documentation
.
@@ -28,7 +28,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
-.\" Man page generated from reStructuredText.
+.\" Man page generated from reStructeredText.
.
.SH VM PROFILES
.sp
@@ -57,9 +57,9 @@ centos_rackspace:
size: 1024 server
os: RHEL6
minion:
- grains:
- role: webserver
master: salt.example.com
+ grains:
+ role: webserver
.ft P
.fi
.sp
@@ -127,22 +127,22 @@ machines to make from said profile:
.nf
.ft C
fedora_small:
- \- web1
- \- web2
- \- web3
- \- web3
- \- web4
- \- web5
+ \- web1
+ \- web2
+ \- web3
+ \- web3
+ \- web4
+ \- web5
fedora_high:
- \- redis1
- \- redis2
- \- redis3
+ \- redis1
+ \- redis2
+ \- redis3
cent_high:
- \- riak1
- \- riak2
- \- riak3
- \- riak4
- \- riak5
+ \- riak1
+ \- riak2
+ \- riak3
+ \- riak4
+ \- riak5
.ft P
.fi
.sp
@@ -173,6 +173,26 @@ that exist but are not specified in the map file will be destroyed:
$ salt\-cloud \-m /path/to/mapfile \-P \-H
.ft P
.fi
+.sp
+A map file can include grains:
+.sp
+.nf
+.ft C
+fedora_small:
+ \- web1:
+ minion:
+ log_level: debug
+ grains:
+ cheese: tasty
+ omelet: du fromage
+ \- web2:
+ minion:
+ log_level: warn
+ grains:
+ cheese: more tasty
+ omelet: with peppers
+.ft P
+.fi
.SH WRITING CLOUD PROVIDER MODULES
.sp
Salt cloud runs on a module system similar to the main Salt project. The
@@ -329,9 +349,643 @@ GOGRID.sharedsecret: saltybacon
.ft P
.fi
.SH RELEASE NOTES AND UPGRADE INSTRUCTIONS
+.SS Salt Cloud 0.6.0 Release Notes
+.sp
+The new Salt project, Salt Cloud, is introduced with version 0.6.0. Salt Cloud
+has been developed to ease the automation and integration of Salt with public
+cloud providers by allowing cloud vms to be cleanly defined, created and
+automatically hooked back into a Salt Master.
+.sp
+While Salt Cloud is primarily made to build cloud vms to tie into a Salt Mater,
+it has been created in a generic way, so that it can be used to provision and
+hook systems of any type via the familiar Salt modules system.
+.sp
+This release supports three public cloud providers (all via libcloud),
+Amazon EC2, Rackspace Cloud and Linode.
+.SS Documentation
+.sp
+The documentation for Salt Cloud can be found on Read the Docs:
+\fI\%http://salt-cloud.readthedocs.org\fP
+.SS Download
+.sp
+Salt Cloud can be downloaded and install via pypi or github:
+.sp
+\fI\%http://pypi.python.org/packages/source/s/salt-cloud/salt-cloud-0.6.0.tar.gz\fP
+.sp
+\fI\%https://github.com/downloads/saltstack/salt-cloud/salt-cloud-0.6.0.tar.gz\fP
+.sp
+Packages are not yet available, Salt Cloud requires three dependencies, the
+salt libs, libcloud, and paramiko.
+.SS Extensible With Cloud Modules
+.sp
+The Salt loader system has been employed to make adding support for additional
+public cloud systems just as modular and simple as adding support for new
+package managers in Salt.
+.sp
+Adding support for a new cloud provider is extremely simple, just add a cloud
+module and everything cleanly links together.
+.SS Define VM Profiles
+.sp
+The way a vms is created is done via profiles. Profiles are used to define what
+properties a vm will have, the cloud provider, the size and the image.
+.sp
+.nf
+.ft C
+centos_rackspace:
+ provider: rackspace
+ image: CentOS 6.2
+ size: 1024 server
+ os: RHEL6
+ minion:
+ grains:
+ role: webserver
+ master: salt.example.com
+.ft P
+.fi
+.sp
+This profile will be used to create vms on Rackspace cloud with the CentOS 6.2
+image and the Rackspace 1024 vm size. Particulars of the minion config can
+also be specified.
+.sp
+Individual vms can be created from profiles:
+.sp
+.nf
+.ft C
+# salt\-cloud \-p centos_rackspace web1
+.ft P
+.fi
+.sp
+This command creates a vms with the name web1 on the Rackspace cloud and
+connects the new vm to a Salt Master located at salt.example.com. The new VM
+has the Salt id of web1.
+.SS Define Maps of Profiles
+.sp
+When it is desired to have a predefined mapping of many, or a specific group
+of vms then a cloud map can be defined:
+.sp
+.nf
+.ft C
+centos_rackspace:
+ web1
+ web2
+ web3
+ web4
+centos_linode:
+ redis1
+ riak1
+ riak2
+ riak3
+ubuntu_ec2:
+ dev1
+ dev2
+ cassandra1
+ cassandra2
+ cassandra3
+.ft P
+.fi
+.sp
+This map file will create vms named web 1\-4 using the centos_rackspace profile
+on rackspace, the redis and riak vms on linode and the dev and Cassandra vms on
+ec2. It can be run with salt\-cloud:
+.sp
+.nf
+.ft C
+# salt\-cloud \-m mapfile
+.ft P
+.fi
+.sp
+When creating more than one vm the \-P option can be passed, to make the vms
+provision in parallel, greatly speeding up large scale expansions of vms.
+.SS Salt Cloud 0.7.0 Release Notes
+.sp
+Salt Cloud marches forward with the 0.7.0 release. As is customary for Salt
+Stack projects the 0.7.0 release is intended to be much more robust and
+deliver a more complete core feature set. Salt Cloud 0.7.0 is just that.
+.sp
+With new tools to help look into what is available on cloud providers,
+new additions to make cloud management more stateful and the addition of
+more supported cloud platforms 0.7.0 has greatly enhanced the capabilities
+of the overall Salt platform.
+.SS Documentation
+.sp
+The documentation for Salt Cloud can be found on Read the Docs:
+\fI\%http://salt-cloud.readthedocs.org\fP
+.SS Download
+.sp
+Salt Cloud can be downloaded and install via pypi or github:
+.sp
+\fI\%http://pypi.python.org/packages/source/s/salt-cloud/salt-cloud-0.7.0.tar.gz\fP
+.sp
+\fI\%https://github.com/downloads/saltstack/salt-cloud/salt-cloud-0.7.0.tar.gz\fP
+.sp
+Some packages have been made available for salt\-cloud and more on on their
+way. Packages for Arch, and FreeBSD are being made available thanks to the
+work of Christer Edwards, and packages for RHEL and Fedora are being created
+by Clint Savage. Package availability will be announced on the salt mailing list.
+.SS New Cloud Provider Support
+.sp
+The following cloud providers are now supported:
+.INDENT 0.0
+.TP
+.B Amazon AWS
+\fI\%http://aws.amazon.com/ec2/\fP
+.TP
+.B Rackspace Cloud
+\fI\%http://www.rackspace.com/cloud/\fP
+.TP
+.B Linode
+\fI\%http://www.linode.com/\fP
+.TP
+.B Joyent
+\fI\%http://joyent.com/\fP
+.TP
+.B GoGrid
+\fI\%http://www.gogrid.com/\fP
+.UNINDENT
+.SS List Available Resources
+.sp
+Setting up Salt Cloud requires knowlege of the available sizes and images on
+cloud providers. Listing the available images and sizes can now be done with
+the salt\-cloud command:
+.sp
+.nf
+.ft C
+[root@saltmaster]# salt\-cloud \-\-list\-sizes linode
+linode
+ Linode 1024
+ bandwidth: 400
+ disk: 40960
+ id: 3
+ name: Linode 1024
+ ram: 1024
+ uuid: 56e6f495190cb2ed1a343f7159ad447cf27d906d
+ Linode 12GB
+ bandwidth: 2000
+ disk: 491520
+ id: 8
+ name: Linode 12GB
+ ram: 12288
+ uuid: 3d1731ebefdbcb4c283957b43d45f89a01f67c5f
+ Linode 1536
+ bandwidth: 600
+ disk: 61440
+ id: 4
+ name: Linode 1536
+ ram: 1536
+ uuid: f0f28628cc70c5f2656aa3f313588d8509ee3787
+ Linode 16GB
+ bandwidth: 2000
+ disk: 655360
+ id: 9
+ name: Linode 16GB
+ ram: 16384
+ uuid: 208cc3c0a60c4eab6ed6861344fef0311c13ffd2
+ Linode 2048
+ bandwidth: 800
+ disk: 81920
+ id: 5
+ name: Linode 2048
+ ram: 2048
+ uuid: 0c9ee69dc7ef7a4cdce71963f8d18e76c61dd57f
+ Linode 20GB
+ bandwidth: 2000
+ disk: 819200
+ id: 10
+ name: Linode 20GB
+ ram: 20480
+ uuid: e0a7b61e3830a120eec94459c9fc34ef7c9e0e36
+ Linode 4GB
+ bandwidth: 1600
+ disk: 163840
+ id: 6
+ name: Linode 4GB
+ ram: 4096
+ uuid: 09585e0f1d4ef4aad486cfa3d53f9d8960f575e7
+ Linode 512
+ bandwidth: 200
+ disk: 20480
+ id: 1
+ name: Linode 512
+ ram: 512
+ uuid: 3497f7def3d6081e6f65ac6e577296bc6b810c05
+ Linode 768
+ bandwidth: 300
+ disk: 30720
+ id: 2
+ name: Linode 768
+ ram: 768
+ uuid: da9f0dbc144aaa234aa5d555426863c8068a8c70
+ Linode 8GB
+ bandwidth: 2000
+ disk: 327680
+ id: 7
+ name: Linode 8GB
+ ram: 8192
+ uuid: e08f8a57551297b9310545430c67667f59120606
+.ft P
+.fi
+.SS Destroy!
+.sp
+Salt Cloud can now destroy cloud vms as easily as it can create them. The new
+\fB\-\-destroy\fP option can be passed to end the life of a vm:
+.sp
+.nf
+.ft C
+$ salt\-cloud \-d web1
+.ft P
+.fi
+.sp
+The map operation can now also destroy vms, the new \fBhard\fP option can be
+passed which makes vm maps much more stateful. With the \fBhard\fP option the
+vm maps are viewed as the absolute source of information for the state of
+cloud resources, and any vm that is not specified in the map file will be
+destroyed:
+.sp
+.nf
+.ft C
+[root@saltmaster]# salt\-cloud \-m /etc/salt/cloud.map \-H
+The following virtual machines are set to be created:
+ web1
+ riak4
+The following virtual machines are set to be destroyed:
+ app7
+ devtest4
+
+Proceed? [N/y]
+.ft P
+.fi
+.SS Salt Cloud 0.8.0 Release Notes
+.sp
+Salt Cloud has reached another milestone, with the 0.8.0 release. This
+release includes many improvements to usability, error handling and general
+stability of the product.
+.SS Documentation
+.sp
+The documentation for Salt Cloud can be found on Read the Docs:
+\fI\%http://salt-cloud.readthedocs.org\fP
+.SS Download
+.sp
+Salt Cloud can be downloaded and install via pypi or github:
+.sp
+\fI\%http://pypi.python.org/packages/source/s/salt-cloud/salt-cloud-0.8.0.tar.gz\fP
+.sp
+\fI\%https://github.com/downloads/saltstack/salt-cloud/salt-cloud-0.8.0.tar.gz\fP
+.sp
+Some packages have been made available for salt\-cloud and more on on their
+way. Packages for Arch, and FreeBSD are being made available thanks to the
+work of Christer Edwards, and packages for RHEL and Fedora are being created
+by Clint Savage. Package availability will be announced on the salt mailing list.
+.SS Increased Formatting Options
+.sp
+Additional options have been added to salt\-cloud \-Q, to support the same kinds
+of formatting already available in Salt:
+.sp
+.nf
+.ft C
+\-\-raw\-out
+\-\-text\-out
+\-\-yaml\-out
+\-\-json\-out
+\-\-no\-color
+.ft P
+.fi
+.SS More Helpful Error Messages
+.sp
+As an ongoing effort, we have been cleaning up and adding error messages in an
+attempt to make salt\-cloud more helpful when something goes wrong. This
+includes displaying messages as they are received from libcloud.
+.SS Specify Grains in Map Files
+.sp
+Previously, map files only had the ability to specify a profile name, and the
+node names that would be associated with it. Now you can also specify grains
+that will be laid down in each individual node:
+.sp
+.nf
+.ft C
+vm_profile:
+ \- mynodename:
+ minion:
+ master: salt\-master
+ grains:
+ fromage: tasty
+.ft P
+.fi
+.sp
+These grains can also be specified in the profile itself. When this happens,
+the grains in map files will override grains in the profile. For example:
+.sp
+.nf
+.ft C
+vm_profile:
+ provider: gogrid
+ size: 512MB
+ image: CentOS 6.2 (64\-bit) w/ None
+ os: RHEL6
+ minion:
+ master: salt.mycompany.com
+ grains:
+ french: fries
+.ft P
+.fi
+.sp
+In this example, mynodename will include grains for both fromage and french,
+but the master will be salt\-master, not salt\-mycompany.com.
+.SS AWS Improvements
+.sp
+AWS is much more complex to work with than any of the other supported cloud
+providers. As such, additional configuration has been added in order to
+accomodate their usage:
+.INDENT 0.0
+.TP
+.B AWS.ssh_username:
+Because AWS images can include a variety of different usernames for the
+initial login, this option allows you to specify which one(s) to use to
+install salt upon firstboot.
+.TP
+.B AWS.ssh_interface:
+AWS instances include both private and public IP addresses. By default,
+salt\-cloud will use the public IP to login. In situations where the
+salt\-master is also located within AWS, the private IP can be used instead.
+.TP
+.B AWS.location and AWS.availability_zone:
+These options allow you to specify from within salt\-cloud, which AWS
+locations your machines spin up in.
+.UNINDENT
+.SS Ubuntu Fixes
+.sp
+Ubuntu packages automatically start the service upon installation, and needed
+to be handled differently in the deploy script. Configuration is now laid down
+before the package is installed, so that the minion can make its initial start
+happen with the correct configuration.
+.SH SALT CLOUD 0.6.0 RELEASE NOTES
+.sp
+The new Salt project, Salt Cloud, is introduced with version 0.6.0. Salt Cloud
+has been developed to ease the automation and integration of Salt with public
+cloud providers by allowing cloud vms to be cleanly defined, created and
+automatically hooked back into a Salt Master.
+.sp
+While Salt Cloud is primarily made to build cloud vms to tie into a Salt Mater,
+it has been created in a generic way, so that it can be used to provision and
+hook systems of any type via the familiar Salt modules system.
+.sp
+This release supports three public cloud providers (all via libcloud),
+Amazon EC2, Rackspace Cloud and Linode.
+.SS Documentation
+.sp
+The documentation for Salt Cloud can be found on Read the Docs:
+\fI\%http://salt-cloud.readthedocs.org\fP
+.SS Download
+.sp
+Salt Cloud can be downloaded and install via pypi or github:
+.sp
+\fI\%http://pypi.python.org/packages/source/s/salt-cloud/salt-cloud-0.6.0.tar.gz\fP
+.sp
+\fI\%https://github.com/downloads/saltstack/salt-cloud/salt-cloud-0.6.0.tar.gz\fP
+.sp
+Packages are not yet available, Salt Cloud requires three dependencies, the
+salt libs, libcloud, and paramiko.
+.SS Extensible With Cloud Modules
+.sp
+The Salt loader system has been employed to make adding support for additional
+public cloud systems just as modular and simple as adding support for new
+package managers in Salt.
+.sp
+Adding support for a new cloud provider is extremely simple, just add a cloud
+module and everything cleanly links together.
+.SS Define VM Profiles
+.sp
+The way a vms is created is done via profiles. Profiles are used to define what
+properties a vm will have, the cloud provider, the size and the image.
+.sp
+.nf
+.ft C
+centos_rackspace:
+ provider: rackspace
+ image: CentOS 6.2
+ size: 1024 server
+ os: RHEL6
+ minion:
+ grains:
+ role: webserver
+ master: salt.example.com
+.ft P
+.fi
+.sp
+This profile will be used to create vms on Rackspace cloud with the CentOS 6.2
+image and the Rackspace 1024 vm size. Particulars of the minion config can
+also be specified.
+.sp
+Individual vms can be created from profiles:
+.sp
+.nf
+.ft C
+# salt\-cloud \-p centos_rackspace web1
+.ft P
+.fi
+.sp
+This command creates a vms with the name web1 on the Rackspace cloud and
+connects the new vm to a Salt Master located at salt.example.com. The new VM
+has the Salt id of web1.
+.SS Define Maps of Profiles
+.sp
+When it is desired to have a predefined mapping of many, or a specific group
+of vms then a cloud map can be defined:
+.sp
+.nf
+.ft C
+centos_rackspace:
+ web1
+ web2
+ web3
+ web4
+centos_linode:
+ redis1
+ riak1
+ riak2
+ riak3
+ubuntu_ec2:
+ dev1
+ dev2
+ cassandra1
+ cassandra2
+ cassandra3
+.ft P
+.fi
+.sp
+This map file will create vms named web 1\-4 using the centos_rackspace profile
+on rackspace, the redis and riak vms on linode and the dev and Cassandra vms on
+ec2. It can be run with salt\-cloud:
+.sp
+.nf
+.ft C
+# salt\-cloud \-m mapfile
+.ft P
+.fi
+.sp
+When creating more than one vm the \-P option can be passed, to make the vms
+provision in parallel, greatly speeding up large scale expansions of vms.
+.SH SALT CLOUD 0.7.0 RELEASE NOTES
+.sp
+Salt Cloud marches forward with the 0.7.0 release. As is customary for Salt
+Stack projects the 0.7.0 release is intended to be much more robust and
+deliver a more complete core feature set. Salt Cloud 0.7.0 is just that.
+.sp
+With new tools to help look into what is available on cloud providers,
+new additions to make cloud management more stateful and the addition of
+more supported cloud platforms 0.7.0 has greatly enhanced the capabilities
+of the overall Salt platform.
+.SS Documentation
+.sp
+The documentation for Salt Cloud can be found on Read the Docs:
+\fI\%http://salt-cloud.readthedocs.org\fP
+.SS Download
+.sp
+Salt Cloud can be downloaded and install via pypi or github:
+.sp
+\fI\%http://pypi.python.org/packages/source/s/salt-cloud/salt-cloud-0.7.0.tar.gz\fP
+.sp
+\fI\%https://github.com/downloads/saltstack/salt-cloud/salt-cloud-0.7.0.tar.gz\fP
+.sp
+Some packages have been made available for salt\-cloud and more on on their
+way. Packages for Arch, and FreeBSD are being made available thanks to the
+work of Christer Edwards, and packages for RHEL and Fedora are being created
+by Clint Savage. Package availability will be announced on the salt mailing list.
+.SS New Cloud Provider Support
+.sp
+The following cloud providers are now supported:
+.INDENT 0.0
+.TP
+.B Amazon AWS
+\fI\%http://aws.amazon.com/ec2/\fP
+.TP
+.B Rackspace Cloud
+\fI\%http://www.rackspace.com/cloud/\fP
+.TP
+.B Linode
+\fI\%http://www.linode.com/\fP
+.TP
+.B Joyent
+\fI\%http://joyent.com/\fP
+.TP
+.B GoGrid
+\fI\%http://www.gogrid.com/\fP
+.UNINDENT
+.SS List Available Resources
+.sp
+Setting up Salt Cloud requires knowlege of the available sizes and images on
+cloud providers. Listing the available images and sizes can now be done with
+the salt\-cloud command:
+.sp
+.nf
+.ft C
+[root@saltmaster]# salt\-cloud \-\-list\-sizes linode
+linode
+ Linode 1024
+ bandwidth: 400
+ disk: 40960
+ id: 3
+ name: Linode 1024
+ ram: 1024
+ uuid: 56e6f495190cb2ed1a343f7159ad447cf27d906d
+ Linode 12GB
+ bandwidth: 2000
+ disk: 491520
+ id: 8
+ name: Linode 12GB
+ ram: 12288
+ uuid: 3d1731ebefdbcb4c283957b43d45f89a01f67c5f
+ Linode 1536
+ bandwidth: 600
+ disk: 61440
+ id: 4
+ name: Linode 1536
+ ram: 1536
+ uuid: f0f28628cc70c5f2656aa3f313588d8509ee3787
+ Linode 16GB
+ bandwidth: 2000
+ disk: 655360
+ id: 9
+ name: Linode 16GB
+ ram: 16384
+ uuid: 208cc3c0a60c4eab6ed6861344fef0311c13ffd2
+ Linode 2048
+ bandwidth: 800
+ disk: 81920
+ id: 5
+ name: Linode 2048
+ ram: 2048
+ uuid: 0c9ee69dc7ef7a4cdce71963f8d18e76c61dd57f
+ Linode 20GB
+ bandwidth: 2000
+ disk: 819200
+ id: 10
+ name: Linode 20GB
+ ram: 20480
+ uuid: e0a7b61e3830a120eec94459c9fc34ef7c9e0e36
+ Linode 4GB
+ bandwidth: 1600
+ disk: 163840
+ id: 6
+ name: Linode 4GB
+ ram: 4096
+ uuid: 09585e0f1d4ef4aad486cfa3d53f9d8960f575e7
+ Linode 512
+ bandwidth: 200
+ disk: 20480
+ id: 1
+ name: Linode 512
+ ram: 512
+ uuid: 3497f7def3d6081e6f65ac6e577296bc6b810c05
+ Linode 768
+ bandwidth: 300
+ disk: 30720
+ id: 2
+ name: Linode 768
+ ram: 768
+ uuid: da9f0dbc144aaa234aa5d555426863c8068a8c70
+ Linode 8GB
+ bandwidth: 2000
+ disk: 327680
+ id: 7
+ name: Linode 8GB
+ ram: 8192
+ uuid: e08f8a57551297b9310545430c67667f59120606
+.ft P
+.fi
+.SS Destroy!
+.sp
+Salt Cloud can now destroy cloud vms as easily as it can create them. The new
+\fB\-\-destroy\fP option can be passed to end the life of a vm:
+.sp
+.nf
+.ft C
+$ salt\-cloud \-d web1
+.ft P
+.fi
+.sp
+The map operation can now also destroy vms, the new \fBhard\fP option can be
+passed which makes vm maps much more stateful. With the \fBhard\fP option the
+vm maps are viewed as the absolute source of information for the state of
+cloud resources, and any vm that is not specified in the map file will be
+destroyed:
+.sp
+.nf
+.ft C
+[root@saltmaster]# salt\-cloud \-m /etc/salt/cloud.map \-H
+The following virtual machines are set to be created:
+ web1
+ riak4
+The following virtual machines are set to be destroyed:
+ app7
+ devtest4
+
+Proceed? [N/y]
+.ft P
+.fi
.SH AUTHOR
Thomas S. Hatch <thatch45@gmail.com> and many others, please see the Authors file
.SH COPYRIGHT
2012, Thomas S Hatch
.\" Generated by docutils manpage writer.
+.\"
.
View
23 doc/ref/cli/salt-cloud.rst
@@ -96,6 +96,29 @@ Options
Specify an alternative location for the salt cloud profiles file.
Default location is /etc/salt/cloud.profiles.
+
+.. option:: --raw-out
+
+ Print the output from the salt command in raw python
+ form, this is suitable for re-reading the output into
+ an executing python script with eval.
+
+.. option:: --text-out
+
+ Print the output from the salt command in the same form the shell would.
+
+.. option:: --yaml-out
+
+ Print the output from the salt command in yaml.
+
+.. option:: --json-out
+
+ Print the output from the salt command in json.
+
+.. option:: --no-color
+
+ Disable all colored output.
+
Examples
========
View
10 doc/topics/aws.rst
@@ -23,6 +23,16 @@ Set up the cloud config at ``/etc/salt/cloud``:
# Set up an optional default cloud provider
provider: AWS
+ # Optionally configure default region
+ AWS.location: ap-southeast-1
+ AWS.availability_zone: ap-southeast-1b
+
+ # Specify whether to use public or private IP for deploy script
+ AWS.ssh_interface
+
+ # Configure which user to use to run the deploy script
+ AWS.ssh_username
+
Set up an initial profile at ``/etc/salt/cloud.profiles``:
.. code-block:: yaml
View
47 doc/topics/map.rst
@@ -13,22 +13,22 @@ machines to make from said profile:
.. code-block:: yaml
fedora_small:
- - web1
- - web2
- - web3
- - web3
- - web4
- - web5
+ - web1
+ - web2
+ - web3
+ - web3
+ - web4
+ - web5
fedora_high:
- - redis1
- - redis2
- - redis3
+ - redis1
+ - redis2
+ - redis3
cent_high:
- - riak1
- - riak2
- - riak3
- - riak4
- - riak5
+ - riak1
+ - riak2
+ - riak3
+ - riak4
+ - riak5
This map file can then be called to roll out all of these virtual machines. Map
files are called from the salt-cloud command with the -m option:
@@ -51,3 +51,22 @@ that exist but are not specified in the map file will be destroyed:
.. code-block:: bash
$ salt-cloud -m /path/to/mapfile -P -H
+
+A map file can include grains:
+
+.. code-block:: yaml
+
+ fedora_small:
+ - web1:
+ minion:
+ log_level: debug
+ grains:
+ cheese: tasty
+ omelet: du fromage
+ - web2:
+ minion:
+ log_level: warn
+ grains:
+ cheese: more tasty
+ omelet: with peppers
+
View
4 doc/topics/profiles.rst
@@ -24,9 +24,9 @@ public cloud provider. A number of additional paramaters can also be inserted:
size: 1024 server
os: RHEL6
minion:
- grains:
- role: webserver
master: salt.example.com
+ grains:
+ role: webserver
Some paramaters can be specified in the main Salt cloud config file and then
are applied to all cloud profiles. For instance if only a single cloud provider
View
4 doc/topics/releases/0.7.0.rst
@@ -6,7 +6,7 @@ Salt Cloud marches forward with the 0.7.0 release. As is customary for Salt
Stack projects the 0.7.0 release is intended to be much more robust and
deliver a more complete core feature set. Salt Cloud 0.7.0 is just that.
-With new tools to help look into what is availiable on cloud providers,
+With new tools to help look into what is available on cloud providers,
new additions to make cloud management more stateful and the addition of
more supported cloud platforms 0.7.0 has greatly enhanced the capabilities
of the overall Salt platform.
@@ -144,7 +144,7 @@ Salt Cloud can now destroy cloud vms as easily as it can create them. The new
$ salt-cloud -d web1
-The map opperation can now also destroy vms, the new ``hard`` option can be
+The map operation can now also destroy vms, the new ``hard`` option can be
passed which makes vm maps much more stateful. With the ``hard`` option the
vm maps are viewed as the absolute source of information for the state of
cloud resources, and any vm that is not specified in the map file will be
View
113 doc/topics/releases/0.8.0.rst
@@ -0,0 +1,113 @@
+==============================
+Salt Cloud 0.8.0 Release Notes
+==============================
+
+Salt Cloud has reached another milestone, with the 0.8.0 release. This
+release includes many improvements to usability, error handling and general
+stability of the product.
+
+Documentation
+=============
+
+The documentation for Salt Cloud can be found on Read the Docs:
+http://salt-cloud.readthedocs.org
+
+Download
+========
+
+Salt Cloud can be downloaded and install via pypi or github:
+
+http://pypi.python.org/packages/source/s/salt-cloud/salt-cloud-0.8.0.tar.gz
+
+https://github.com/downloads/saltstack/salt-cloud/salt-cloud-0.8.0.tar.gz
+
+Some packages have been made available for salt-cloud and more on on their
+way. Packages for Arch, and FreeBSD are being made available thanks to the
+work of Christer Edwards, and packages for RHEL and Fedora are being created
+by Clint Savage. Package availability will be announced on the salt mailing list.
+
+Increased Formatting Options
+============================
+
+Additional options have been added to salt-cloud -Q, to support the same kinds
+of formatting already available in Salt:
+
+::
+
+ --raw-out
+ --text-out
+ --yaml-out
+ --json-out
+ --no-color
+
+More Helpful Error Messages
+===========================
+
+As an ongoing effort, we have been cleaning up and adding error messages in an
+attempt to make salt-cloud more helpful when something goes wrong. This
+includes displaying messages as they are received from libcloud.
+
+Specify Grains in Map Files
+===========================
+
+Previously, map files only had the ability to specify a profile name, and the
+node names that would be associated with it. Now you can also specify grains
+that will be laid down in each individual node:
+
+.. code-block:: yaml
+
+ vm_profile:
+ - mynodename:
+ minion:
+ master: salt-master
+ grains:
+ fromage: tasty
+
+These grains can also be specified in the profile itself. When this happens,
+the grains in map files will override grains in the profile. For example:
+
+.. code-block:: yaml
+
+ vm_profile:
+ provider: gogrid
+ size: 512MB
+ image: CentOS 6.2 (64-bit) w/ None
+ os: RHEL6
+ minion:
+ master: salt.mycompany.com
+ grains:
+ french: fries
+
+In this example, mynodename will include grains for both fromage and french,
+but the master will be salt-master, not salt-mycompany.com.
+
+AWS Improvements
+================
+
+AWS is much more complex to work with than any of the other supported cloud
+providers. As such, additional configuration has been added in order to
+accomodate their usage:
+
+AWS.ssh_username:
+ Because AWS images can include a variety of different usernames for the
+ initial login, this option allows you to specify which one(s) to use to
+ install salt upon firstboot.
+
+AWS.ssh_interface:
+ AWS instances include both private and public IP addresses. By default,
+ salt-cloud will use the public IP to login. In situations where the
+ salt-master is also located within AWS, the private IP can be used instead.
+
+AWS.location and AWS.availability_zone:
+ These options allow you to specify from within salt-cloud, which AWS
+ locations your machines spin up in.
+
+Ubuntu Fixes
+============
+
+Ubuntu packages automatically start the service upon installation, and needed
+to be handled differently in the deploy script. Configuration is now laid down
+before the package is installed, so that the minion can make its initial start
+happen with the correct configuration.
+
+
View
4 saltcloud/cli.py
@@ -55,9 +55,9 @@ def _parse_cli(self):
parser.add_option(
'--version',
dest='version',
- default='',
+ default=False,
action='store_true',
- help='show program version number and exit')
+ help='Show program version number and exit')
parser.add_option('-p',
'--profile',
View
26 saltcloud/cloud.py
@@ -12,6 +12,7 @@
import saltcloud.utils
import saltcloud.loader
import salt.client
+import salt.utils
# Import third party libs
import yaml
@@ -143,14 +144,16 @@ def create(self, vm_):
priv, pub = saltcloud.utils.gen_keys(
saltcloud.utils.get_option('keysize', self.opts, vm_)
)
- saltcloud.utils.accept_key(self.opts['pki_dir'], pub, vm_['name'])
vm_['pub_key'] = pub
vm_['priv_key'] = priv
+ ok = False
try:
- self.clouds['{0}.create'.format(self.provider(vm_))](vm_)
+ ok = self.clouds['{0}.create'.format(self.provider(vm_))](vm_)
except KeyError as exc:
print('Failed to create vm {0}. Configuration value {1} needs '
'to be set'.format(vm_['name'], exc))
+ if ok != False:
+ saltcloud.utils.accept_key(self.opts['pki_dir'], pub, vm_['name'])
def run_profile(self):
'''
@@ -232,7 +235,8 @@ def map_data(self):
for name in pmap[prov]:
exist.add(name)
if name in ret['create']:
- ret['create'].pop(name)
+ if prov != 'aws' or pmap['aws'][name]['state'] != 2:
+ ret['create'].pop(name)
if self.opts['hard']:
# Look for the items to delete
ret['destroy'] = exist.difference(defined)
@@ -255,13 +259,23 @@ def run_map(self):
if not res.lower().startswith('y'):
return
# We are good to go, execute!
+ # Generate the fingerprint of the master pubkey in
+ # order to mitigate man-in-the-middle attacks
+ master_pub = self.opts['pki_dir'] + '/master.pub'
+ master_finger = ''
+ if os.path.isfile(master_pub) and hasattr(salt.utils, 'pem_finger'):
+ master_finger = salt.utils.pem_finger(master_pub)
for name, profile in dmap['create'].items():
tvm = copy.deepcopy(profile)
tvm['name'] = name
+ tvm['master_finger'] = master_finger
for miniondict in self.map[tvm['profile']]:
- if name in miniondict:
- tvm['map_grains'] = miniondict[name]['grains']
- tvm['map_minion'] = miniondict[name]['minion']
+ if isinstance(miniondict, dict):
+ if name in miniondict:
+ if 'grains' in miniondict[name]:
+ tvm['map_grains'] = miniondict[name]['grains']
+ if 'minion' in miniondict[name]:
+ tvm['map_minion'] = miniondict[name]['minion']
if self.opts['parallel']:
multiprocessing.Process(
target=lambda: self.create(tvm)
View
159 saltcloud/clouds/aws.py
@@ -68,14 +68,32 @@ def __virtual__():
return 'aws'
-def get_conn():
+EC2_LOCATIONS = {
+ 'ap-northeast-1': Provider.EC2_AP_NORTHEAST,
+ 'ap-southeast-1': Provider.EC2_AP_SOUTHEAST,
+ 'eu-west-1': Provider.EC2_EU_WEST,
+ 'sa-east-1': Provider.EC2_SA_EAST,
+ 'us-east-1': Provider.EC2_US_EAST,
+ 'us-west-1': Provider.EC2_US_WEST,
+ 'us-west-2': Provider.EC2_US_WEST_OREGON
+}
+DEFAULT_LOCATION = 'us-east-1'
+
+
+def get_conn(**kwargs):
'''
Return a conn object for the passed vm data
'''
- prov = 'EC2'
- if not hasattr(Provider, prov):
- return None
- driver = get_driver(getattr(Provider, 'EC2'))
+ if 'location' in kwargs:
+ location = kwargs['location']
+ if location not in EC2_LOCATIONS:
+ sys.stderr.write('The specified location does not seem to be valid: {0}\n'.format(location))
+ sys.exit(1)
+ return None #TODO raise exception
+ else:
+ location = DEFAULT_LOCATION
+
+ driver = get_driver(EC2_LOCATIONS[location])
return driver(
__opts__['AWS.id'],
__opts__['AWS.key'],
@@ -86,31 +104,83 @@ def keyname(vm_):
'''
Return the keyname
'''
- return str(vm_.get('AWS.keyname', __opts__.get('AWS.keyname', '')))
+ return str(vm_.get('keyname', __opts__.get('AWS.keyname', '')))
def securitygroup(vm_):
'''
- Return the keyname
+ Return the security group
'''
- return str(vm_.get(
- 'AWS.securitygroup',
- __opts__.get('AWS.securitygroup', 'default')
- ))
+ return vm_.get('securitygroup', __opts__.get('AWS.securitygroup', 'default'))
+ securitygroups = vm_.get('securitygroup', __opts__.get('AWS.securitygroup', 'default'))
+ if not isinstance(securitygroups, list):
+ securitygroup = securitygroups
+ securitygroups = [securitygroup]
+ return securitygroups
+
+
+def ssh_username(vm_):
+ '''
+ Return the ssh_username. Defaults to 'ec2-user'.
+ '''
+ usernames = vm_.get('ssh_username', __opts__.get('AWS.ssh_username', 'ec2-user'))
+ if not isinstance(usernames, list):
+ username = usernames
+ usernames = [username]
+ if not 'ec2-user' in usernames:
+ usernames.append('ec2-user')
+ if not 'root' in usernames:
+ usernames.append('root')
+ return usernames
+
+
+def ssh_interface(vm_):
+ '''
+ Return the ssh_interface type to connect to. Either 'public_ips' (default) or 'private_ips'.
+ '''
+ return vm_.get('ssh_interface', __opts__.get('AWS.ssh_interface', 'public_ips'))
+
+
+def get_location(vm_):
+ '''
+ Return the AWS region to use
+ '''
+ return vm_.get('location', __opts__.get('AWS.location', DEFAULT_LOCATION))
+
+
+def get_availability_zone(conn, vm_):
+ '''
+ Return the availability zone to use
+ '''
+ locations = conn.list_locations()
+ az = None
+ if 'availability_zone' in vm_:
+ az = vm_['availability_zone']
+ elif 'EC2.availability_zone' in __opts__:
+ az = __opts__['EC2.availability_zone']
+
+ if az is None:
+ # Default to first zone
+ return locations[0]
+ for loc in locations:
+ if loc.availability_zone.name == az:
+ return loc
def create(vm_):
'''
Create a single vm from a data dict
'''
- print('Creating Cloud VM {0}'.format(vm_['name']))
- conn = get_conn()
- kwargs = {'ssh_username': 'ec2-user',
- 'ssh_key': __opts__['AWS.private_key']}
+ location = get_location(vm_)
+ print('Creating Cloud VM {0} in {1}'.format(vm_['name'], location))
+ conn = get_conn(location=location)
+ usernames = ssh_username(vm_)
+ kwargs = {'ssh_key': __opts__['AWS.private_key']}
kwargs['name'] = vm_['name']
deploy_script = script(vm_)
kwargs['image'] = get_image(conn, vm_)
kwargs['size'] = get_size(conn, vm_)
+ kwargs['location'] = get_availability_zone(conn, vm_)
ex_keyname = keyname(vm_)
if ex_keyname:
kwargs['ex_keyname'] = ex_keyname
@@ -127,44 +197,33 @@ def create(vm_):
)
sys.stderr.write(err)
return False
+ print('Created node {0}'.format(vm_['name']))
while not data.public_ips:
time.sleep(0.5)
data = get_node(conn, vm_['name'])
- if saltcloud.utils.wait_for_ssh(data.public_ips[0]):
- fd_, path = tempfile.mkstemp()
- os.close(fd_)
- with open(path, 'w+') as fp_:
- fp_.write(deploy_script.script)
- cmd = ('scp -oStrictHostKeyChecking=no -i {0} {3} {1}@{2}:/tmp/deploy.sh ').format(
- __opts__['AWS.private_key'],
- 'ec2-user',
- data.public_ips[0],
- path,
- )
- if subprocess.call(cmd, shell=True) != 0:
- time.sleep(15)
- cmd = ('scp -oStrictHostKeyChecking=no -i {0} {3} {1}@{2}:/tmp/deploy.sh ').format(
- __opts__['AWS.private_key'],
- 'root',
- data.public_ips[0],
- path,
- )
- subprocess.call(cmd, shell=True)
- cmd = ('ssh -oStrictHostKeyChecking=no -t -i {0} {1}@{2} '
- '"sudo bash /tmp/deploy.sh"').format(
- __opts__['AWS.private_key'],
- 'root',
- data.public_ips[0],
- )
- else:
- cmd = ('ssh -oStrictHostKeyChecking=no -t -i {0} {1}@{2} '
- '"sudo bash /tmp/deploy.sh"').format(
- __opts__['AWS.private_key'],
- 'ec2-user',
- data.public_ips[0],
- )
- subprocess.call(cmd, shell=True)
- os.remove(path)
+ if ssh_interface(vm_) == "private_ips":
+ ip_address = data.private_ips[0]
+ else:
+ ip_address = data.public_ips[0]
+ if saltcloud.utils.wait_for_ssh(ip_address):
+ username = 'ec2-user'
+ for user in usernames:
+ if saltcloud.utils.wait_for_passwd(host=ip_address, username=user, timeout=60, key_filename=__opts__['AWS.private_key']):
+ username = user
+ break
+ kwargs['ssh_username'] = username
+ deployed = saltcloud.utils.deploy_script(
+ host=ip_address,
+ username=username,
+ key_filename=__opts__['AWS.private_key'],
+ deploy_command='sudo bash /tmp/deploy.sh',
+ tty=True,
+ script=deploy_script.script)
+ if deployed:
+ print('Salt installed on {0}'.format(vm_['name']))
+ else:
+ print('Failed to start Salt on Cloud VM {0}'.format(vm_['name']))
+
print('Created Cloud VM {0} with the following values:'.format(
vm_['name']
))
View
16 saltcloud/clouds/gogrid.py
@@ -23,7 +23,9 @@
# Import python libs
import os
+import subprocess
import types
+import paramiko
# Import libcloud
from libcloud.compute.types import Provider
@@ -70,13 +72,13 @@ def create(vm_):
'''
print('Creating Cloud VM {0}'.format(vm_['name']))
conn = get_conn()
+ deploy_script = script(vm_)
kwargs = {}
kwargs['name'] = vm_['name']
- kwargs['deploy'] = script(vm_)
kwargs['image'] = get_image(conn, vm_)
kwargs['size'] = get_size(conn, vm_)
try:
- data = conn.deploy_node(**kwargs)
+ data = conn.create_node(**kwargs)
except Exception as exc:
message = str(exc)
err = ('Error creating {0} on GOGRID\n\n'
@@ -86,6 +88,16 @@ def create(vm_):
)
sys.stderr.write(err)
return False
+ deployed = saltcloud.utils.deploy_script(
+ host=data.public_ips[0],
+ username='root',
+ password=data.extra['password'],
+ script=deploy_script.script)
+ if deployed:
+ print('Salt installed on {0}'.format(vm_['name']))
+ else:
+ print('Failed to start Salt on Cloud VM {0}'.format(vm_['name']))
+
print('Created Cloud VM {0} with the following values:'.format(
vm_['name']
))
View
15 saltcloud/clouds/linode.py
@@ -17,6 +17,7 @@
# Import python libs
import os
import types
+import paramiko
# Import libcloud
from libcloud.compute.types import Provider
@@ -92,15 +93,15 @@ def create(vm_):
'''
print('Creating Cloud VM {0}'.format(vm_['name']))
conn = get_conn()
+ deploy_script = script(vm_)
kwargs = {}
kwargs['name'] = vm_['name']
- kwargs['deploy'] = script(vm_)
kwargs['image'] = get_image(conn, vm_)
kwargs['size'] = get_size(conn, vm_)
kwargs['location'] = get_location(conn, vm_)
kwargs['auth'] = NodeAuthPassword(get_password(vm_))
try:
- data = conn.deploy_node(**kwargs)
+ data = conn.create_node(**kwargs)
except Exception as exc:
err = ('Error creating {0} on LINODE\n\n'
'The following exception was thrown by libcloud when trying to '
@@ -109,6 +110,16 @@ def create(vm_):
)
sys.stderr.write(err)
return False
+ deployed = saltcloud.utils.deploy_script(
+ host=data.public_ips[0],
+ username='root',
+ password=__opts__['LINODE.password'],
+ script=deploy_script.script)
+ if deployed:
+ print('Salt installed on {0}'.format(vm_['name']))
+ else:
+ print('Failed to start Salt on Cloud VM {0}'.format(vm_['name']))
+
print('Created Cloud VM {0} with the following values:'.format(
vm_['name']
))
View
16 saltcloud/clouds/rackspace.py
@@ -23,6 +23,8 @@
# Import python libs
import os
import types
+import paramiko
+import tempfile
# Import libcloud
from libcloud.compute.types import Provider
@@ -69,13 +71,13 @@ def create(vm_):
'''
print('Creating Cloud VM {0}'.format(vm_['name']))
conn = get_conn()
+ deploy_script = script(vm_)
kwargs = {}
kwargs['name'] = vm_['name']
- kwargs['deploy'] = script(vm_)
kwargs['image'] = get_image(conn, vm_)
kwargs['size'] = get_size(conn, vm_)
try:
- data = conn.deploy_node(**kwargs)
+ data = conn.create_node(**kwargs)
except DeploymentError as exc:
err = ('Error creating {0} on RACKSPACE\n\n'
'The following exception was thrown by libcloud when trying to '
@@ -84,6 +86,16 @@ def create(vm_):
)
sys.stderr.write(err)
return False
+ deployed = saltcloud.utils.deploy_script(
+ host=data.public_ips[0],
+ username='root',
+ password=data.extra['password'],
+ script=deploy_script.script)
+ if deployed:
+ print('Salt installed on {0}'.format(vm_['name']))
+ else:
+ print('Failed to start Salt on Cloud VM {0}'.format(vm_['name']))
+
print('Created Cloud VM {0} with the following values:'.format(
vm_['name']
))
View
12 saltcloud/deploy/Ubuntu.sh
@@ -1,12 +1,12 @@
#!/bin/bash
+mkdir -p /etc/salt/pki
+echo '{{ vm['priv_key'] }}' > /etc/salt/pki/minion.pem
+echo '{{ vm['pub_key'] }}' > /etc/salt/pki/minion.pub
+echo "{{ minion }}" > /etc/salt/minion
+
apt-get update
apt-get install -y python-software-properties
-add-apt-repository -y ppa:saltstack/salt
+echo | add-apt-repository ppa:saltstack/salt
apt-get update
apt-get install -y salt-minion
-mkdir -p /etc/salt/pki
-echo '{{ vm['priv_key'] }}' > /etc/salt/pki/minion.pem
-echo '{{ vm['pub_key'] }}' > /etc/salt/pki/minion.pub
-echo '{{ minion }}' > /etc/salt/minion
-service salt-minion start
View
103 saltcloud/utils/__init__.py
@@ -9,6 +9,8 @@
import socket
import tempfile
import time
+import paramiko
+import subprocess
# Import salt libs
import salt.crypt
@@ -103,13 +105,19 @@ def minion_conf_string(opts, vm_):
configuration file
'''
minion = {'id': vm_['name']}
+ if 'master_finger' in vm_:
+ minion['master_finger'] = vm_['master_finger']
minion.update(opts.get('minion', {}))
minion.update(vm_.get('minion', {}))
minion.update(opts.get('map_minion', {}))
minion.update(vm_.get('map_minion', {}))
- minion['grains'].update(opts.get('map_grains', {}))
- minion['grains'].update(vm_.get('map_grains', {}))
- return yaml.safe_dump(minion)
+ optsgrains = opts.get('map_grains', {})
+ if optsgrains:
+ minion['grains'].update(optsgrains)
+ vmgrains = vm_.get('map_grains', {})
+ if vmgrains:
+ minion['grains'].update(vmgrains)
+ return yaml.safe_dump(minion, default_flow_style=False)
def wait_for_ssh(host, port=22, timeout=900):
@@ -124,6 +132,95 @@ def wait_for_ssh(host, port=22, timeout=900):
sock.shutdown(2)
return True
except Exception:
+ time.sleep(1)
if time.time() - start > timeout:
return False
+
+def wait_for_passwd(host, port=22, timeout=900, username='root',
+ password=None, key_filename=None, maxtries=50,
+ trysleep=1):
+ '''
+ Wait until ssh connection can be accessed via password or ssh key
+ '''
+ start = time.time()
+ trycount=0
+ while True:
+ try:
+ ssh = paramiko.SSHClient()
+ ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
+ kwargs = {'hostname': host,
+ 'port': 22,
+ 'username': username,
+ 'timeout': 15}
+ if password and not key_filename:
+ kwargs['password'] = password
+ if key_filename:
+ kwargs['key_filename'] = key_filename
+ try:
+ ssh.connect(**kwargs)
+ except (paramiko.AuthenticationException, paramiko.SSHException) as authexc:
+ trycount += 1
+ print('Authentication error (try {0} of {1}): {2}'.format(trycount, maxtries, authexc))
+ if trycount < maxtries:
+ sleep(trysleep)
+ continue
+ else:
+ print('Authencication failed: {0}'.format(authexec))
+ return False
+ except Exception as exc:
+ print('There was an error in wait_for_passwd: {0}'.format(exc))
+ return True
+ except Exception:
+ time.sleep(1)
+ if time.time() - start > timeout:
+ return False
+
+def deploy_script(host, port=22, timeout=900, username='root',
+ password=None, key_filename=None, script=None,
+ deploy_command='bash /tmp/deploy.sh', tty=None):
+ '''
+ Copy a deploy script to a remote server, execute it, and remove it
+ '''
+ if wait_for_ssh(host=host, port=port, timeout=timeout):
+ if wait_for_passwd(host, port=port, username=username, password=password, key_filename=key_filename, timeout=timeout):
+ ssh = paramiko.SSHClient()
+ ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
+ kwargs = {'hostname': host,
+ 'port': 22,
+ 'username': username,
+ 'timeout': 15}
+ if password and not key_filename:
+ kwargs['password'] = password
+ if key_filename:
+ kwargs['key_filename'] = key_filename
+ try:
+ ssh.connect(**kwargs)
+ except Exception as exc:
+ print('There was an error in deploy_script: {0}'.format(exc))
+ tmpfh, tmppath = tempfile.mkstemp()
+ tmpfile = open(tmppath, 'w')
+ tmpfile.write(script)
+ tmpfile.close()
+ sftp = ssh.get_transport()
+ sftp.open_session()
+ sftp = paramiko.SFTPClient.from_transport(sftp)
+ sftp.put(tmppath, '/tmp/deploy.sh')
+ os.remove(tmppath)
+ ssh.exec_command('chmod +x /tmp/deploy.sh')
+ if tty:
+ # Tried this with paramiko's invoke_shell(), and got tired of
+ # fighting with it
+ cmd = ('ssh -oStrictHostKeyChecking=no -t -i {0} {1}@{2} "sudo bash /tmp/deploy.sh"').format(
+ key_filename,
+ username,
+ host
+ )
+ subprocess.call(cmd, shell=True)
+ else:
+ stdin, stdout, stderr = ssh.exec_command(deploy_command)
+ for line in stdout:
+ sys.stdout.write(line)
+ ssh.exec_command('rm /tmp/deploy.sh')
+ return True
+ return False
View
2  saltcloud/version.py
@@ -1,2 +1,2 @@
-__version_info__ = (0, 7, 0)
+__version_info__ = (0, 8, 0)
__version__ = '.'.join(map(str, __version_info__))
Please sign in to comment.
Something went wrong with that request. Please try again.