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

168 阅读3分钟

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

我最喜欢的简易自动化工具曾经是cron系统--古老、可靠、面向用户,而且(除了我永远无法记住的调度语法之外)简单。然而,cron的问题是,它假定一台电脑每天24小时都在工作。在错过了太多的计划备份之后,我发现了anacron,一个基于时间戳而不是计划时间的cron系统。如果你的电脑在通常情况下运行时处于关闭状态,Anacron会确保在电脑重新开启时运行该作业。创建一个作业就像把一个shell脚本放到三个目录中的一个一样简单。cron.daily,cron.weekly, 或cron.monthly (如果你想的话,你可以定义更多)。有了anacron,我发现自己把脚本和Ansible playbook放到了各种琐碎的任务中,包括即将到来的到期日或事件的弹出提醒。

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

用Ansible设置软件

任何时候我设置一台新的电脑,无论是笔记本电脑、工作站还是服务器,我都会安装anacron。这很简单,但是anacron的安装只提供了anacron命令。它并没有设置Anacron的用户环境。所以我创建了一个Ansible playbook来设置用户使用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.builtin.file: 指令上迭代一次(目录名称填充在{{ item }} 变量中)。就像Ansible中的一切一样,如果目录已经存在,就不会有错误或冲突。

用Ansible复制文件

ansible.builtin.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.builtin.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.builtin.package 模块为软件包的安装提供了一个通用接口,所以我在这个游戏手册中使用它。幸运的是,我还没有遇到一个 repo 将anacron 命名为anacron 以外的东西,所以现在,我不必考虑软件包名称的潜在差异。

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

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

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

为了用Ansible安装anacron,我运行了playbook。

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

从那时起,我可以写shell脚本来执行一些琐碎但重复的任务,然后把它复制到~/.local/etc/cron.daily ,让它每天自动运行一次(或者大约如此)。我还为一些任务编写了Ansible playbook,比如清理我的下载文件夹。我把玩法手册放在~/Ansible ,这是我保存Ansible脚本的地方,然后在~/.local/etc/cron.daily ,创建一个shell脚本来执行这个玩法。这很简单,不费吹灰之力,而且很快就变成了第二天的事情。