Python脚本如何生成Vagrant配置

wen 实用脚本 4

本文目录导读:

Python脚本如何生成Vagrant配置

  1. 使用字符串模板(最简单)
  2. 使用Jinja2模板(推荐-更灵活)
  3. 使用配置类(面向对象方式)
  4. 使用YAML配置文件

我来介绍几种用Python生成Vagrant配置的方法:

使用字符串模板(最简单)

def generate_vagrantfile(hostname="default", ip="192.168.33.10", memory=1024, cpus=1):
    vagrantfile = f"""
Vagrant.configure("2") do |config|
    config.vm.box = "ubuntu/focal64"
    config.vm.hostname = "{hostname}"
    config.vm.network "private_network", ip: "{ip}"
    config.vm.provider "virtualbox" do |vb|
        vb.memory = {memory}
        vb.cpus = {cpus}
    end
    config.vm.provision "shell", inline: <<-SHELL
        apt-get update
        apt-get install -y python3
    SHELL
end
"""
    return vagrantfile
# 使用示例
config = generate_vagrantfile(
    hostname="web-server",
    ip="192.168.33.20",
    memory=2048,
    cpus=2
)
with open("Vagrantfile", "w") as f:
    f.write(config)

使用Jinja2模板(推荐-更灵活)

首先安装:pip install jinja2

from jinja2 import Template
# 定义模板
template = Template("""
Vagrant.configure("2") do |config|
    {% for vm in vms %}
    config.vm.define "{{ vm.name }}" do |{{ vm.name }}|
        {{ vm.name }}.vm.box = "{{ vm.box | default('ubuntu/focal64') }}"
        {{ vm.name }}.vm.hostname = "{{ vm.hostname | default(vm.name) }}"
        {{ vm.name }}.vm.network "private_network", ip: "{{ vm.ip }}"
        {{ vm.name }}.vm.provider "virtualbox" do |vb|
            vb.memory = {{ vm.memory | default(1024) }}
            vb.cpus = {{ vm.cpus | default(1) }}
        end
        {% if vm.provision %}
        {{ vm.name }}.vm.provision "shell", inline: <<-SHELL
            {{ vm.provision }}
        SHELL
        {% endif %}
        {% if vm.synced_folders %}
        {% for folder in vm.synced_folders %}
        {{ vm.name }}.vm.synced_folder "{{ folder.host }}", "{{ folder.guest }}"
        {% endfor %}
        {% endif %}
    end
    {% endfor %}
end
""")
# 配置多台虚拟机
vms_config = {
    "vms": [
        {
            "name": "web",
            "hostname": "web-server",
            "ip": "192.168.33.10",
            "memory": 2048,
            "cpus": 2,
            "provision": "apt-get update\napt-get install -y nginx",
            "synced_folders": [
                {"host": "./www", "guest": "/var/www/html"}
            ]
        },
        {
            "name": "db", 
            "hostname": "db-server",
            "ip": "192.168.33.11",
            "memory": 4096,
            "cpus": 4,
            "box": "centos/8",
            "provision": "yum install -y mysql-server"
        },
        {
            "name": "cache",
            "hostname": "redis-server", 
            "ip": "192.168.33.12",
            "memory": 1024,
            "cpus": 1
        }
    ]
}
# 生成配置
vagrantfile_content = template.render(vms_config)
# 写入文件
with open("Vagrantfile", "w") as f:
    f.write(vagrantfile_content)

使用配置类(面向对象方式)

import json
from typing import List, Optional
class VagrantVM:
    def __init__(self, name: str, ip: str, box: str = "ubuntu/focal64",
                 memory: int = 1024, cpus: int = 1, hostname: Optional[str] = None,
                 provision: Optional[str] = None, ports: List[dict] = None,
                 synced_folders: List[dict] = None):
        self.name = name
        self.ip = ip
        self.box = box
        self.memory = memory
        self.cpus = cpus
        self.hostname = hostname or name
        self.provision = provision
        self.ports = ports or []
        self.synced_folders = synced_folders or []
class VagrantConfig:
    def __init__(self):
        self.vms = []
    def add_vm(self, vm: VagrantVM):
        self.vms.append(vm)
        return self
    def generate(self) -> str:
        config_lines = ['Vagrant.configure("2") do |config|']
        for vm in self.vms:
            config_lines.append(f'  config.vm.define "{vm.name}" do |{vm.name}|')
            config_lines.append(f'    {vm.name}.vm.box = "{vm.box}"')
            config_lines.append(f'    {vm.name}.vm.hostname = "{vm.hostname}"')
            config_lines.append(f'    {vm.name}.vm.network "private_network", ip: "{vm.ip}"')
            # 端口转发
            for port in vm.ports:
                config_lines.append(
                    f'    {vm.name}.vm.network "forwarded_port", '
                    f'guest: {port["guest"]}, host: {port["host"]}'
                )
            # 同步文件夹
            for folder in vm.synced_folders:
                config_lines.append(
                    f'    {vm.name}.vm.synced_folder "{folder["host"]}", "{folder["guest"]}"'
                )
            # 提供者配置
            config_lines.append(f'    {vm.name}.vm.provider "virtualbox" do |vb|')
            config_lines.append(f'      vb.memory = {vm.memory}')
            config_lines.append(f'      vb.cpus = {vm.cpus}')
            config_lines.append('    end')
            # 自动化配置
            if vm.provision:
                config_lines.append(f'    {vm.name}.vm.provision "shell", inline: <<-SHELL')
                config_lines.append(f'      {vm.provision}')
                config_lines.append('    SHELL')
            config_lines.append('  end')
        config_lines.append('end')
        return '\n'.join(config_lines)
    def to_json(self, filename: str = "vagrant_config.json"):
        config_dict = {
            "vms": [
                {
                    "name": vm.name,
                    "box": vm.box,
                    "ip": vm.ip,
                    "memory": vm.memory,
                    "cpus": vm.cpus,
                    "hostname": vm.hostname,
                    "provision": vm.provision,
                    "ports": vm.ports,
                    "synced_folders": vm.synced_folders
                }
                for vm in self.vms
            ]
        }
        with open(filename, "w") as f:
            json.dump(config_dict, f, indent=2)
# 使用示例
if __name__ == "__main__":
    # 创建配置
    config = VagrantConfig()
    # 添加Web服务器
    config.add_vm(VagrantVM(
        name="web",
        ip="192.168.33.10",
        memory=2048,
        cpus=2,
        provision="apt-get update\napt-get install -y nginx",
        ports=[{"guest": 80, "host": 8080}],
        synced_folders=[{"host": "./www", "guest": "/var/www/html"}]
    ))
    # 添加数据库服务器
    config.add_vm(VagrantVM(
        name="db",
        ip="192.168.33.11",
        box="centos/8",
        memory=4096,
        cpus=4,
        provision="yum install -y mysql-server"
    ))
    # 生成Vagrantfile
    vagrantfile_content = config.generate()
    with open("Vagrantfile", "w") as f:
        f.write(vagrantfile_content)
    # 导出JSON配置(备份/分享)
    config.to_json()
    print("Vagrantfile generated successfully!")

使用YAML配置文件

import yaml
from jinja2 import Template as Jinja2Template
def generate_from_yaml(yaml_file: str, output_file: str = "Vagrantfile"):
    # 读取YAML配置
    with open(yaml_file, 'r') as f:
        config = yaml.safe_load(f)
    # 使用Jinja2模板
    vagrant_template = """
Vagrant.configure("2") do |config|
    config.vm.box_check_update = {{ boxes_check_update | lower }}
    {% for vm in vms %}
    config.vm.define "{{ vm.name }}" do |{{ vm.name }}|
        {{ vm.name }}.vm.box = "{{ vm.box }}"
        {{ vm.name }}.vm.hostname = "{{ vm.hostname }}"
        {{ vm.name }}.vm.network "private_network", ip: "{{ vm.ip }}"
        {% if vm.network_type == "public" %}
        {{ vm.name }}.vm.network "public_network"
        {% endif %}
        {{ vm.name }}.vm.provider "{{ vm.provider | default('virtualbox') }}" do |vb|
            vb.memory = {{ vm.memory | default(1024) }}
            vb.cpus = {{ vm.cpus | default(1) }}
            {% if vm.gui %}
            vb.gui = true
            {% endif %}
        end
        {% if vm.provision %}
        {{ vm.name }}.vm.provision "shell", inline: <<-SHELL
            {{ vm.provision }}
        SHELL
        {% endif %}
        {% for folder in vm.synced_folders | default([]) %}
        {{ vm.name }}.vm.synced_folder "{{ folder.host }}", "{{ folder.guest }}"
        {% endfor %}
        {% for port in vm.ports | default([]) %}
        {{ vm.name }}.vm.network "forwarded_port", guest: {{ port.guest }}, host: {{ port.host }}
        {% endfor %}
    end
    {% endfor %}
end
"""
    template = Jinja2Template(vagrant_template)
    vagrantfile = template.render(config)
    with open(output_file, 'w') as f:
        f.write(vagrantfile)
# YAML配置文件示例 (vagrant_config.yaml):
"""
boxes_check_update: true
vms:
  - name: web
    box: ubuntu/focal64
    hostname: web-server
    ip: 192.168.33.10
    memory: 2048
    cpus: 2
    provider: virtualbox
    gui: false
    network_type: private
    ports:
      - guest: 80
        host: 8080
      - guest: 443
        host: 8443
    synced_folders:
      - host: ./www
        guest: /var/www/html
    provision: |
      apt-get update
      apt-get install -y nginx
      systemctl enable nginx
      systemctl start nginx
  - name: db
    box: centos/8
    hostname: db-server
    ip: 192.168.33.11
    memory: 4096
    cpus: 4
    provision: |
      yum update -y
      yum install -y mysql-server
      systemctl enable mysqld
"""
# 使用示例
# generate_from_yaml("vagrant_config.yaml")

这些方法各有优势:

  • 字符串模板:简单直接,适合快速原型
  • Jinja2模板:最灵活,支持复杂逻辑和循环
  • 面向对象:可维护性好,适合大型项目
  • YAML配置:配置与代码分离,便于分享和版本控制

选择哪种方法取决于你的具体需求和项目规模。

抱歉,评论功能暂时关闭!