跳至内容

7. 贡献

为 cloud-init 项目做出贡献

恭喜!您已经从 cloud-init 的基本概念一路学习到高级配置和故障排除技巧。现在您是一名 cloud-init 高级用户了。本章将开启您旅程的下一步:从 cloud-init 的使用者转变为潜在的贡献者。

cloud-init 是一个至关重要的开源项目,其发展离不开社区的贡献。无论是修改文档中的错别字、报告 bug,还是编写全新的模块,每一次贡献都至关重要。本章将为您提供一个了解源代码、构建自定义模块以及与上游社区互动的概览。这不是一份详尽的开发者指南,而是一份友好的入门介绍。

1. cloud-init 源代码概览

在您贡献之前,您需要了解项目的整体结构。让我们来探索一下源代码并搭建一个基本的开发环境。

语言和代码仓库

cloud-init 的源代码几乎全部是用 Python 编写的,Canonical 在 Launchpad 上托管着 cloud-init 的源代码仓库。但为了更方便协作和更熟悉的用户界面,大多数贡献者都通过其在 GitHub 上的官方镜像进行交互。

要获取源代码,您可以克隆 GitHub 仓库。

# Clone the source code to your local machine
git clone https://github.com/canonical/cloud-init.git
cd cloud-init

搭建开发环境

为了在不影响系统 Python 包的情况下进行代码开发,您应该始终使用虚拟环境。

# Create a Python virtual environment
python3 -m venv .venv

# Activate the virtual environment
source .venv/bin/activate

# Install the required development dependencies
pip install -r requirements-dev.txt

源代码概览

浏览一个新的代码库可能令人望而生畏。以下是最重要的目录:

  • cloudinit/: 这是主要的 Python 源代码目录。
  • cloudinit/sources/: 此目录包含 数据源 (Datasources) 的代码(例如 DataSourceNoCloud.py)。这就是 cloud-init 如何检测和读取不同云平台配置的方式。
  • cloudinit/config/: 这里存放着 模块 (Modules)(例如 cc_packages.py, cc_users_groups.py)。cc_ 前缀是 `#cloud-config` 启用的模块的约定。这是最常进行新功能贡献的地方。
  • doc/: 项目的官方文档。改进文档是做出首次贡献的最佳方式之一。
  • tests/: 项目的全面测试套件。

2. 编写基础自定义模块

虽然 `runcmd` 非常有用,但编写一个 proper 模块是创建可重用、可移植且幂等的配置的最佳方式。

让我们创建一个最简单的模块:一个读取 `user-data` 中的配置键并将一条消息写入 `cloud-init` 日志的模块。

  1. 创建模块文件: 创建一个名为 `cloudinit/config/cc_hello_world.py` 的新文件。

    # Filename: cloudinit/config/cc_hello_world.py
    
    # A list of frequency and stage for this module to run
    frequency = "once-per-instance"
    distros = ["all"]
    
    def handle(name, cfg, cloud, log, args):
        # Get a 'message' key from the user-data config.
        # If it doesn't exist, use a default value.
        message = cfg.get("message", "Hello from a custom module!")
    
        # Write the message to the main cloud-init log.
        log.info(f"Hello World Module says: {message}")
    
  2. 启用模块: 仅创建文件是不够的。您必须告诉 cloud-init 运行它。在 `/etc/cloud/cloud.cfg.d/99-my-modules.cfg` 创建一个文件,并将您的模块添加到模块列表之一。

    # Add our custom module to the list of modules that run during the config stage
    cloud_config_modules:
      - hello_world
    
  3. 使用模块: 现在,您可以在 `user-data` 中使用该模块了。顶层键(`hello_world`)应与模块名(不带 `cc_` 前缀)匹配。

    #cloud-config
    hello_world:
      message: "My first custom module is working!"
    

使用此配置启动虚拟机后,您可以检查 `/var/log/cloud-init.log`,您将找到自定义消息,证明您的模块已成功运行。

3. 贡献工作流程

为开源项目做贡献遵循标准的工作流程。以下是简化的概述:

  1. 找到要处理的内容: 开始的最好地方是 Launchpad 上的项目问题跟踪器。查找 bug 或功能请求。鼓励新手从文档修复或标记为“易于解决”("low-hanging-fruit")或“初学者友好问题”("good first issue")的问题开始。

  2. Fork 和创建分支: 在 GitHub 上创建您自己的 cloud-init 仓库副本(称为“fork”)。然后,为您的更改创建一个新分支。

    git checkout -b my-documentation-fix
    
  3. 进行更改并提交: 进行代码或文档更改。提交时,写一个清晰的消息来描述您所做的操作。`-s` 标志会添加一个 `Signed-off-by` 行,该行证明您编写了补丁或有权贡献它。

    git commit -s -m "Doc: Fix typo in the users module documentation"
    
  4. 包含测试: 所有重要的贡献,特别是新功能,都必须包含测试。浏览 `tests/` 目录以了解现有模块是如何测试的。

  5. 提交 Pull Request (PR): 将您的分支推送到您在 GitHub 上的 fork,并向 `canonical/cloud-init` 仓库的 `main` 分支打开一个 Pull Request。这是您将您的工作包含在项目中的正式请求。

  6. 参与代码审查: 项目维护者将审查您的 PR。他们可能会提出问题或要求进行更改。这是一个协作过程。参与反馈是开源贡献的关键部分。

社区互动

要了解更多信息、提问以及与社区互动,您可以加入 OFTC IRC 网络上的 `#cloud-init` 频道或官方邮件列表。

最后的话

恭喜您完成了本指南。您已经从新手用户成长为 cloud-init 高级用户,现在您拥有了一份地图,可以指引您进入开源贡献的世界。cloud-init 社区非常欢迎您,他们重视您的贡献,无论大小。祝您构建愉快!

作者:Wale Soyinka

贡献者:Steven Spencer