-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtask-arguments-and-variables.html
More file actions
319 lines (316 loc) · 16.9 KB
/
Copy pathtask-arguments-and-variables.html
File metadata and controls
319 lines (316 loc) · 16.9 KB
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
<html>
<head>
<title>Tash Arguments and Variables - Droid PHP</title>
<meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link href="https://maxcdn.bootstrapcdn.com/bootswatch/3.3.7/flatly/bootstrap.min.css" rel="stylesheet" integrity="sha384-+ENW/yibaokMnme+vBLnHMphUYxHs34h9lpdbSLuAwGkOKFRl4C34WkjazBtb7eT" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.8.0/styles/monokai.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.8.0/highlight.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.8.0/languages/yaml.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.8.0/languages/php.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-md-3">
<h1>Navigation</h1>
<ul>
<li><a href="/index.html">Home</a></li>
<li><a href="/getting-started.html">Getting started</a></li>
<li><a href="/task-arguments-and-variables.html" title="Task Arguments and Variables">Task Arguments and Variables</a></li>
<li><a href="/enable-remote-command-execution.html" title="Enable Remote Command Execution">Enable remote command execution</a></li>
<li><a href="/configuration-reference/index.html" title="Configuration Reference">Configuration reference</a>
<ul>
<li><a href="/configuration-reference/project.html" title="Project Configuration">Project</a></li>
<li><a href="/configuration-reference/target.html" title="Target Configuration">Target</a></li>
<li><a href="/configuration-reference/task.html" title="Task Configuration">Task</a></li>
<li><a href="/configuration-reference/host.html" title="Host Configuration">Host</a></li>
<li><a href="/configuration-reference/group.html" title="Group Configuration">Group</a></li>
<li><a href="/configuration-reference/firewall-rule.html" title="Firewall Rule Configuration">Firewall Rule</a></li>
<li><a href="/configuration-reference/module.html" title="Module Configuration">Module</a></li>
</ul>
</li>
<li><a href="/modules.html" title="Modules">Modules - reusable Task lists</a></li>
<li><a href="/command-reference/index.html" title="Command Reference">Command Reference</a></li>
<li><a href="/command-plugins.html" title="Command Plugins">Command Plugins</a></li>
<li><a href="/hacking.html" title="Hacking - Contributor's Guide">Hacking</a></li>
</ul>
</div>
<div class="col-md-6">
<h1>Task Arguments and Variables</h1>
<p>There are two ways to provide Droid with data needed to execute Commands. The
first is the direct supply of data, in the form of command arguments, when
running Droid Commands from the command line:-</p>
<pre><code class="language-shell">$ vendor/bin/droid fs:mkdir --mode="0750" /path/to/new/directory
$ vendor/bin/droid fs:copy my-file /path/to/new/directory/</code></pre>
<p>The second is through the use of <strong>Task Arguments</strong> and <strong>Variables</strong> when
Droid executes the Targets of a Droid Project:-</p>
<pre><code class="language-yaml">variables:
deployment:
source:
path: "my-file"
destination:
path: "/path/to/new/directory"
mode: "0750"
targets:
deploy:
tasks:
- name: "Create the destination"
command: "fs:mkdir"
arguments:
directory: "{{ deployment.destination.path }}"
mode: "{{ deployment.destination.mode }}"
- name: "Copy my file to the destination"
command: "fs:copy"
arguments:
src: "{{ deployment.source.path }}"
dest: "{{ deployment.destination.path }}/"</code></pre>
<p>The benefits of this approach are realised when we want to be able to repeat
the execution of Commands in the future, or with different data, or on multiple
Hosts.</p>
<h2>Task Arguments</h2>
<p>Droid processes Task arguments to resolve them into the values it will provide
to a Command. There are three forms of Task argument which differ by the
processing applied to them.</p>
<p>A literal value is not processed; it is passed unchanged to the Command:-</p>
<pre><code class="language-yaml">command: "debug:echo"
arguments:
message: "Hello"</code></pre>
<p>In the above example, the <code>message</code> argument is the literal string of
characters <code>Hello</code> which will be printed by the <code>debug:echo</code> Command.</p>
<p>A placeholder is replaced by the corresponding Variable value:-</p>
<pre><code class="language-yaml">command: "debug:echo"
arguments:
message: "Hello {{ username }}"</code></pre>
<p>In the above example, the <code>{{ username }}</code> placeholder is replaced with the
value of a Variable named <code>username</code>.</p>
<p>The third form of Task Argument is a path to a file which, when prefixed with
the <code>@</code> character, is replaced by the encoded content of the file at that path.
See the section entitled "<strong>File Arguments</strong>" for more detail.</p>
<p>Finally, a Task Argument can combine all three forms:-</p>
<pre><code class="language-yaml">arguments:
file: "@/path/to/folder/{{ filename }}"</code></pre>
<h3>Placeholder syntax</h3>
<p>Placeholders are processed using the Twig template engine and their syntax is
therefore <a href="http://twig.sensiolabs.org/doc/templates.html" title="Twig for Template Designers">Twig syntax</a>. Twig is greatly expressive; this is a
basic introduction to its syntax.</p>
<p>At its simplest, there is the replacement of a named variable with its value:-</p>
<pre><code class="language-twig">"The sky looks {{ colour }}."</code></pre>
<p>might be transformed to:-</p>
<pre><code class="language-text">"The sky looks cyan."</code></pre>
<p>There is "dot notation" for referencing nested variables or attributes of an
object; given the following variables:-</p>
<pre><code class="language-yaml">variables:
user_account:
name: "alice"
password: "5ekre7"</code></pre>
<p>the following is transformed:-</p>
<pre><code class="language-twig">"The password of {{ user_account.name }} is {{ user_account.password }}"</code></pre>
<p>into:-</p>
<pre><code class="language-text">"The password of alice is 5ekre7"</code></pre>
<p>There are a number of useful <a href="http://twig.sensiolabs.org/doc/filters/index.html" title="Twig Filters">filters</a>, such as</p>
<pre><code class="language-twig">"Hello there {{ user_account.name|capitalize }}."</code></pre>
<p>which becomes:-</p>
<pre><code class="language-text">"Hello there Alice."</code></pre>
<p>The <a href="http://twig.sensiolabs.org/doc/templates.html" title="Twig for Template Designers">Twig syntax documentation</a> is comprehensive and recommended
reading, especially when constructing template files. Bear in mind, when
reading the documentation, these points about the way the Twig engine is used
by Droid:-</p>
<ul>
<li>HTML escaping is not done by default. Use the <a href="http://twig.sensiolabs.org/doc/filters/escape.html" title="Twig filter: escape"><code>escape</code></a>
filter when escaping is a requirement.</li>
<li>Twig will not silently ignore attempted use of variables or attributes that
do not exist. It will complain loudly and halt execution.</li>
<li>Caching of templates is disabled.</li>
<li>Twig expects characters in the UTF-8 character set.</li>
</ul>
<h3>File Arguments</h3>
<p>When a Task Argument is given as a path to a file and prefixed with the <code>@</code>
character it is replaced by the content of that file. The content is
transformed into a base64, binary data URI. It looks like this:-</p>
<pre><code class="language-text">data:application/octet-stream;base64,RHJvaWQgd2FzICdlcmUuCg==</code></pre>
<p>This is primarily useful when copying a relatively small file to a remote Host,
using the <code>fs:copy</code> Command. This mechanism avoids the need for a separate
step to copy the file from host to host: the content of the file is given
directly to the <code>fs:copy</code> Command on the remote Host, as the <code>src</code> argument.
For example, given the following Task:-</p>
<pre><code class="language-yaml">name: "Copy a file"
command: "fs:copy"
arguments:
src: "@/path/to/a/file"
dest: "/usr/local/share/my-file.txt"
hosts: my_host</code></pre>
<p>might become the following command, executed on the Host <code>my_host</code>:-</p>
<pre><code class="language-shell">$ /usr/local/droid/vendor/bin/droid fs:copy \
data:application/octet-stream;base64,RHJvaWQgd2FzICdlcmUuCg== \
/usr/local/share/my-file.txt</code></pre>
<p>Additionally, when the name of the file given as a Task Argument ends with
".template" or ".twig", Droid processes the file content as a file template.
The content is rendered by the Twig engine in exactly the same way as the
aforementioned placeholders in Task Arguments and with same set of Variables.
For example, given the following file template:-</p>
<pre><code class="language-twig">{# This file is a template and this is a comment within it #}
Hello {{ name|capitalize }}.</code></pre>
<p>and the following Variables and Task:</p>
<pre><code class="language-yaml">variables:
name: "joshua"
tasks:
- name: "Copy a template file"
command: "fs:copy"
arguments:
src: "@/path/to/some.template"
dest: "/usr/local/share/my-file.txt"</code></pre>
<p>the content of the file becomes the following:-</p>
<pre><code class="language-text">Hello Joshua.</code></pre>
<p>before being encoded into a data uri:-</p>
<pre><code class="language-text">data:application/octet-stream;base64,SGVsbG8gSm9zaHVhLgo=</code></pre>
<p>Read on to find out how Droid assembles a set of Variables for the arguments of
a particular Command invocation.</p>
<h2>Variables</h2>
<p>Variables hold the data of a Droid Project. They are mappings of arbitrary
names to values. A value may be a string of characters, a number, a list or a
mapping. For example:-</p>
<pre><code class="language-yaml">variables:
shape: "line"
length: 2048
points:
- {x: 0}
- {x: 512, y: 64}
- x: 768
y: 128
z: -64
point_conf:
colour: "blue"
size: 1</code></pre>
<p>Droid assembles a set of Variables for each individual invocation of a Command.
It then transforms Task Arguments into the arguments to a command, replacing
placeholders with values from the assembled Variables.</p>
<h3>Assembling a data set</h3>
<p>Variables may be declared in various places in a Droid Project and these are
merged in a specific order before use in Task Arguments. Variables are merged
from the least specific to the most specific so that the result is a
combination of them all. More specific values take the place of less specific
ones with the same Variable name. The various Variables are, in order of
increasing specificity:-</p>
<ul>
<li>Module Variables</li>
<li>Project Variables</li>
<li>Target Variables</li>
<li>Group Variables</li>
<li>Host Variables</li>
</ul>
<p>By way of example, in the following Project:-</p>
<pre><code class="language-yaml">variables:
dns:
domain_name: "example.com"
server: "ns1.example.com"
hosts:
web-01:
variables:
dns:
domain_name: "apps.example.com"
db-master:
variables:
replication_role: "master"</code></pre>
<p>the variables available to Tasks to be executed on the Host <code>web-01</code> are:-</p>
<pre><code class="language-yaml">dns:
domain_name: "apps.example.com"
server: "ns1.example.com"</code></pre>
<p>That is, the Host inherits the <code>dns.server</code> Variable and overrides the value of
<code>dns.domain_name</code>. For the Host <code>db-master</code>:-</p>
<pre><code class="language-yaml">dns:
domain_name: "example.com"
server: "ns1.example.com"
replication_role: "master"</code></pre>
<p>That is, the Host inherits all of the values of <code>dns</code> and augments the
Variables with its <code>replication_role</code>.</p>
<p>A more detailed look at the various places to define Variables follows.</p>
<h4>Module Variables</h4>
<p>A Module is a reusable list of Tasks and its Variables are meant to hold
sensible default values for those Tasks. A Project which makes use of a Module
is expected to override the default values with ones that have some meaning
within the Project. As such, Module Variables are the least specific.</p>
<h4>Project Variables</h4>
<p>Project Variables hold the next more specific values. They are intended to be
a central repository of Project data available to all Tasks. Project data can
easily be augmented with extra data or, where necessary, some or all of the
data can be replaced by more specific data.</p>
<h4>Target Variables</h4>
<p>A Target is a list of Tasks which, like a recipe, is intended to achieve a
particular goal. Target Variables hold the next more specific values and are
intended to provide to its Tasks the kind of data which aren't meaningful to
Tasks in other Targets.</p>
<p>Another use for Target Variables is to provide data to the Tasks of a Module
which the Target incorporates. This use of Target Variables allows the Module
to be used in multiple Targets and to provide different data for each usage.</p>
<h4>Group Variables</h4>
<p>A Group is a logical collection of Hosts, such as a group of web servers.
Group Variables hold the next more specific values and are intended for the
association of data with all members of the Group. The Variables of a
particular Group are available to only those Task Arguments applicable to its
member Hosts. The Variables of all Groups of which a Host is a member are made
available to the applicable Task Arguments.</p>
<h4>Host Variables</h4>
<p>Host Variables hold the most specific values and are intended to apply to a
particular Host. When a Command is to be executed on a Host, its Variables are
available to the Task Arguments, along with all that it inherits.</p>
<h3>Dynamic Variables</h3>
<p>Sometimes the value of a Variable needs to be some attribute of a Host or Group
in Droid's inventory. For example, a number of Tasks might need to refer to
the <code>public_ip</code> address of a Host. This is achieved with the dynamic variable
syntax, which is an expression surrounded by a pair of <code>%</code> characters:-</p>
<pre><code class="language-yaml">variables:
web_servers:
- "%web-01.public_ip%"
- "%web-02.public_ip%"</code></pre>
<p>Such expressions are evaluated during the initial processing of the Droid
Project configuration. A name, which precedes the first dot, is resolved to
either a Host or a Group in Droid's inventory. Then a named attribute, which
is everything after the first dot, is resolved to an attribute of the resulting
object.</p>
<h3>Magic data</h3>
<p>There are occasions when a magic value is inserted into the set of data
available to the Task Arguments of a particular invocation. These values are
inserted in specific circumstances and are named:</p>
<ul>
<li><code>host</code></li>
<li><code>item</code></li>
<li><code>mod_path</code></li>
</ul>
<h4><code>host</code></h4>
<p>The <code>host</code> magic value is made available to Task Arguments for a Command to be
executed on a Host. Its value is an object which represents that Host. The
Task Arguments are therefore able to refer to attributes of that Host by using
Twig's "dot notation". For example:-</p>
<pre><code class="language-yaml">name: "Print some info about a Host"
command: "debug:echo"
arguments:
message: "I am {{ host.name }} at {{ host.public_ip }}."
hosts: "web_servers"</code></pre>
<p>The above example will run the command on each Host in a Group named
<code>web_servers</code> and the name and IP address of the Host will be printed in each
case.</p>
<h4><code>item</code></h4>
<p>The <code>item</code> magic value is made available to Task Arguments for a Command
intended to be executed repeatedly, each time with a different item of data.
Its value is the current item of data. For example:-</p>
<pre><code class="language-yaml">name: "Touch some files"
command: "fs:touch"
arguments:
file: "/var/www/{{ item.name }}"
mtime: "{{ item.time }}
with_items:
- {path: "index.php", time: "now"}
- {path: "index.htm", time: "last Tuesday"}</code></pre>
<h4><code>mod_path</code></h4>
<p>The <code>mod_path</code> magic value is made available to Task Arguments of Tasks in
Modules. The value is the path to the root of the Module installation and is
intended to enable Modules to locate assets, such as file templates, which they
provide.</p>
</div>
<div class="col-md-3"></div>
</div>
</div>
</body>
</html>