本文目录导读:

我来介绍几种用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配置:配置与代码分离,便于分享和版本控制
选择哪种方法取决于你的具体需求和项目规模。