我如何使用 Ansible 和 anacron 实现自动化
Ansible 自动化 anacron

> 
> 有了 anacron，我可以把脚本和 Ansible 剧本放到合适的地方，以完成各种琐碎的任务。
> 
> 
> 


![](/data/attachment/album/202110/13/155036tc0c7th906cc96mm.jpg "Woman programming")


自动化是伟大的 IT 和 DevOps 理想，但根据我的经验，可能根本不存在什么不方便的东西。有很多次，我为某些任务想出了一个很好的解决方案，我甚至会编写脚本，但我没有让它真正实现自动化，因为在我工作的机器上不存在易于自动化的基础设施。


我最喜欢的简易自动化工具曾经是 cron 系统，它古老、可靠、面向用户，而且简单（除了一个我永远无法记住的调度语法之外）。然而，cron 的问题是，它假定一台电脑每天 24 小时都在工作。在错过了太多预定的备份之后，我发现了 [anacron](https://opensource.com/article/21/2/linux-automation)，一个基于时间戳而非预定时间的 cron 系统。如果你的电脑在通常情况下运行时处于关闭状态，anacron 会确保它在电脑重新开启时运行。创建一个作业只需要简单地把一个 shell 脚本放到三个目录中：`cron.day`、`cron.weekly` 或者 `cron.monthly` （如果你想的话，你可以定义更多）。有了 anacron，我发现自己把脚本和 Ansible 剧本用在了各种琐碎的任务中，包括弹出到期和事件提醒。


这是一个现代问题的简单而明显的解决方案，但如果 anacron 没有安装在电脑上，那它对我就没有用。


### 用 Ansible 进行软件设置


任何时候我设置一台新的计算机，无论是笔记本电脑、工作站还是服务器，我都会安装 anacron。这很简单，但是 anacron 的安装只提供了 `anacron` 命令。它并没有设置 anacron 的用户环境。所以我创建了一个 Ansible 剧本来设置用户需要什么来使用 anacron 并安装 `anacron` 命令。


首先，标准的 Ansible 模板：



```
---
- hosts: localhost
  tasks:

```

### 用 Ansible 创建目录


接下来，我创建了用于 Anacron 的目录树。你可以把它看成是一种透明的 crontab。



```
    - name: create directory tree
      ansible.builtin.file:
        path: "{{ item }}"
        state: directory
      with_items:
        - '~/.local/etc/cron.daily'
        - '~/.local/etc/cron.weekly'
        - '~/.local/etc/cron.monthly'
        - '~/.var/spool/anacron'

```

这个语法可能看起来有点奇怪，但它实际上是一个循环。`with_items:` 指令定义了四个要创建的目录，Ansible 在 `ansible.buildin.file:` 指令中为每个目录迭代一次（目录名填充了 `{{ item }}` 变量）。与 Ansible 中的一切一样，如果目录已经存在，不会有错误或冲突。


### 用 Ansible 复制文件


`ansible.buildin.copy` 模块将文件从一个地方复制到另一个地方。为了让它工作，我需要创建一个叫做 `anacrontab` 的文件。它不是 Ansible 剧本，所以我把它放在我的 `~/Ansible/data` 目录下，那里是我的剧本的支持文件。



```
  - name: copy anacrontab into place
   ansible.builtin.copy:
    src: ~/Ansible/data/anacrontab
    dest: ~/.local/etc/anacrontab
    mode: '0755'

```

我的 `anacrontab` 文件很简单，模仿了一些发行版默认安装在 `/etc/anacron` 中的文件：



```
SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
1  0  cron.day    run-parts $HOME/.local/etc/cron.daily/
7  0  cron.wek    run-parts $HOME/.local/etc/cron.weekly/
30 0  cron.mon    run-parts $HOME/.local/etc/cron.monthly/

```

### 登录时运行 anacron


大多数 Linux 发行版将 anacron 配置为从 `/etc/anacron` 读取作业。我主要是作为一个普通用户使用 anacron，所以我从我的登录账号 `~/.profile` 启动 anacron。我不想让自己记住这些配置，所以我让 Ansible 来做。我使用 `ansible.buildin.lineinfile` 模块，它会在 `~/.profile` 不存在时创建它，并插入 anacron 的启动行。



```
    - name: add local anacrontab to .profile
      ansible.builtin.lineinfile:
        path: ~/.profile
        regexp: '^/usr/sbin/anacron'
        line: '/usr/sbin/anacron -t ~/.local/etc/anacrontab'
        create: true

```

### 用 Ansible 安装 anacron


对于我的大多数系统来说，`dnf` 模块可以用来安装软件包，但我的工作站运行的是 Slackware（使用 `slackpkg`），有时不同的 Linux 发行版也会进入我的收藏。`ansible.buildin.package` 模块提供了一个安装软件包的通用接口，所以我把它用在这个剧本上。幸运的是，我还没有遇到一个名为 `anacron` 的仓库不是 `anacron`，所以现在，我不必考虑软件包名称的潜在差异。


这实际上是一个单独的剧本，因为软件包的安装需要权限升级，它由 `becomes: true` 指令提供。



```
- hosts: localhost
  become: true
  tasks:
    - name: install anacron
      ansible.builtin.package:
        name: anacron
        state: present

```

### 使用 anacron 和 Ansible 实现轻松自动化


为了用 Ansible 安装 anacron，我运行该剧本：



```
$ ansible-playbook ~/Ansible/setup-anacron.yaml

```

从此，我就可以编写 shell 脚本来执行一些琐碎但重复的任务，然后把它复制到 `~/.local/etc/cron.daily`，让它每天自动运行一次（或者大约如此）。我还为诸如 [清理下载文件夹](https://opensource.com/article/21/9/keep-folders-tidy-ansible) 之类的任务编写了 Ansible 剧本。我把我的剧本放在 `~/Ansible` 里，这是我保存 Ansible 剧本的地方，然后在 `~/.local/etc/cron.daily` 里创建一个 shell 脚本来执行这个剧本。这很简单，不费吹灰之力，而且很快成为习惯。




---


via: <https://opensource.com/article/21/9/ansible-anacron-automation>


作者：[Seth Kenlon](https://opensource.com/users/seth) 选题：[lujun9972](https://github.com/lujun9972) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)


本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


OK
Automation is the great IT and DevOps ideal, but in my experience, anything that's not immediately convenient may as well not exist at all. There have been many times when I've come up with a pretty good solution for some task, and I'll even script it, but I stop short of making it literally automated because the infrastructure for easy automation doesn't exist on the machine I'm working on.


My favorite easy automation tool used to be the cron system—old, reliable, user-facing, and (aside from a scheduling syntax I can never commit to memory) simple. However, the problem with cron is that it assumes a computer is on 24 hours a day, every day. After missing one too many scheduled backups, I discovered [anacron](https://opensource.com/article/21/2/linux-automation), the cron system based on timestamps rather than scheduled times. If your computer is off when a job would typically have run, anacron ensures that it's run when the computer is back on. Creating a job is as easy as dropping a shell script into one of three directories: `cron.daily`

, `cron.weekly`

, or `cron.monthly`

(you can define more if you want). With anacron, I find myself dropping scripts and Ansible playbooks into place for all manner of trivial tasks, including pop-up reminders of upcoming due dates or events.

It's a simple and obvious solution to a modern problem, but it does me no good if anacron isn't installed on the computer.

## Software setup with Ansible

Any time I set up a new computer, whether it's a laptop, workstation, or server, I install anacron. That's easy, but an anacron install only provides the anacron command. It doesn't set up the anacron user environment. So I created an Ansible playbook to set up what the user needs to use anacron and install the anacron command.

First, the standard Ansible boilerplate:

```
---
- hosts: localhost
tasks:
```


## Creating directories with Ansible

Next, I create the directory tree I use for anacron. You can think of this as a sort of transparent crontab.

```
- name: create directory tree
ansible.builtin.file:
path: "{{ item }}"
state: directory
with_items:
- '~/.local/etc/cron.daily'
- '~/.local/etc/cron.weekly'
- '~/.local/etc/cron.monthly'
- '~/.var/spool/anacron'
```


The syntax of this might seem a little strange, but it's actually a loop. The `with_items:`

directive defines four directories to create, and Ansible iterates over the `ansible.builtin.file:`

directive once for each directory (the directory name populates the `{{ item }}`

variable). As with everything in Ansible, there's no error or conflict if the directory already exists.

## Copying files with Ansible

The `ansible.builtin.copy`

module copies files from one location to another. For this to work, I needed to create a file called `anacrontab`

. It's not an Ansible playbook, so I keep it in my `~/Ansible/data`

directory, where I keep support files for my playbooks.

```
- name: copy anacrontab into place
ansible.builtin.copy:
src: ~/Ansible/data/anacrontab
dest: ~/.local/etc/anacrontab
mode: '0755'
```


My `anacrontab`

file is simple and mimics the one some distributions install by default into `/etc/anacron`

:

```
SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
1 0 cron.day run-parts $HOME/.local/etc/cron.daily/
7 0 cron.wek run-parts $HOME/.local/etc/cron.weekly/
30 0 cron.mon run-parts $HOME/.local/etc/cron.monthly/
```


## Running anacron on login

Most Linux distributions configure anacron to read jobs from `/etc/anacron`

. I mostly use anacron as a regular user, so I launch anacron from my login `~/.profile`

. I don't want to have to remember to configure that myself, so I have Ansible do it. I use the `ansible.builtin.lineinfile`

module, which creates `~/.profile`

if it doesn't already exist and inserts the anacron launch line.

```
- name: add local anacrontab to .profile
ansible.builtin.lineinfile:
path: ~/.profile
regexp: '^/usr/sbin/anacron'
line: '/usr/sbin/anacron -t ~/.local/etc/anacrontab'
create: true
```


## Installing anacron with Ansible

For most of my systems, the `dnf`

module would work for package installation, but my workstation runs Slackware (which uses `slackpkg`

), and sometimes a different Linux distro makes its way into my collection. The `ansible.builtin.package`

module provides a generic interface to package installation, so I use it for this playbook. Luckily, I haven't come across a repo that names `anacron`

anything but `anacron`

, so for now, I don't have to account for potential differences in package names.

This is actually a separate play because package installation requires privilege escalation, provided by the `becomes: true`

directive.

```
- hosts: localhost
become: true
tasks:
- name: install anacron
ansible.builtin.package:
name: anacron
state: present
```


## Using anacron and Ansible for easy automation

To install anacron with Ansible, I run the playbook:

`$ ansible-playbook ~/Ansible/setup-anacron.yaml`


From then on, I can write shell scripts to perform some trivial but repetitive task and copy it into `~/.local/etc/cron.daily`

to have it automatically run once a day (or thereabouts). I also write Ansible playbooks for tasks such as [cleaning out my downloads folder](https://opensource.com/article/21/9/keep-folders-tidy-ansible). I place my playbooks in `~/Ansible`

, which is where I keep my Ansible plays, and then create a shell script in `~/.local/etc/cron.daily`

to execute the play. It's easy, painless, and quickly becomes second nature.

## Comments are closed.