如何使用 Ansible 保持我的文件文件夹整洁

我尽量经常使用 Ansible,即使对于那些我知道如何使用 shell 脚本完成的任务,因为我知道 Ansible 很容易扩展。
60 位读者喜欢这篇文章。
Filing cabinet for organization

我尽量经常使用 Ansible,即使对于那些我知道如何使用 shell 脚本完成的任务,因为我知道 Ansible 很容易扩展。 即使我可能只是为我的个人工作站开发一个 Ansible playbook,但有时它最终会比预期的更有用,并且很容易将相同的 playbook 应用于我网络上的所有计算机。 此外,有时真正擅长某事的最大敌人是认为它只适合专业人士、大型项目,或者你觉得你不是的那种。 我使用 Ansible 是因为它是一个很棒的开源工具,但我受益最多的是因为它具有可扩展性。

我最近分配给 Ansible 的任务之一是保持我的 Downloads 文件夹整洁的艰巨任务。 如果你和我一样,你最终会整天从互联网上下载许多文件,然后忘记这些文件的存在。 一方面,我不介意这个习惯。 有时候,我意识到我仍然需要 Downloads 文件夹中的一个文件,所以忘记一个文件而不是立即删除它可能是有帮助的。 但是,还有一些文件我下载明确是为了使用一次,然后应该删除。

我决定使用一个高度具体的 Ansible 任务来查找我知道我不需要的文件,然后删除它们。

Ansible 样板

Ansible playbook 通常以完全相同的方式开始:定义你的主机并声明一个任务

---
- hosts: localhost
  tasks:

将这三行代码记在心里。 它们是 Ansible playbook 的 "shebang" (#!)。 一旦你将这些行放在一个文本文件中,你就可以开始定义你的任务步骤。

使用 Ansible 查找文件

你可以使用 find Ansible 模块在系统上查找文件。 如果一个 Ansible 模块是一个命令,那么它的参数就是它的 命令选项。 在这个 playbook 示例中,我想查找明确位于 ~/Downloads 文件夹中的文件,我可以使用 paths 参数来定义它。

这是我开始编写 playbook 时的过程:我在 Ansible 模块索引中找到一个似乎可以完成我需要的模块,然后我阅读它的参数以了解我对该模块的控制程度。

就我而言,我意外地收集在我的 Downloads 文件夹中的文件是 CSV 文件。 它们每周都会被下载、处理,然后应该消失。 但它们会持续存在数周,直到我感到不堪重负并删除它们。 以下是如何使用 Ansible 在 Downloads 中查找 CSV 文件

---
- hosts: localhost
  tasks:
    - name: Find CSV in Downloads
      find:
        paths: ~/Downloads
        recurse: false
        patterns: '*.csv,*.CSV'
      register: result

paths 参数告诉 Ansible 在哪里搜索文件。

recurse: false 参数禁止 Ansible 在 Downloads 的子目录中搜索。 这使我能够保留我下载并保存到子目录中的 CSV 文件。 Ansible 仅以我直接保存到 Downloads 的 CSV 文件(这是我的习惯)为目标。

patterns 参数告诉 Ansible 什么应该被视为匹配项。 我下载的所有 CSV 文件都以 .csv 结尾,但我相信我愿意删除 .CSV (全部大写)。

完成此步骤的点睛之笔是调用 register 模块,该模块将 find 过程的结果保存到名为 result 的变量中。

这很重要,因为我希望 Ansible 对 find 的结果执行第二个操作,因此这些结果需要存储在某个地方以供下一步使用。

使用 Ansible 删除文件

任务中的下一步是删除 find 发现的文件。 用于删除文件的模块是 file 模块

此步骤完全依赖于 find 步骤,因此它使用了多个变量

    - name: Remove CSV files
      file:
        path: "{{ item.path }}"
        state: absent
      with_items: "{{ result.files }}"

path 参数使用内置的 "{{ item.path }}" 变量,但令人困惑的是,该变量实际上尚未定义。 在 with_items 关键字在循环中使用 file 模块之前,该变量没有关于路径的信息。 with_items 步骤使用 result 变量的内容一次提取一个文件名,该文件名成为 path 参数的 item。 一旦提取了当前项目的路径,Ansible 就会使用 state: absent 规则来确保位于该路径的文件保留在系统上(换句话说,它被删除了)。

这是一个非常危险的步骤,尤其是在测试期间。 如果你搞错了这一步,你很容易删除你不想删除的文件。

验证 playbook

Ansible playbook 以 YAML 编写,它具有严格的语法。 使用 yamllint 命令验证你的 YAML 是否正确

$ yamllint cleanup.yaml
$

没有结果意味着没有错误。 这个 playbook 一定是由一个真正 了解并喜欢 YAML 的人编写的!

安全地测试 Ansible play

为了避免意外删除我的整个主目录,我使用 --check 选项运行了我的第一次尝试。 这确保 Ansible 实际上不会更改你的系统。

$ ansible-playbook --check example.yaml
[WARNING]: provided hosts list is empty, only localhost is available.
'all'

PLAY [localhost] ****************************************************

TASK [Gathering Facts] **********************************************
ok: [localhost]

TASK [Find CSV files in Downloads] **********************************
ok: [localhost]

TASK [Remove CSV files] *********************************************
changed: [localhost] => (item={'path': '/home/tux/Downloads/foo.csv', [...]
changed: [localhost] => (item={'path': '/home/tux/Downloads/bar.csv', [...]
changed: [localhost] => (item={'path': '/home/tux/Downloads/baz.csv', [...]

PLAY RECAP **********************************************************
localhost                  : ok=3    changed=1    unreachable=0 [...]

输出非常冗长,但它表明我的 playbook 是正确的:只有 Downloads 中的 CSV 文件被标记为删除。

运行 Ansible playbook

要运行 Ansible playbook,请使用 ansible-playbook 命令

$ ansible-playbook example.yaml

确认结果

$ ls *.csv  ~/Downloads/
ls: cannot access '*.csv': No such file or directory
/home/tux/Downloads/:
file.txt

安排 Ansible playbook

Ansible playbook 已经确认,但我希望它至少每周运行一次。 我使用 Anacron 而不是 Cron,所以我创建了一个 Anacron 作业来每周运行

$ cat << EOF >> ~/.local/etc/cron.weekly/cleanup
#!/bin/sh
ansible-playbook $HOME/Ansible/cleanup.yaml
EOF
$ chmod +x ~/.local/etc/cron.daily/cleanup

你能用 Ansible 做什么?

通常,Ansible 旨在作为系统维护工具。 它经过精心调整,可以引导复杂的系统,以帮助在出现问题时进行纠正,并使系统保持特定状态。 我已将其用于简单但重复性的任务,例如设置一个复杂的目录树,通常需要多个命令或单击。 我也将其用于我不想出错的任务,例如从目录中删除旧文件。 我也将其用于我不想费心记住的任务,例如将对生产系统所做的多个更改与其冗余备份系统同步。

我不在我的服务器上使用这个清理脚本,因为我不在我的服务器上每周下载 CSV 文件,但我确实使用了它的一个变体。 Ansible 不能替代 shell 或 Python 脚本,但对于某些任务来说,它是一种非常精确的方法来执行你可能希望在更多系统上运行的一些任务。

接下来阅读什么
Seth Kenlon
Seth Kenlon 是一位 UNIX 极客、自由文化倡导者、独立多媒体艺术家和 D&D 爱好者。 他曾在电影和计算行业工作,而且经常同时工作。

贡献者

2 条评论

很棒的例子! 特别是对于个人用例。 虽然使用 Ansible 很容易做到这一点,但正是这种练习让我找到了 organize-tool (https://organize.readthedocs.io/)。 谢谢。

很好! 感谢你向我推荐 Organize。 我会去看看,并且可能会向一些人推荐它。 我认识 *很多* 桌面非常混乱的人,他们可能会非常欣赏这个!

回复 作者 orx57

Creative Commons License 本作品根据 Creative Commons Attribution-Share Alike 4.0 International License 授权。
© . All rights reserved.