mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-04 15:06:37 +08:00
[新增] OpenFlare Pages
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
package goose
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
presslygoose "github.com/pressly/goose/v3"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
const versionPagesStaticHosting int64 = 202606030001
|
||||
|
||||
// migration202606030001 adds OpenFlare Pages static hosting tables and the
|
||||
// proxy_routes.pages_project_id binding used by the global release snapshot.
|
||||
func migration202606030001(backend string, ctx Context) *presslygoose.Migration {
|
||||
return newGORMMigration(
|
||||
versionPagesStaticHosting,
|
||||
"202606030001_add_pages_static_hosting.go",
|
||||
backend,
|
||||
ctx,
|
||||
migratePagesStaticHosting,
|
||||
)
|
||||
}
|
||||
|
||||
func migratePagesStaticHosting(ctx Context, db *gorm.DB, backend string) error {
|
||||
if err := ctx.ApplyCurrentSchema(db, backend); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := db.Exec(
|
||||
`UPDATE proxy_routes SET upstream_type = 'direct' WHERE upstream_type IS NULL OR TRIM(upstream_type) = ''`,
|
||||
).Error; err != nil {
|
||||
return fmt.Errorf("backfill proxy_routes.upstream_type: %w", err)
|
||||
}
|
||||
return validatePagesStaticHosting(db)
|
||||
}
|
||||
|
||||
func validatePagesStaticHosting(db *gorm.DB) error {
|
||||
if db == nil {
|
||||
return fmt.Errorf("database handle is nil")
|
||||
}
|
||||
for _, table := range []string{"pages_projects", "pages_deployments", "pages_deployment_files"} {
|
||||
if !db.Migrator().HasTable(table) {
|
||||
return fmt.Errorf("table %s is missing", table)
|
||||
}
|
||||
}
|
||||
for _, column := range []string{"upstream_type", "pages_project_id"} {
|
||||
if !db.Migrator().HasColumn("proxy_routes", column) {
|
||||
return fmt.Errorf("column proxy_routes.%s is missing", column)
|
||||
}
|
||||
}
|
||||
for _, column := range []string{"slug", "active_deployment_id", "spa_fallback_enabled"} {
|
||||
if !db.Migrator().HasColumn("pages_projects", column) {
|
||||
return fmt.Errorf("column pages_projects.%s is missing", column)
|
||||
}
|
||||
}
|
||||
for _, column := range []string{"project_id", "checksum", "artifact_path", "entry_file"} {
|
||||
if !db.Migrator().HasColumn("pages_deployments", column) {
|
||||
return fmt.Errorf("column pages_deployments.%s is missing", column)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -41,6 +41,7 @@ func newGORMMigration(version int64, source string, backend string, ctx Context,
|
||||
func registeredMigrations(backend string, ctx Context) []*presslygoose.Migration {
|
||||
return []*presslygoose.Migration{
|
||||
migration202606020001(backend, ctx),
|
||||
migration202606030001(backend, ctx),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,9 @@ func registeredModels() []any {
|
||||
&Option{},
|
||||
&Origin{},
|
||||
&ProxyRoute{},
|
||||
&PagesProject{},
|
||||
&PagesDeployment{},
|
||||
&PagesDeploymentFile{},
|
||||
&ConfigVersion{},
|
||||
&Node{},
|
||||
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
const (
|
||||
PagesDeploymentStatusUploaded = "uploaded"
|
||||
PagesDeploymentStatusActive = "active"
|
||||
)
|
||||
|
||||
type PagesProject struct {
|
||||
ID uint `json:"id" gorm:"primaryKey"`
|
||||
Name string `json:"name" gorm:"size:255;not null"`
|
||||
Slug string `json:"slug" gorm:"uniqueIndex;size:128;not null"`
|
||||
Description string `json:"description" gorm:"type:text;not null;default:''"`
|
||||
Enabled bool `json:"enabled" gorm:"not null;default:true"`
|
||||
SPAFallbackEnabled bool `json:"spa_fallback_enabled" gorm:"not null;default:false"`
|
||||
ActiveDeploymentID *uint `json:"active_deployment_id" gorm:"index"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
type PagesDeployment struct {
|
||||
ID uint `json:"id" gorm:"primaryKey"`
|
||||
ProjectID uint `json:"project_id" gorm:"not null;index"`
|
||||
DeploymentNumber int `json:"deployment_number" gorm:"not null"`
|
||||
Checksum string `json:"checksum" gorm:"size:64;not null;index"`
|
||||
Status string `json:"status" gorm:"size:32;not null;default:'uploaded';index"`
|
||||
ArtifactPath string `json:"artifact_path" gorm:"size:2048;not null"`
|
||||
FileCount int `json:"file_count" gorm:"not null;default:0"`
|
||||
TotalSize int64 `json:"total_size" gorm:"not null;default:0"`
|
||||
EntryFile string `json:"entry_file" gorm:"size:512;not null;default:'index.html'"`
|
||||
CreatedBy string `json:"created_by" gorm:"size:64;not null;default:''"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
ActivatedAt *time.Time `json:"activated_at"`
|
||||
}
|
||||
|
||||
type PagesDeploymentFile struct {
|
||||
ID uint `json:"id" gorm:"primaryKey"`
|
||||
DeploymentID uint `json:"deployment_id" gorm:"not null;index"`
|
||||
Path string `json:"path" gorm:"size:2048;not null"`
|
||||
Size int64 `json:"size" gorm:"not null;default:0"`
|
||||
Checksum string `json:"checksum" gorm:"size:64;not null"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
func ListPagesProjects() (projects []*PagesProject, err error) {
|
||||
err = DB.Order("id desc").Find(&projects).Error
|
||||
return projects, err
|
||||
}
|
||||
|
||||
func GetPagesProjectByID(id uint) (*PagesProject, error) {
|
||||
project := &PagesProject{}
|
||||
err := DB.First(project, id).Error
|
||||
return project, err
|
||||
}
|
||||
|
||||
func GetPagesProjectBySlug(slug string) (*PagesProject, error) {
|
||||
project := &PagesProject{}
|
||||
err := DB.Where("slug = ?", slug).First(project).Error
|
||||
return project, err
|
||||
}
|
||||
|
||||
func ListPagesDeployments(projectID uint) (deployments []*PagesDeployment, err error) {
|
||||
err = DB.Where("project_id = ?", projectID).Order("id desc").Find(&deployments).Error
|
||||
return deployments, err
|
||||
}
|
||||
|
||||
func GetPagesDeploymentByID(id uint) (*PagesDeployment, error) {
|
||||
deployment := &PagesDeployment{}
|
||||
err := DB.First(deployment, id).Error
|
||||
return deployment, err
|
||||
}
|
||||
|
||||
func ListPagesDeploymentFiles(deploymentID uint) (files []*PagesDeploymentFile, err error) {
|
||||
err = DB.Where("deployment_id = ?", deploymentID).Order("path asc").Find(&files).Error
|
||||
return files, err
|
||||
}
|
||||
@@ -34,6 +34,7 @@ type ProxyRoute struct {
|
||||
TunnelNodeID *uint `json:"tunnel_node_id" gorm:"index"`
|
||||
TunnelTargetAddr string `json:"tunnel_target_addr" gorm:"size:512"`
|
||||
TunnelTargetProtocol string `json:"tunnel_target_protocol" gorm:"size:16"`
|
||||
PagesProjectID *uint `json:"pages_project_id" gorm:"index"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
@@ -95,6 +96,7 @@ func (route *ProxyRoute) Update() error {
|
||||
"tunnel_node_id": route.TunnelNodeID,
|
||||
"tunnel_target_addr": route.TunnelTargetAddr,
|
||||
"tunnel_target_protocol": route.TunnelTargetProtocol,
|
||||
"pages_project_id": route.PagesProjectID,
|
||||
}).Error
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user