Enrico Zini: Use ansible actions in a script
This is part of a series of posts on ideas for an ansible-like provisioning
system, implemented in Transilience.
I like many of the modules provided with Ansible: they are convenient,
platform-independent implementations of common provisioning steps. They'd be
fantastic to have in a library that I could use in normal programs.
This doesn't look easy to do with Ansible code as it is. Also, the code quality
of various Ansible modules doesn't fit something I'd want in a standard library
of cross-platform provisioning functions.
Modeling Actions
I want to keep the declarative, idempotent aspect of describing actions on a
system. A good place to start could be a hierarchy of
dataclasses that hold
the same parameters as ansible modules, plus a
I like that Ansible tasks have names, and I hate having to give names to
trivial tasks like "Create directory /foo/bar", so I added a
Running Actions remotely
Dataclasses have an asdict
function that makes them trivially serializable. If their members stick to
data types that can be serialized with Mitogen
and the run implementation doesn't use non-pure, non-stdlib Python modules,
then I can trivially run actions on
all sorts of remote systems
using Mitogen:
How fast would that be, compared to Ansible?
With a network round-trip for each single operation I'm already 3x faster than
Ansible, and it can run on nspawn containers, too!
I always wanted to have a library of ansible modules useable in normal scripts,
and I've always been angry with Ansible for not bundling their backend code in
a generic library. Well, now there's the beginning of one!
Sweet! Next step, pipelining.
run() method that performs the
action:
@dataclass class Action: """ Base class for all action implementations. An Action is the equivalent of an ansible module: a declarative representation of an idempotent operation on a system. An Action can be run immediately, or serialized, sent to a remote system, run, and sent back with its results. """ uuid: str = field(default_factory=lambda: str(uuid.uuid4())) result: Result = field(default_factory=Result) def summary(self): """ Return a short text description of this action """ return self.__class__.__name__ def run(self, system: transilience.system.System): """ Perform the action """ self.result.state = ResultState.NOOP
summary() method
so that trivial tasks like that can take care of naming themselves.
Dataclasses allow to introspect fields and annotate them with extra metadata,
and together with docstrings, I can make actions reasonably self-documeting.
I ported some of Ansible's modules over: see complete list in the git
repository.
Running Actions in a script
With a bit of glue code
I can now run Ansible-style functions from a plain Python script:
#!/usr/bin/python3 from transilience.runner import Script script = Script() for i in range(10): script.builtin.file(state="touch", path=f"/tmp/test i ")
#!/usr/bin/python3 from transilience.runner import Script from transilience.system import Mitogen script = Script(system=Mitogen("my server", "ssh", hostname="machine.example.org", username="user")) for i in range(10): script.builtin.file(state="touch", path=f"/tmp/test i ")
$ time ansible-playbook test.yaml [...] real 0m15.232s user 0m4.033s sys 0m1.336s $ time ./test_script real 0m4.934s user 0m0.547s sys 0m0.049s
A while back there was a thread on one of our company mailing lists about
I built my last desktop computer what seems like ages ago. In 2011, I was in a
very different place, both financially and as a person. At the time, I was
earning minimum wage at my school's caf to pay rent. Since the caf was owned
by the school cooperative, I had an employee discount on computer parts. This
gave me a chance to build my first computer from spare parts at a reasonable
price.
After 10 years of service
Welcome to the 33th post in the rigorously raconteuring R recommendations series, or
Before and during FOSDEM 2020, I agreed with the people (developers, supporters, managers) of the UBports Foundation to package the Unity8 Operating Environment for Debian. Since 27th Feb 2020, Unity8 has now become Lomiri.
Recent Uploads to Debian related to Lomiri (Feb - May 2021)
Over the past 4 months I attended 14 of the weekly scheduled UBports development sync sessions and worked on the following bits and pieces regarding Lomiri in Debian:


emacs tramp mode for chroot. I saw tramp for docker and lxc so I
figured it must be possible to write a mode for chroot. I
wrote one
for
Having build a single node Kubernetes cluster and had a poke at what it s doing in terms of networking the next thing I want to do is figure out what it s doing in terms of containers. You might argue this should have come before networking, but to me the networking piece is more non-standard than the container piece, so I wanted to understand that first.
Let s start with a process listing on the host.
As the President of the GNOME Foundation Board of Directors, I m really pleased to see the