View Source ExAttr (ExAttr v1.0.0)
Simple utility library that performs native xattr
operations using rustler and the xattr
crate created by Steven Allen
Rational
I was disappointed to see that there was no native interface within Elixir or Erlang's
standard libraries for managing extended attributes. While this can technically be worked
around by simply wrapping the setfattr
and getfattr
commands, I wasn't happy with the
performance of this approach.
Additionally, while there are similar libraries that handle xattr operations for Elixir, I'm picky about how I handle serialization and was looking for something less opinionated and "dumb" that I could easily wrap my application specific logic around.
Since I couldn't find anything that fit this criteria I figured I'd just do it myself, and so here we are!
Namespacing Advise
If you want to add some custom-application-specific xattrs to a file, it's generally a good idea to do this all
under a common namespace specific to your application. Since POSIX extended attributes already has some built-in
namespacing that differentiates between trusted
, system
, user
, etc, it is highly likely you will need to make
your namespace a child of the user
namespace (ex: "user.<my_namespace>"
) unless you are doing SELinux stuff.
This is most easily abstracted away by simply wrapping the functions of this library to auto handle all that for you. Here is an example of what I mean:
defmodule MyApp.XAttr do
@namespace "user.my_apps_namespace"
def set(path, name, value) do
name = "#{@namespace}.#{name}"
ExAttr.set(path, name, value)
end
def get(path, name) do
name = "#{@namespace}.#{name}"
ExAttr.get(path, name)
end
def list(path) do
case ExAttr.list(path) do
{:ok, list} ->
list
|> Enum.filter(&match?("#{@namespace}." <> _, &1))
|> Enum.map(fn "#{@namespace}." <> name -> name end)
|> then(fn list ->
{:ok, list}
end)
{:error, reason} ->
{:error, reason}
end
end
# And so on...
end
Summary
Functions
Dumps map of extended attributes for the specified file.
Dumps map of extended attributes for the specified file, raises on error.
Get an extended attribute for the specified file.
Get an extended attribute for the specified file, raises on error
List extended attributes attached to the specified file.
List extended attributes attached to the specified file, raises on error.
Remove an extended attribute from the specified file.
Remove an extended attribute from the specified file, raises on error.
Set an extended attribute on the specified file. Passing a nil
value will remove the attribute.
Set an extended attribute on the specified file. Passing a nil
value will remove the attribute, raises on error.
Forwards the result of the xattr:SUPPORTED_PLATFORM
function from
the xattr
crate this library wraps.
Types
Functions
Dumps map of extended attributes for the specified file.
Note
This may not list all attributes. Speficially, it definitely won’t list any trusted attributes unless you are root and it may not list system attributes.
Examples
iex> :ok = ExAttr.set("test.txt", "user.foo", "bar")
iex> :ok = ExAttr.set("test.txt", "user.bar", "foo")
iex> :ok = ExAttr.set("test.txt", "user.test", "example")
iex> ExAttr.dump("test.txt")
{:ok, %{"user.bar" => "foo", "user.foo" => "bar", "user.test" => "example"}}
Dumps map of extended attributes for the specified file, raises on error.
Note
This may not list all attributes. Speficially, it definitely won’t list any trusted attributes unless you are root and it may not list system attributes.
Get an extended attribute for the specified file.
Examples
iex> ExAttr.get("test.txt", "user.foo")
{:ok, nil}
iex> ExAttr.set("test.txt", "user.foo", "123")
:ok
iex> ExAttr.get("test.txt", "user.foo")
{:ok, "123"}
Get an extended attribute for the specified file, raises on error
List extended attributes attached to the specified file.
Note
This may not list all attributes. Speficially, it definitely won’t list any trusted attributes unless you are root and it may not list system attributes.
Examples
iex> :ok = ExAttr.set("test.txt", "user.foo", "bar")
iex> :ok = ExAttr.set("test.txt", "user.bar", "foo")
iex> :ok = ExAttr.set("test.txt", "user.test", "example")
iex> ExAttr.list("test.txt")
{:ok, ["user.test", "user.bar", "user.foo"]}
List extended attributes attached to the specified file, raises on error.
Note
This may not list all attributes. Speficially, it definitely won’t list any trusted attributes unless you are root and it may not list system attributes.
Remove an extended attribute from the specified file.
Examples
iex> ExAttr.set("test.txt", "user.foo", "123")
:ok
iex> ExAttr.get("test.txt", "user.foo")
{:ok, "123"}
iex> ExAttr.remove("test.txt", "user.foo")
:ok
iex> ExAttr.get("test.txt", "user.foo")
{:ok, nil}
iex> ExAttr.remove("test.txt", "user.foo")
{:error, "No data available (os error 61)"}
Remove an extended attribute from the specified file, raises on error.
Set an extended attribute on the specified file. Passing a nil
value will remove the attribute.
Examples
iex> ExAttr.set("test.txt", "user.foo", "123")
:ok
iex> ExAttr.get("test.txt", "user.foo")
{:ok, "123"}
iex> ExAttr.set("test.txt", "user.foo", nil)
:ok
iex> ExAttr.get("test.txt", "user.foo")
{:ok, nil}
Set an extended attribute on the specified file. Passing a nil
value will remove the attribute, raises on error.
@spec supported_platform() :: boolean()
Forwards the result of the xattr:SUPPORTED_PLATFORM
function from
the xattr
crate this library wraps.
Returns true if platform is supported.