/
deployment.py
129 lines (107 loc) · 3.72 KB
/
deployment.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# 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