feat(delivery): complete MySQL version-to-package mapping

- 8.0 from Ubuntu archive, 8.4 from MySQL official APT repo
- 5.6/5.7 not supported for now; enforce one MySQL series per host
- Sync Go version whitelist with the playbook package map
This commit is contained in:
Hungerdream
2026-07-27 15:18:54 +08:00
parent e8e9612527
commit bfb4f0df4d
4 changed files with 61 additions and 9 deletions
+48 -6
View File
@@ -8,9 +8,18 @@
# --- identity ---
mysql_instance: "{{ instance_name }}"
mysql_version_value: "{{ mysql_version | default('8.0') }}"
# 版本包映射:8.0 用 Ubuntu 24.04 自带源(精确锁版);8.4 用 MySQL 官方 APT 源的 LTS 组件
# (noble 自带源无 8.4,官方源组件内即为该系列,不再锁小版本)。
# 5.6/5.7 已官方 EOL 且 Ubuntu 24.04 无可用 apt 包,明确不纳入白名单。
mysql_package_map:
"8.0": "mysql-server=8.0.46-0ubuntu0.24.04.3"
mysql_package_name: "{{ mysql_package_map[mysql_version_value] }}"
"8.0":
package: "mysql-server=8.0.46-0ubuntu0.24.04.3"
repo_component: ""
"8.4":
package: "mysql-community-server"
repo_component: "mysql-8.4-lts"
mysql_package_name: "{{ (mysql_package_map[mysql_version_value] | default({})).package | default('') }}"
mysql_repo_component: "{{ (mysql_package_map[mysql_version_value] | default({})).repo_component | default('') }}"
# --- platform-allocated inputs (safe fallbacks when not passed in) ---
# 端口池 13306–13999:平台从池分配并传入;未传时兜底池首端口,占用探测在目标机执行。
@@ -132,13 +141,46 @@
host-wide Σ-quota budgeting is the platform's responsibility, this is a last-resort guard.
tasks:
- name: Detect an existing Ubuntu MySQL package
ansible.builtin.command: dpkg-query -W mysql-server
- name: Detect an existing MySQL server package
ansible.builtin.command: dpkg-query -W -f '${Package}=${Version}\n' mysql-server mysql-community-server
register: mysql_package_before
failed_when: false
changed_when: false
- name: Install Ubuntu MySQL package
- name: Resolve the installed MySQL server version
ansible.builtin.set_fact:
mysql_installed_version: >-
{{ (mysql_package_before.stdout_lines | select('search', '=') | list
| first | default('')).split('=') | last }}
# /usr 下的 mysqld/mysql 二进制全机共享,一台主机只能承载一个 MySQL 版本系列。
- name: Enforce host-level MySQL series consistency
ansible.builtin.assert:
that:
- mysql_installed_version == '' or mysql_installed_version.startswith(mysql_version_value ~ '.')
fail_msg: >-
Host already runs MySQL {{ mysql_installed_version }} but {{ mysql_version_value }} was requested;
native binaries under /usr are shared host-wide, so one host serves exactly one MySQL series.
- name: Install the MySQL APT repository signing key
ansible.builtin.get_url:
url: https://repo.mysql.com/RPM-GPG-KEY-mysql-2023
dest: /etc/apt/keyrings/mysql.asc
owner: root
group: root
mode: '0644'
when: mysql_repo_component != ''
- name: Configure the MySQL APT repository component
ansible.builtin.apt_repository:
repo: >-
deb [signed-by=/etc/apt/keyrings/mysql.asc]
http://repo.mysql.com/apt/ubuntu {{ ansible_distribution_release }} {{ mysql_repo_component }}
filename: xinfra-mysql-delivery
state: present
when: mysql_repo_component != ''
- name: Install the MySQL server package
ansible.builtin.apt:
name: "{{ mysql_package_name }}"
state: present
@@ -150,7 +192,7 @@
name: mysql.service
state: stopped
enabled: false
when: mysql_package_before.rc != 0
when: mysql_installed_version == ''
- name: Check for the bundled MySQL AppArmor profile
ansible.builtin.stat:
+3
View File
@@ -66,7 +66,10 @@ loose-mysqlx=0
{% if topology == 'mgr_3' %}
# --- Group Replication (config-ready; runtime bootstrap handled out-of-band) ---
plugin-load-add=group_replication.so
{% if mysql_version_value != '8.4' %}
{# deprecated since 8.0.26 and removed in 8.3+; only inject for older series #}
transaction-write-set-extraction=XXHASH64
{% endif %}
loose-group-replication-group-name={{ mgr_group_name }}
loose-group-replication-start-on-boot=OFF
loose-group-replication-local-address={{ ansible_host | default(inventory_hostname) }}:{{ mysql_gr_port_value }}
+4 -3
View File
@@ -286,8 +286,9 @@ func (s *DeliveryService) CreateTask(ctx context.Context, userID uint64, isAdmin
return &task, false, nil
}
// 版本白名单与 playbook 的 mysql_package_map 保持同步。
var supportedMySQLVersions = map[string]bool{"8.0": true}
// 版本白名单与 playbook 的 mysql_package_map 保持同步:
// 8.0 走 Ubuntu 自带源,8.4 走 MySQL 官方 APT 源;5.6/5.7 已 EOL 且无 noble 包,不支持。
var supportedMySQLVersions = map[string]bool{"8.0": true, "8.4": true}
// 拓扑白名单:playbook 已支持 primary_replica/mgr_3 的配置渲染,
// 但调度器仍是单主机模型且复制编排未自动化,本期仅放开 standalone。
@@ -319,7 +320,7 @@ func validateDeliveryInput(input MySQLDeliveryInput, dataDisks []string) error {
return fmt.Errorf("requested resources are outside the supported range (memory: 2048-65536 MiB, storage: 20-2000 GiB)")
}
if input.MySQLVersion != "" && !supportedMySQLVersions[input.MySQLVersion] {
return fmt.Errorf("unsupported mysql_version %q, supported: 8.0", input.MySQLVersion)
return fmt.Errorf("unsupported mysql_version %q, supported: 8.0, 8.4 (5.6/5.7 are EOL and have no Ubuntu 24.04 packages)", input.MySQLVersion)
}
if input.Topology != "" && !supportedTopologies[input.Topology] {
return fmt.Errorf("unsupported topology %q, supported: standalone (primary_replica/mgr_3 pending scheduler support)", input.Topology)
+6
View File
@@ -37,6 +37,11 @@ func TestValidateDeliveryInput(t *testing.T) {
if err := validateDeliveryInput(namedZone, dataDisks); err != nil {
t.Fatalf("named timezone rejected: %v", err)
}
lts := valid
lts.MySQLVersion = "8.4"
if err := validateDeliveryInput(lts, dataDisks); err != nil {
t.Fatalf("8.4 LTS rejected: %v", err)
}
for name, mutate := range map[string]func(*MySQLDeliveryInput){
"uppercase namespace": func(in *MySQLDeliveryInput) { in.Namespace = "Team-A" },
"bad instance": func(in *MySQLDeliveryInput) { in.InstanceName = "mysql_01" },
@@ -45,6 +50,7 @@ func TestValidateDeliveryInput(t *testing.T) {
"too little storage": func(in *MySQLDeliveryInput) { in.StorageGi = 10 },
"too much storage": func(in *MySQLDeliveryInput) { in.StorageGi = 4000 },
"unsupported version": func(in *MySQLDeliveryInput) { in.MySQLVersion = "5.7" },
"eol version": func(in *MySQLDeliveryInput) { in.MySQLVersion = "5.6" },
"unsupported topology": func(in *MySQLDeliveryInput) { in.Topology = "mgr_3" },
"port below pool": func(in *MySQLDeliveryInput) { in.MySQLPort = 3307 },
"port above pool": func(in *MySQLDeliveryInput) { in.MySQLPort = 14000 },