initial upload
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
)
|
||||
|
||||
func main() {
|
||||
dsn := os.Getenv("TAPM_DATABASE_DSN")
|
||||
if dsn == "" {
|
||||
log.Fatal("TAPM_DATABASE_DSN is required")
|
||||
}
|
||||
directory := os.Getenv("TAPM_MIGRATIONS_DIR")
|
||||
if directory == "" {
|
||||
directory = "/app/migrations"
|
||||
}
|
||||
|
||||
db, err := sql.Open("mysql", dsn)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
|
||||
defer cancel()
|
||||
if err := db.PingContext(ctx); err != nil {
|
||||
log.Fatalf("database: %v", err)
|
||||
}
|
||||
|
||||
var locked int
|
||||
if err := db.QueryRowContext(ctx, `SELECT GET_LOCK('tapm_schema_migrations', 30)`).Scan(&locked); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if locked != 1 {
|
||||
log.Fatal("could not acquire migration lock")
|
||||
}
|
||||
defer db.ExecContext(context.Background(), `SELECT RELEASE_LOCK('tapm_schema_migrations')`)
|
||||
|
||||
if _, err := db.ExecContext(ctx, `CREATE TABLE IF NOT EXISTS schema_migrations (
|
||||
version BIGINT UNSIGNED NOT NULL PRIMARY KEY,
|
||||
applied_at TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6)
|
||||
) ENGINE=InnoDB`); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
entries, err := os.ReadDir(directory)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
sort.Slice(entries, func(i, j int) bool { return entries[i].Name() < entries[j].Name() })
|
||||
for _, entry := range entries {
|
||||
if entry.IsDir() || !strings.HasSuffix(entry.Name(), ".sql") {
|
||||
continue
|
||||
}
|
||||
versionText, _, ok := strings.Cut(entry.Name(), "_")
|
||||
if !ok {
|
||||
log.Fatalf("migration %q must begin with a numeric version and underscore", entry.Name())
|
||||
}
|
||||
version, err := strconv.ParseUint(versionText, 10, 64)
|
||||
if err != nil {
|
||||
log.Fatalf("migration %q: %v", entry.Name(), err)
|
||||
}
|
||||
var applied int
|
||||
if err := db.QueryRowContext(
|
||||
ctx,
|
||||
`SELECT COUNT(*) FROM schema_migrations WHERE version = ?`,
|
||||
version,
|
||||
).Scan(&applied); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if applied != 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
body, err := os.ReadFile(filepath.Join(directory, entry.Name()))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if _, err := db.ExecContext(ctx, string(body)); err != nil {
|
||||
log.Fatalf("apply %s: %v", entry.Name(), err)
|
||||
}
|
||||
fmt.Printf("applied migration %s\n", entry.Name())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"git.scity.us/TAI/TA-Deployment-Broker/internal/app"
|
||||
)
|
||||
|
||||
func main() {
|
||||
cfg, err := app.LoadConfig()
|
||||
if err != nil {
|
||||
log.Fatalf("configuration: %v", err)
|
||||
}
|
||||
|
||||
server, err := app.New(cfg)
|
||||
if err != nil {
|
||||
log.Fatalf("initialize: %v", err)
|
||||
}
|
||||
defer server.Close()
|
||||
|
||||
httpServer := &http.Server{
|
||||
Addr: cfg.ListenAddr,
|
||||
Handler: server.Routes(),
|
||||
ReadHeaderTimeout: 10 * time.Second,
|
||||
ReadTimeout: 30 * time.Second,
|
||||
WriteTimeout: 15 * time.Minute,
|
||||
IdleTimeout: 90 * time.Second,
|
||||
MaxHeaderBytes: 1 << 20,
|
||||
}
|
||||
|
||||
go func() {
|
||||
log.Printf("TAPM Deployment Access listening on %s", cfg.ListenAddr)
|
||||
if err := httpServer.ListenAndServe(); err != nil &&
|
||||
!errors.Is(err, http.ErrServerClosed) {
|
||||
log.Fatalf("serve: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
stop := make(chan os.Signal, 1)
|
||||
signal.Notify(stop, syscall.SIGINT, syscall.SIGTERM)
|
||||
<-stop
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
|
||||
defer cancel()
|
||||
if err := httpServer.Shutdown(ctx); err != nil {
|
||||
log.Printf("shutdown: %v", err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user