1 from buildbot
.plugins
import *
2 from buildbot_common
.build_helpers
import *
4 from buildbot
.util
import bytes2unicode
6 from functools
import partial
8 __all__
= [ "configure", "E" ]
12 BUILDBOT_URL
= "https://git.immae.eu/buildbot/{}/".format(PROJECT
)
13 SOCKET
= "unix:/run/buildbot/{}.sock".format(PROJECT
)
14 PB_SOCKET
= "unix:address=/run/buildbot/{}_pb.sock".format(PROJECT
)
15 SSH_KEY_PATH
= "/var/lib/buildbot/buildbot_key"
16 SSH_HOST_KEY
= "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIFbhFTl2A2RJn5L51yxJM4XfCS2ZaiSX/jo9jFSdghF"
17 XMPP_RECIPIENTS
= os
.environ
["BUILDBOT_XMPP_RECIPIENTS"].split(" ")
19 BIP39_GIT_URL
= "https://git.immae.eu/perso/Immae/Projets/Cryptomonnaies/BIP39.git"
20 IMMAE_EU_GIT_URL
= "gitolite@git.immae.eu:perso/Immae/Sites/Blog"
21 HISTORY_GIT_URL
= "gitolite@git.immae.eu:perso/Immae/Sites/History"
22 RECETTES_GIT_URL
= "gitolite@git.immae.eu:perso/Immae/Sites/Recettes"
23 COURS_GIT_URL
= "gitolite@git.immae.eu:perso/Immae/Sites/Cours"
24 DOCS_GIT_URL
= "gitolite@git.immae.eu:perso/Immae/Sites/Docs"
25 NORMALESUP_GIT_URL
= "gitolite@git.immae.eu:perso/Immae/Projets/Sites/Normalesup"
27 COURS_RELEASE_PATH
= "/var/lib/buildbot/outputs/immae/cours"
28 COURS_TARBALL_PATH
= "/var/lib/ftp/release.immae.eu/cours"
29 COURS_TARBALL_URL
= "https://release.immae.eu/cours"
30 BIP39_RELEASE_PATH
= "/var/lib/buildbot/outputs/immae/bip39"
31 HISTORY_RELEASE_PATH
= "/var/lib/buildbot/outputs/immae/history"
32 IMMAE_EU_RELEASE_PATH
= "/var/lib/buildbot/outputs/immae/blog"
33 DOCS_RELEASE_PATH
= "/var/lib/buildbot/outputs/immae/docs"
34 RECETTES_RELEASE_PATH
= "/var/lib/buildbot/outputs/immae/recettes"
35 NORMALESUP_RELEASE_PATH
= "/var/lib/buildbot/outputs/immae/recherche"
36 GSMCELLS_RELEASE_PATH
= "/var/lib/ftp/release.immae.eu/gsm_cells"
37 GSMCELLS_RELEASE_URL
= "https://release.immae.eu/gsm_cells"
40 SECRETS_FILE
= os
.getcwd() + "/secrets"
41 LDAP_URL
= "ldaps://ldap.immae.eu:636"
42 LDAP_ADMIN_USER
= "cn=buildbot,ou=services,dc=immae,dc=eu"
43 LDAP_BASE
= "dc=immae,dc=eu"
44 LDAP_PATTERN
= "(uid=%(username)s)"
45 LDAP_GROUP_PATTERN
= "(&(memberOf=cn=groups,ou=immaeEu,cn=buildbot,ou=services,dc=immae,dc=eu)(member=%(dn)s))"
46 TITLE_URL
= "https://www.immae.eu"
47 TITLE
= "Immae website"
50 c
["buildbotURL"] = E
.BUILDBOT_URL
51 c
["www"]["port"] = E
.SOCKET
53 worker_name
= "generic-worker-immae-eu"
54 c
['workers'].append(worker
.LocalWorker(worker_name
))
59 withoutbranch
.append(configure_gsm_cells(c
, worker_name
))
61 withbranch
.append(_configure("immae_eu", immae_eu_build_factory
, c
, worker_name
))
62 withbranch
.append(_configure("normalesup", normalesup_build_factory
, c
, worker_name
))
63 withbranch
.append(_configure("cours", cours_build_factory
, c
, worker_name
))
64 withbranch
.append(_configure("recettes", recettes_build_factory
, c
, worker_name
))
65 withbranch
.append(_configure("docs", docs_build_factory
, c
, worker_name
))
66 withbranch
.append(_configure("history", history_build_factory
, c
, worker_name
))
67 withbranch
.append(_configure("bip39", bip39_build_factory
, c
, worker_name
))
69 withbranch
.append(_configure_symfony("Chloe", c
, worker_name
,
70 "gitolite@git.immae.eu:perso/Immae/Sites/Chloe/New"))
71 withbranch
.append(_configure_symfony("Florian", c
, worker_name
,
72 "gitolite@git.immae.eu:perso/florian_telles/stabilo"))
73 withbranch
.append(configure_symfony_isabelle_aten(c
, worker_name
))
74 withbranch
.append(_configure_symfony("Ludivine", c
, worker_name
,
75 "gitolite@git.immae.eu:perso/Immae/Sites/Ludivine"))
76 withbranch
.append(_configure_symfony("Connexionswing", c
, worker_name
,
77 "gitolite@git.immae.eu:perso/Immae/Projets/Connexionswing"))
78 withbranch
.append(_configure_symfony("Piedsjaloux", c
, worker_name
,
79 "gitolite@git.immae.eu:Pieds_jaloux/NewSite"))
81 c
['schedulers'].append(force_scheduler("force_immae_eu", withbranch
))
82 c
['schedulers'].append(force_scheduler("force_no_branch_immae_eu", withoutbranch
, nobranch
=True))
84 configure_slack_push(c
, E
.SECRETS_FILE
, all_builder_names(c
))
85 configure_xmpp_push(c
, E
.SECRETS_FILE
, all_builder_names(c
), E
.XMPP_RECIPIENTS
)
87 BRANCH_TO_SYMFONY_ENV
= {
102 BRANCH_TO_SERVICE_NAME
= {
104 "test": "phpfpm-chloe_new_integration",
105 #"master": "phpfpm-chloe_production",
108 "stabilo_dev": "phpfpm-florian_app",
111 "test": "phpfpm-isabelle_aten_integration",
112 "master": "phpfpm-isabelle_aten_production",
115 "test": "phpfpm-ludivine_integration",
116 "master": "phpfpm-ludivine_production",
119 "test": "phpfpm-connexionswing_integration",
120 "master": "phpfpm-connexionswing_production",
123 "test": "phpfpm-piedsjaloux_integration",
124 "master": "phpfpm-piedsjaloux_production",
128 BRANCH_TO_POST_STEP
= {
130 "master": "SYMFONY_ENV=prod php ./bin/console assetic:dump --env=prod --no-debug"
134 def need_follow_systemd(name
, step
):
135 return step
.getProperty("branch") in BRANCH_TO_SERVICE_NAME
.get(name
, {})
137 def need_post_step(name
, step
):
138 return step
.getProperty("branch") in BRANCH_TO_POST_STEP
.get(name
, {})
141 def get_post_step_command(props
, name
):
142 if props
.hasProperty("branch") and len(props
["branch"]) > 0:
143 post_step
= BRANCH_TO_POST_STEP
.get(name
, {}).get(props
["branch"])
144 if post_step
is not None:
148 def get_parameters_file(props
, name
):
149 if props
.hasProperty("branch") and len(props
["branch"]) > 0:
150 env
= BRANCH_TO_SYMFONY_ENV
.get(name
, {}).get(props
["branch"], "dev")
153 return E
.SECRETS_FILE
+ "/symfony_{}_{}_parameters.yml".format(name
, env
)
156 def get_composer_install_command(props
, name
):
157 if props
.hasProperty("branch") and len(props
["branch"]) > 0:
158 env
= BRANCH_TO_SYMFONY_ENV
.get(name
, {}).get(props
["branch"], "dev")
162 return "SYMFONY_ENV={} composer install".format(env
) + (" --no-dev" if env
== "prod" else "")
165 def get_systemd_service_invocation_command(props
, name
):
166 if props
.hasProperty("branch") and len(props
["branch"]) > 0:
167 service
= BRANCH_TO_SERVICE_NAME
.get(name
, {}).get(props
["branch"])
168 if service
is not None:
169 return "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o CheckHostIP=no -i {} buildbot@eldiron systemctl show -p InvocationID --value {}.service".format(E
.SSH_KEY_PATH
, service
)
172 def follow_systemd_command(props
, name
, invocation_id
):
173 if props
.hasProperty("branch") and len(props
["branch"]) > 0:
174 service
= BRANCH_TO_SERVICE_NAME
.get(name
, {}).get(props
["branch"])
175 if service
is not None:
176 return ["follow-systemd-unit", service
, util
.Property("service_invocation_id")]
178 def configure_gsm_cells(c
, worker_name
):
179 builder_name
= "GSMCells_build"
180 c
['schedulers'].append(schedulers
.Nightly(name
="GSMCells-weekly",
181 builderNames
=[builder_name
], dayOfWeek
=6, hour
=3))
182 c
['builders'].append(util
.BuilderConfig(name
=builder_name
, workernames
=[worker_name
], factory
=gsm_cells_build_factory()))
186 def _configure(name
, factory
, c
, worker_name
):
188 capitalized
= "BIP39"
190 capitalized
= "".join([n
.capitalize() for n
in name
.split('_')])
191 builder_name
= "{}_build".format(capitalized
)
193 c
['schedulers'].append(git_hook_scheduler(capitalized
, [builder_name
]))
194 c
['builders'].append(util
.BuilderConfig(name
=builder_name
, workernames
=[worker_name
], factory
=factory()))
198 def configure_symfony_isabelle_aten(c
, worker_name
):
199 return _configure_symfony("IsabelleAten", c
, worker_name
,
200 "gitolite@git.immae.eu:perso/Immae/Sites/Aten", parameters_path
=None,
201 other_steps
=lambda path_env
: [
202 NixShellCommand(name
="Install yarn",
203 logEnviron
=False, haltOnFailure
=True,
204 env
=path_env
, command
="yarn install"),
205 NixShellCommand(name
="Build frontend",
206 logEnviron
=False, haltOnFailure
=True,
207 env
=path_env
, command
="yarn run encore production")
211 def _configure_symfony(name
, c
, worker_name
, *args
, **kwargs
):
212 builder_name
= "Symfony_{}_build".format(name
)
214 c
['schedulers'].append(git_hook_scheduler("Symfony_{}".format(name
), [builder_name
]))
215 c
['builders'].append(util
.BuilderConfig(name
=builder_name
, workernames
=[worker_name
], factory
=symfony_project_factory(name
, *args
, **kwargs
)))
219 def history_build_factory():
221 "PATH": os
.environ
["BUILDBOT_PATH_History"] + ":${PATH}"
223 factory
= util
.BuildFactory()
224 factory
.addStep(steps
.Git(logEnviron
=False, repourl
=E
.HISTORY_GIT_URL
,
225 submodules
=True, sshPrivateKey
=open(E
.SSH_KEY_PATH
).read().rstrip(),
226 sshHostKey
=E
.SSH_HOST_KEY
, mode
="full", method
="fresh"))
227 factory
.addStep(steps
.ShellCommand(name
="build website",
228 logEnviron
=False, haltOnFailure
=True,
229 env
=path_env
, command
=["jekyll", "build"]))
230 factory
.addStep(steps
.MasterShellCommand(command
="rm -rf {}".format(E
.HISTORY_RELEASE_PATH
)))
231 factory
.addStep(steps
.DirectoryUpload(workersrc
="_site",
232 masterdest
=E
.HISTORY_RELEASE_PATH
,
233 url
="https://www.immae.eu/history"))
234 factory
.addStep(steps
.MasterShellCommand(command
="chmod -R a+rX {}".format(E
.HISTORY_RELEASE_PATH
)))
238 def docs_build_factory():
240 "PATH": os
.environ
["BUILDBOT_PATH_Docs"] + ":${PATH}"
242 factory
= util
.BuildFactory()
243 factory
.addStep(steps
.Git(logEnviron
=False, repourl
=E
.DOCS_GIT_URL
,
244 submodules
=True, sshPrivateKey
=open(E
.SSH_KEY_PATH
).read().rstrip(),
245 sshHostKey
=E
.SSH_HOST_KEY
, mode
="full", method
="fresh"))
246 factory
.addStep(steps
.ShellCommand(name
="build website",
247 logEnviron
=False, haltOnFailure
=True,
248 env
=path_env
, command
=["make", "html"]))
249 factory
.addStep(steps
.MasterShellCommand(command
="rm -rf {}".format(E
.DOCS_RELEASE_PATH
)))
250 factory
.addStep(steps
.DirectoryUpload(workersrc
="_build/html",
251 masterdest
=E
.DOCS_RELEASE_PATH
,
252 url
="https://www.immae.eu/docs"))
253 factory
.addStep(steps
.MasterShellCommand(command
="chmod -R a+rX {}".format(E
.DOCS_RELEASE_PATH
)))
257 def recettes_build_factory():
259 "PATH": os
.environ
["BUILDBOT_PATH_Recettes"] + ":${PATH}"
261 factory
= util
.BuildFactory()
262 factory
.addStep(steps
.Git(logEnviron
=False, repourl
=E
.RECETTES_GIT_URL
,
263 submodules
=True, sshPrivateKey
=open(E
.SSH_KEY_PATH
).read().rstrip(),
264 sshHostKey
=E
.SSH_HOST_KEY
, mode
="full", method
="fresh"))
265 factory
.addStep(NixShellCommand(name
="build website",
266 logEnviron
=False, haltOnFailure
=True,
267 env
=path_env
, command
="jekyll build --trace --baseurl /recettes"))
268 factory
.addStep(steps
.MasterShellCommand(command
="rm -rf {}".format(E
.RECETTES_RELEASE_PATH
)))
269 factory
.addStep(steps
.DirectoryUpload(workersrc
="_site",
270 masterdest
=E
.RECETTES_RELEASE_PATH
,
271 url
="https://www.immae.eu/recettes"))
272 factory
.addStep(steps
.MasterShellCommand(command
="chmod -R a+rX {}".format(E
.RECETTES_RELEASE_PATH
)))
276 def bip39_build_factory():
278 "PATH": os
.environ
["BUILDBOT_PATH_BIP39"] + ":${PATH}"
280 factory
= util
.BuildFactory()
281 factory
.addStep(steps
.Git(logEnviron
=False, repourl
=E
.BIP39_GIT_URL
,
282 submodules
=True, mode
="full", method
="fresh"))
283 factory
.addStep(steps
.ShellCommand(name
="build file",
284 logEnviron
=False, haltOnFailure
=True,
285 env
=path_env
, command
=["python", "compile.py"]))
286 factory
.addStep(steps
.FileUpload(name
="upload file", workersrc
="bip39-standalone.html",
287 masterdest
=E
.BIP39_RELEASE_PATH
+ "/index.html",
288 url
="https://tools.immae.eu/BIP39", mode
=0o644))
289 factory
.addStep(steps
.MasterShellCommand(command
="chmod -R a+rX {}".format(E
.BIP39_RELEASE_PATH
)))
293 def immae_eu_build_factory():
295 "PATH": os
.environ
["BUILDBOT_PATH_ImmaeEu"] + ":${PATH}"
297 factory
= util
.BuildFactory()
298 factory
.addStep(steps
.Git(logEnviron
=False, repourl
=E
.IMMAE_EU_GIT_URL
,
299 submodules
=True, sshPrivateKey
=open(E
.SSH_KEY_PATH
).read().rstrip(),
300 sshHostKey
=E
.SSH_HOST_KEY
, mode
="full", method
="fresh"))
301 factory
.addStep(steps
.ShellCommand(name
="build website",
302 logEnviron
=False, haltOnFailure
=True,
303 env
=path_env
, command
=["make", "html"]))
304 factory
.addStep(steps
.MasterShellCommand(command
="rm -rf {}".format(E
.IMMAE_EU_RELEASE_PATH
)))
305 factory
.addStep(steps
.DirectoryUpload(workersrc
="output",
306 masterdest
=E
.IMMAE_EU_RELEASE_PATH
,
307 url
="https://www.immae.eu"))
308 factory
.addStep(steps
.MasterShellCommand(command
="chmod -R a+rX {}".format(E
.IMMAE_EU_RELEASE_PATH
)))
312 def cours_build_factory():
314 "PATH": os
.environ
["BUILDBOT_PATH_Cours"] + ":${PATH}",
317 factory
= util
.BuildFactory()
318 factory
.addStep(steps
.Git(logEnviron
=False, repourl
=E
.COURS_GIT_URL
,
319 submodules
=True, sshPrivateKey
=open(E
.SSH_KEY_PATH
).read().rstrip(),
320 sshHostKey
=E
.SSH_HOST_KEY
, mode
="incremental"))
321 factory
.addStep(steps
.ShellCommand(name
="build website",
322 logEnviron
=False, haltOnFailure
=True,
323 command
=["make", "build"], env
=path_env
))
324 factory
.addStep(steps
.MasterShellCommand(command
="rm -rf {}".format(E
.COURS_RELEASE_PATH
)))
325 factory
.addStep(steps
.DirectoryUpload(workersrc
="build",
326 masterdest
=E
.COURS_RELEASE_PATH
,
327 url
="https://www.immae.eu/cours"))
328 factory
.addStep(steps
.MasterShellCommand(command
="chmod -R a+rX {}".format(E
.COURS_RELEASE_PATH
)))
330 factory
.addStep(steps
.ShellCommand(name
="build pdfs",
331 logEnviron
=False, haltOnFailure
=True,
332 command
=["make", "pdfs"], env
=path_env
))
334 package
= util
.Interpolate("cours_%(kw:clean_branch)s.tar.gz", clean_branch
=clean_branch
)
335 release_file
= "{0}/cours_%(kw:clean_branch)s.tar.gz"
336 package_dest
= util
.Interpolate(release_file
.format(E
.COURS_TARBALL_PATH
), clean_branch
=clean_branch
)
337 package_url
= util
.Interpolate(release_file
.format(E
.COURS_TARBALL_URL
), clean_branch
=clean_branch
)
338 factory
.addStep(steps
.ShellCommand(name
="build pdf tarball",
339 logEnviron
=False, haltOnFailure
=True,
340 command
=["tar", "-cvf", package
, "-C", "pdfs", "mp", "mpsi"], env
=path_env
))
341 factory
.addStep(steps
.FileUpload(name
="upload package", workersrc
=package
,
342 masterdest
=package_dest
, url
=package_url
, mode
=0o644))
346 def normalesup_build_factory():
348 "PATH": os
.environ
["BUILDBOT_PATH_Normalesup"] + ":${PATH}"
350 factory
= util
.BuildFactory()
351 factory
.addStep(steps
.Git(logEnviron
=False, repourl
=E
.NORMALESUP_GIT_URL
,
352 submodules
=True, sshPrivateKey
=open(E
.SSH_KEY_PATH
).read().rstrip(),
353 sshHostKey
=E
.SSH_HOST_KEY
, mode
="incremental"))
354 factory
.addStep(steps
.ShellCommand(name
="build website",
355 logEnviron
=False, haltOnFailure
=True,
356 command
=["make", "build"], env
=path_env
))
357 factory
.addStep(steps
.ShellCommand(name
="give read access to all files",
358 logEnviron
=False, haltOnFailure
=True,
359 command
="chmod -R a+rX build", env
=path_env
))
360 factory
.addStep(steps
.ShellCommand(name
="synchronize with phare",
361 logEnviron
=False, haltOnFailure
=True,
362 env
=path_env
, command
=[
363 "rsync", "-av", "--delete",
364 "-e", "ssh -i {} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o CheckHostIP=no".format(E
.SSH_KEY_PATH
),
366 os
.environ
["BUILDBOT_NORMALESUP_HOST"]
368 factory
.addStep(steps
.MasterShellCommand(command
="rm -rf {}".format(E
.NORMALESUP_RELEASE_PATH
)))
369 factory
.addStep(steps
.DirectoryUpload(workersrc
="build", masterdest
=E
.NORMALESUP_RELEASE_PATH
,
370 url
="https://www.immae.eu/recherche"))
371 factory
.addStep(steps
.MasterShellCommand(command
="chmod -R a+rX {}".format(E
.NORMALESUP_RELEASE_PATH
)))
375 def gsm_cells_build_factory():
377 "PATH": os
.environ
["BUILDBOT_PATH_GSMCells"] + ":${PATH}",
378 "IN_BUILDBOT": "yes",
382 Options +FollowSymLinks
386 for k
, v
in os
.environ
.items():
387 if k
.startswith("BUILDBOT_GSM_CELLS_"):
388 path_env
[k
[len("BUILDBOT_GSM_CELLS_"):]] = v
390 script
= os
.environ
["BUILDBOT_PROJECT_DIR"] + "/scripts/lacells_download"
391 factory
= util
.BuildFactory()
392 factory
.addStep(steps
.ShellCommand(name
="download files",
393 logEnviron
=False, haltOnFailure
=True, command
=[script
], env
=path_env
))
394 factory
.addStep(steps
.ShellCommand(name
="give read access to all files",
395 logEnviron
=False, haltOnFailure
=True,
396 command
="chmod a+r lacells.db", env
=path_env
))
397 factory
.addStep(steps
.FileUpload(workersrc
="lacells.db",
398 masterdest
=(E
.GSMCELLS_RELEASE_PATH
+"/lacells.db"), url
=(E
.GSMCELLS_RELEASE_URL
+"/lacells.db")))
399 factory
.addStep(steps
.MasterShellCommand(command
="touch {}/.duplicity-ignore".format(E
.GSMCELLS_RELEASE_PATH
)))
400 factory
.addStep(steps
.MasterShellCommand(command
='echo "$HTACCESS" > {}/.htaccess'.format(E
.GSMCELLS_RELEASE_PATH
),
402 factory
.addStep(steps
.MasterShellCommand(command
="ln -sf lacells.db {}/lacells.db.new".format(E
.GSMCELLS_RELEASE_PATH
)))
403 factory
.addStep(steps
.MasterShellCommand(command
="chmod -R a+rX {}".format(E
.GSMCELLS_RELEASE_PATH
)))
407 def symfony_project_factory(name
, repourl
, parameters_path
="app/config/parameters.yml", other_steps
=lambda a
: []):
408 if "BUILDBOT_PATH_SYMFONY_{}".format(name
) in os
.environ
:
410 "PATH": os
.environ
["BUILDBOT_PATH_SYMFONY_{}".format(name)] + ":${PATH}"
417 for k
, v
in os
.environ
.items():
418 if k
.startswith("BUILDBOT_SYMFONY_{}_".format(name
)):
419 path_env
[k
[len("BUILDBOT_SYMFONY_{}_".format(name
)):]] = v
421 factory
= util
.BuildFactory()
422 factory
.addStep(steps
.Git(logEnviron
=False, repourl
=repourl
,
423 submodules
=True, sshPrivateKey
=open(E
.SSH_KEY_PATH
).read().rstrip(),
424 sshHostKey
=E
.SSH_HOST_KEY
, mode
="full", method
="fresh"))
425 if parameters_path
is not None:
426 factory
.addStep(steps
.FileDownload(mastersrc
=get_parameters_file
.withArgs(name
),
427 workerdest
=parameters_path
))
428 factory
.addStep(NixShellCommand(name
="build website",
429 logEnviron
=False, haltOnFailure
=True,
430 env
=path_env
, command
=get_composer_install_command
.withArgs(name
)))
431 if name
in BRANCH_TO_POST_STEP
:
432 factory
.addStep(NixShellCommand(name
="build website post",
433 logEnviron
=False, haltOnFailure
=True, doStepIf
=partial(need_post_step
, name
),
434 env
=path_env
, command
=get_post_step_command
.withArgs(name
)))
435 if parameters_path
is not None:
436 factory
.addStep(steps
.ShellCommand(name
="Remove parameters.yml",
437 logEnviron
=False, haltOnFailure
=True,
438 command
="rm -f {}".format(parameters_path
)))
439 for step
in other_steps(path_env
):
440 factory
.addStep(step
)
441 package
= util
.Interpolate("{}_%(kw:clean_branch)s.tar.gz".format(name
), clean_branch
=clean_branch
)
442 release_file
= "{0}/{1}/%(kw:clean_branch)s.tar.gz"
443 package_dest
= util
.Interpolate(release_file
.format("/var/lib/ftp/release.immae.eu/buildbot", name
), clean_branch
=clean_branch
)
444 # Tar doesn’t like creating the tarball in the same directory
445 factory
.addStep(steps
.ShellCommand(name
="Make a tarball 1/2",
446 logEnviron
=False, haltOnFailure
=True, env
=path_env
,
447 command
=["touch", package
]))
448 factory
.addStep(steps
.ShellCommand(name
="Make a tarball 2/2",
449 logEnviron
=False, haltOnFailure
=True, env
=path_env
,
450 command
=["tar", "--exclude", package
, "-czf", package
, "."]))
451 factory
.addStep(steps
.SetPropertyFromCommand(command
=get_systemd_service_invocation_command
.withArgs(name
),
452 property="service_invocation_id", doStepIf
=partial(need_follow_systemd
, name
)))
453 factory
.addStep(steps
.FileUpload(name
="upload package",
454 workersrc
=package
, masterdest
=package_dest
, mode
=0o644))
455 factory
.addStep(steps
.MasterShellCommand(command
=follow_systemd_command
.withArgs(name
, util
.Property("service_invocation_id")), env
=path_env
, logEnviron
=False, doStepIf
=partial(need_follow_systemd
, name
)))