link¶
link makes sure a symbolic link exists and points where you say, or that
it does not exist. It reads the link with readlink, creates or repoints
it with ln -sfn, and removes it with rm -f. Use it for the classic
"enabled" links (sites-enabled/app), for a current link between
releases, and to put a program on the PATH.
New in 0.2.0
Minimal example¶
link "/etc/nginx/sites-enabled/app", to: "/etc/nginx/sites-available/app"
Options¶
| Option | Type | Default | Description |
|---|---|---|---|
to |
String | required | Where the link points. Stored as given: a relative target such as "releases/2" is relative to the link's directory. The target does not have to exist. |
state |
:present or :absent |
:present |
:absent removes the link. |
force |
true or false |
false |
Replace a regular file that is where the link should be. Without it, a file in the way is an error. |
notifies |
[:action, "type[name]"], optionally with :immediately, or a list of them |
none | Actions to run on other resources when this one changes. See Notifications. |
subscribes |
[:action, "type[name]"], optionally with :immediately, or a list of them |
none | Actions to run on this resource when another one changes. |
tags |
Symbol, String, or an Array of them | none | Tags for running part of a recipe with --tags and --skip-tags. See Tags. |
The link's directory must exist; declare it with a
directory resource first if it does not. A directory where
the link should be is always an error, even with force: true.
Scenarios¶
examples/resources/link/recipe.rb
# Two releases of an application side by side, and a link that says which
# one is live: deploying another release is a change to the link.
directory "/srv/app/releases/1"
directory "/srv/app/releases/2"
file "/srv/app/releases/2/console", content: "#!/bin/sh\necho \"release 2\"\n", mode: "0755"
link "/srv/app/current", to: "releases/2"
# A command on the PATH that runs whichever release is live.
link "/usr/local/bin/app-console", to: "/srv/app/current/console"
# A link that must not exist.
link "/usr/local/bin/old-console", state: :absent
Releases and a current link¶
$ sudo sadame apply examples/resources/link
sadame 0.5.1 apply on local (Debian GNU/Linux 12 (bookworm))
changed directory[/srv/app/releases/1]
state: absent -> present
changed directory[/srv/app/releases/2]
state: absent -> present
changed file[/srv/app/releases/2/console]
state: absent -> present
mode: 0755
--- /dev/null
+++ /srv/app/releases/2/console (desired)
@@ -0,0 +1,2 @@
+#!/bin/sh
+echo "release 2"
changed link[/srv/app/current]
state: absent -> present
to: releases/2
changed link[/usr/local/bin/app-console]
state: absent -> present
to: /srv/app/current/console
unchanged link[/usr/local/bin/old-console]
Summary
changed 5 directory[/srv/app/releases/1]
directory[/srv/app/releases/2]
file[/srv/app/releases/2/console]
link[/srv/app/current]
link[/usr/local/bin/app-console]
unchanged 1
failed 0
skipped 0
notified 0
Finished in 0.29s.
$ readlink /srv/app/current /usr/local/bin/app-console
releases/2
/srv/app/current/console
$ app-console
release 2
Someone pointed it at the old release¶
$ sudo ln -sfn releases/1 /srv/app/current
$ sudo sadame drift examples/resources/link
sadame 0.5.1 drift on local (Debian GNU/Linux 12 (bookworm))
~ link[/srv/app/current]
to: releases/1 -> releases/2
Drift: 1 of 6 resources differs from the recipe.
$ sudo sadame apply examples/resources/link
sadame 0.5.1 apply on local (Debian GNU/Linux 12 (bookworm))
unchanged directory[/srv/app/releases/1]
unchanged directory[/srv/app/releases/2]
unchanged file[/srv/app/releases/2/console]
changed link[/srv/app/current]
to: releases/1 -> releases/2
unchanged link[/usr/local/bin/app-console]
unchanged link[/usr/local/bin/old-console]
Summary
changed 1 link[/srv/app/current]
unchanged 5
failed 0
skipped 0
notified 0
Finished in 0.22s.
Reloading a service when a link changes¶
A link that enables a configuration can notify the service that reads it:
link "/etc/nginx/sites-enabled/app",
to: "/etc/nginx/sites-available/app",
notifies: [:reload, "service[nginx]"]
Common mistakes¶
- A file in the way. A path that exists as a regular file fails with
"is a regular file, not a symbolic link". Add
force: truewhen replacing it is what you want, as for/etc/resolv.conf. - Relative targets.
to: "releases/2"is relative to the link's directory, not to the directory you run sadame from. sadame compares the target as written:to: "/srv/app/releases/2"andto: "releases/2"are different links, even when they lead to the same place. - Expecting the link to create its directory.
lnfails when the directory does not exist.