| # Licensed to the Apache Software Foundation (ASF) under one or more |
| # contributor license agreements. See the NOTICE file distributed with |
| # this work for additional information regarding copyright ownership. |
| # libcloud.org licenses this file to You 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. |
| |
| """ |
| Provides generic deployment steps for machines post boot. |
| """ |
| import os |
| |
| class Deployment(object): |
| """ |
| Base class for deployment tasks. |
| """ |
| |
| def run(self, node, client): |
| """ |
| Runs this deployment task on C{node} using the C{client} provided. |
| |
| @type node: L{Node} |
| @keyword node: Node to operate one |
| |
| @type client: L{BaseSSHClient} |
| @keyword client: Connected SSH client to use. |
| |
| @return: L{Node} |
| """ |
| raise NotImplementedError, \ |
| 'run not implemented for this deployment' |
| |
| |
| class SSHKeyDeployment(Deployment): |
| """ |
| Installs a public SSH Key onto a host. |
| """ |
| |
| def __init__(self, key): |
| """ |
| @type key: C{str} |
| @keyword key: Contents of the public key write |
| """ |
| self.key = key |
| |
| def run(self, node, client): |
| """ |
| Installs SSH key into C{.ssh/authorized_keys} |
| |
| See also L{Deployment.run} |
| """ |
| client.put(".ssh/authorized_keys", contents=self.key) |
| return node |
| |
| class ScriptDeployment(Deployment): |
| """ |
| Runs an arbitrary Shell Script task. |
| """ |
| |
| def __init__(self, script, name=None, delete=False): |
| """ |
| @type script: C{str} |
| @keyword script: Contents of the script to run |
| |
| @type name: C{str} |
| @keyword name: Name of the script to upload it as, if not specified, a random name will be choosen. |
| |
| @type delete: C{bool} |
| @keyword delete: Weither to delete the script on completion. |
| """ |
| self.script = script |
| self.stdout = None |
| self.stderr = None |
| self.delete = delete |
| self.name = name |
| if self.name is None: |
| self.name = "/root/deployment_%s.sh" % (os.urandom(4).encode('hex')) |
| |
| def run(self, node, client): |
| """ |
| Uploads the shell script and then executes it. |
| |
| See also L{Deployment.run} |
| """ |
| client.put(path=self.name, chmod=755, contents=self.script) |
| self.stdout, self.stderr = client.run(self.name) |
| if self.delete: |
| client.delete(self.name) |
| return node |
| |
| class MultiStepDeployment(Deployment): |
| """ |
| Runs a chain of Deployment steps. |
| """ |
| def __init__(self, add = None): |
| """ |
| @type add: C{list} |
| @keyword add: Deployment steps to add. |
| """ |
| self.steps = [] |
| self.add(add) |
| |
| def add(self, add): |
| """Add a deployment to this chain. |
| |
| @type add: Single L{Deployment} or a C{list} of L{Deployment} |
| @keyword add: Adds this deployment to the others already in this object. |
| """ |
| if add is not None: |
| add = add if isinstance(add, (list, tuple)) else [add] |
| self.steps.extend(add) |
| |
| def run(self, node, client): |
| """ |
| Run each deployment that has been added. |
| |
| See also L{Deployment.run} |
| """ |
| for s in self.steps: |
| node = s.run(node, client) |
| return node |