Files
xinfra/server/internal/model/delivery.go
T
Hungerdream 0ca3af39dc feat(server): 支持 MySQL 一主多从拓扑调度与复制健康检查
- DeliveryTask/DeploymentResult 新增 target_hosts/target_host_ips 完整节点列表(主节点在前)
- 交付输入支持 replica_count(1-7)与有序 target_hosts,按节点数放大配额/预留/资源用量
- 端口占用与已占主机解析改为逗号列表,兼容存量单主机字段
- 指定主机校验池成员/重复/单机实例数,自动补齐剩余节点或延后调度
- AWX Limit 与回滚覆盖全部节点,extra_vars 下发主从主机与 IP 列表
- completeTask 全节点 TCP 探活,副本经 mysqlReplicationReady 校验复制线程状态
- awxTaskSummary 按服务类型生成摘要;go-sql-driver/mysql 提为直接依赖
2026-07-31 18:12:05 +08:00

236 lines
13 KiB
Go

package model
import "time"
const (
TaskPending = "pending"
TaskValidating = "validating"
TaskDispatching = "dispatching"
TaskRunning = "running"
TaskRegistering = "registering"
TaskFinished = "finished"
TaskRegisterFailed = "register_failed"
TaskExecutionFailed = "execution_failed"
TaskValidationFailed = "validation_failed"
TaskCanceling = "canceling"
TaskCanceled = "canceled"
TaskRollbackPending = "rollback_pending"
TaskRollingBack = "rolling_back"
TaskRolledBack = "rolled_back"
TaskRollbackFailed = "rollback_failed"
TaskRollbackAck = "rollback_acknowledged"
)
type ResourceQuota struct {
ID uint64 `gorm:"primaryKey" json:"id"`
BusinessLineID uint64 `gorm:"not null;uniqueIndex:idx_resource_quota_scope,priority:1" json:"business_line_id"`
TargetID uint64 `gorm:"not null;uniqueIndex:idx_resource_quota_scope,priority:2" json:"target_id"`
CPUMilli int64 `gorm:"not null" json:"cpu_milli"`
MemoryMi int64 `gorm:"not null" json:"memory_mi"`
StorageGi int64 `gorm:"not null" json:"storage_gi"`
InstanceLimit int64 `gorm:"not null" json:"instance_limit"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type DeliveryTask struct {
ID string `gorm:"size:36;primaryKey" json:"id"`
BusinessLineID uint64 `gorm:"not null;index" json:"business_line_id"`
RequestedBy uint64 `gorm:"not null;index" json:"requested_by"`
Component string `gorm:"size:32;not null;default:mysql;index" json:"component"`
TargetType string `gorm:"size:32;not null" json:"target_type"`
ServiceType string `gorm:"size:32;not null;default:'mysql';index" json:"service_type"`
TargetID uint64 `gorm:"not null;index" json:"target_id"`
Namespace string `gorm:"size:63;not null;index" json:"namespace"`
InstanceName string `gorm:"size:63;not null" json:"instance_name"`
TargetHost string `gorm:"size:1024" json:"target_host,omitempty"`
TargetHostIP string `gorm:"size:64" json:"target_host_ip,omitempty"`
// For primary_replica, these contain the complete node lists in primary,replica order.
TargetHosts string `gorm:"type:text" json:"target_hosts,omitempty"`
TargetHostIPs string `gorm:"type:text" json:"target_host_ips,omitempty"`
MySQLPort int `gorm:"column:mysql_port;not null;default:3307" json:"mysql_port"`
PostgreSQLPort int `gorm:"column:postgresql_port;not null;default:15432" json:"postgresql_port,omitempty"`
Status string `gorm:"size:32;not null;index" json:"status"`
ImmutablePayload string `gorm:"type:json;not null" json:"immutable_payload"`
PayloadHash string `gorm:"size:64;not null" json:"payload_hash"`
IdempotencyKey string `gorm:"size:128;not null;uniqueIndex" json:"idempotency_key"`
ErrorMessage string `gorm:"type:text" json:"error_message,omitempty"`
CreatedAt time.Time `gorm:"index" json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
StartedAt *time.Time `json:"started_at,omitempty"`
FinishedAt *time.Time `json:"finished_at,omitempty"`
CredentialAvailable bool `gorm:"-" json:"credential_available"`
}
type ResourceReservation struct {
ID uint64 `gorm:"primaryKey" json:"id"`
TaskID string `gorm:"size:36;not null;uniqueIndex" json:"task_id"`
BusinessLineID uint64 `gorm:"not null;index" json:"business_line_id"`
TargetID uint64 `gorm:"not null;index" json:"target_id"`
CPUMilli int64 `gorm:"not null" json:"cpu_milli"`
MemoryMi int64 `gorm:"not null" json:"memory_mi"`
StorageGi int64 `gorm:"not null" json:"storage_gi"`
InstanceCount int64 `gorm:"not null;default:1" json:"instance_count"`
Status string `gorm:"size:32;not null;index" json:"status"`
ExpiresAt time.Time `gorm:"not null;index" json:"expires_at"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type ResourceUsage struct {
ID uint64 `gorm:"primaryKey" json:"id"`
TaskID string `gorm:"size:36;not null;uniqueIndex" json:"task_id"`
InstanceID uint64 `gorm:"not null;uniqueIndex" json:"instance_id"`
BusinessLineID uint64 `gorm:"not null;index" json:"business_line_id"`
TargetID uint64 `gorm:"not null;index" json:"target_id"`
CPUMilli int64 `gorm:"not null" json:"cpu_milli"`
MemoryMi int64 `gorm:"not null" json:"memory_mi"`
StorageGi int64 `gorm:"not null" json:"storage_gi"`
InstanceCount int64 `gorm:"not null;default:1" json:"instance_count"`
Status string `gorm:"size:32;not null;index" json:"status"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
ReleasedAt *time.Time `json:"released_at,omitempty"`
}
type DeploymentResult struct {
ID uint64 `gorm:"primaryKey" json:"id"`
TaskID string `gorm:"size:36;not null;uniqueIndex" json:"task_id"`
BusinessLineID uint64 `gorm:"not null;index" json:"business_line_id"`
Component string `gorm:"size:32;not null;index" json:"component"`
ServiceType string `gorm:"size:32;not null;index" json:"service_type"`
InstanceName string `gorm:"size:128;not null;index" json:"instance_name"`
Namespace string `gorm:"size:128;not null;default:'';index" json:"namespace"`
TargetID uint64 `gorm:"not null;index" json:"target_id"`
NodeName string `gorm:"size:128;not null;default:''" json:"node_name"`
Host string `gorm:"size:255;not null;default:''" json:"host"`
TargetHosts string `gorm:"type:text" json:"target_hosts,omitempty"`
TargetHostIPs string `gorm:"type:text" json:"target_host_ips,omitempty"`
Port int `gorm:"not null;default:0" json:"port"`
Version string `gorm:"size:64;not null;default:''" json:"version"`
Status string `gorm:"size:32;not null;index" json:"status"`
Metadata string `gorm:"type:json" json:"metadata"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type DeploymentCredential struct {
ID uint64 `gorm:"primaryKey" json:"id"`
TaskID string `gorm:"size:36;not null;index" json:"task_id"`
DeploymentResultID uint64 `gorm:"not null;default:0;index" json:"deployment_result_id"`
BusinessLineID uint64 `gorm:"not null;index" json:"business_line_id"`
Component string `gorm:"size:32;not null;index" json:"component"`
InstanceName string `gorm:"size:128;not null;index" json:"instance_name"`
Username string `gorm:"size:128;not null" json:"username"`
AccountHost string `gorm:"size:128;not null;default:''" json:"account_host"`
Ciphertext string `gorm:"type:text;not null" json:"-"`
Nonce string `gorm:"size:64;not null" json:"-"`
Status string `gorm:"size:32;not null;index" json:"status"`
Source string `gorm:"size:64;not null;default:'user_input'" json:"source"`
ViewedBy uint64 `gorm:"not null;default:0" json:"viewed_by"`
ViewedAt *time.Time `json:"viewed_at,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type PostgreSQLCluster struct {
ID uint64 `gorm:"primaryKey" json:"id"`
TaskID string `gorm:"size:36;not null;uniqueIndex" json:"task_id"`
BusinessLineID uint64 `gorm:"not null;index" json:"business_line_id"`
TargetID uint64 `gorm:"not null;index" json:"target_id"`
Name string `gorm:"size:63;not null;uniqueIndex" json:"name"`
VersionMajor string `gorm:"size:8;not null" json:"version_major"`
Topology string `gorm:"size:32;not null" json:"topology"`
ReplicationMode string `gorm:"size:32;not null;default:'async'" json:"replication_mode"`
FailoverMode string `gorm:"size:32;not null;default:'manual'" json:"failover_mode"`
PrimaryInstanceID uint64 `gorm:"not null;default:0" json:"primary_instance_id"`
Status string `gorm:"size:32;not null;index" json:"status"`
BackupStatus string `gorm:"size:32;not null;default:'not_configured'" json:"backup_status"`
MonitoringStatus string `gorm:"size:32;not null;default:'not_configured'" json:"monitoring_status"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type PostgreSQLInstance struct {
ID uint64 `gorm:"primaryKey" json:"id"`
TaskID string `gorm:"size:36;not null;index" json:"task_id"`
ClusterID uint64 `gorm:"not null;index" json:"cluster_id"`
BusinessLineID uint64 `gorm:"not null;index" json:"business_line_id"`
TargetID uint64 `gorm:"not null;index" json:"target_id"`
InstanceID string `gorm:"size:63;not null;uniqueIndex" json:"instance_id"`
Hostname string `gorm:"size:255;not null;uniqueIndex:idx_postgresql_host_port,priority:1" json:"hostname"`
HostIP string `gorm:"size:64;not null" json:"host_ip"`
Port int `gorm:"not null;index:idx_postgresql_host_port,priority:2" json:"port"`
DataDir string `gorm:"size:512;not null;uniqueIndex" json:"data_dir"`
ConfigDir string `gorm:"size:512;not null" json:"config_dir"`
LogDir string `gorm:"size:512;not null" json:"log_dir"`
SystemdUnit string `gorm:"size:128;not null" json:"systemd_unit"`
VersionMajor string `gorm:"size:8;not null" json:"version_major"`
VersionFull string `gorm:"size:32;not null;default:''" json:"version_full"`
Role string `gorm:"size:16;not null" json:"role"`
HAComponentRole string `gorm:"size:16;not null;default:'database'" json:"ha_component_role"`
UpstreamInstanceID string `gorm:"size:63;not null;default:''" json:"upstream_instance_id"`
ReplicationSlotName string `gorm:"size:63;not null;default:''" json:"replication_slot_name"`
Status string `gorm:"size:32;not null;index" json:"status"`
Metadata string `gorm:"type:json" json:"metadata"`
BackupStatus string `gorm:"size:32;not null;default:'not_configured'" json:"backup_status"`
MonitoringStatus string `gorm:"size:32;not null;default:'not_configured'" json:"monitoring_status"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type PostgreSQLResourceUsage struct {
ID uint64 `gorm:"primaryKey" json:"id"`
TaskID string `gorm:"size:36;not null;index" json:"task_id"`
InstanceID uint64 `gorm:"not null;uniqueIndex" json:"instance_id"`
ClusterID uint64 `gorm:"not null;index" json:"cluster_id"`
BusinessLineID uint64 `gorm:"not null;index" json:"business_line_id"`
TargetID uint64 `gorm:"not null;index" json:"target_id"`
CPUMilli int64 `gorm:"not null" json:"cpu_milli"`
MemoryMi int64 `gorm:"not null" json:"memory_mi"`
StorageGi int64 `gorm:"not null" json:"storage_gi"`
Port int `gorm:"not null" json:"port"`
DataDir string `gorm:"size:512;not null" json:"data_dir"`
Status string `gorm:"size:32;not null;index" json:"status"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
ReleasedAt *time.Time `json:"released_at,omitempty"`
}
type ExecutionJob struct {
ID uint64 `gorm:"primaryKey" json:"id"`
TaskID string `gorm:"size:36;not null;uniqueIndex" json:"task_id"`
IdempotencyKey string `gorm:"size:128;not null;uniqueIndex" json:"idempotency_key"`
ExecutorJobID string `gorm:"size:128;not null;uniqueIndex" json:"executor_job_id"`
Status string `gorm:"size:32;not null;index" json:"status"`
StartedAt *time.Time `json:"started_at,omitempty"`
FinishedAt *time.Time `json:"finished_at,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// RollbackJob tracks the compensating AWX run independently from the deploy run.
// Keeping a separate record preserves both job IDs for audit and retry tooling.
type RollbackJob struct {
ID uint64 `gorm:"primaryKey" json:"id"`
TaskID string `gorm:"size:36;not null;uniqueIndex" json:"task_id"`
ExecutorJobID string `gorm:"size:128;not null" json:"executor_job_id"`
Status string `gorm:"size:32;not null;index" json:"status"`
Reason string `gorm:"type:text" json:"reason"`
StartedAt *time.Time `json:"started_at,omitempty"`
FinishedAt *time.Time `json:"finished_at,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type TaskEvent struct {
ID uint64 `gorm:"primaryKey" json:"id"`
TaskID string `gorm:"size:36;not null;index" json:"task_id"`
FromState string `gorm:"size:32;not null" json:"from_state"`
ToState string `gorm:"size:32;not null" json:"to_state"`
Stage string `gorm:"size:32;index" json:"stage,omitempty"`
EventStatus string `gorm:"size:32;index" json:"event_status,omitempty"`
Message string `gorm:"type:text" json:"message"`
CreatedAt time.Time `gorm:"index" json:"created_at"`
}