add user-facing cli to makefile, and config master address through .env

This commit is contained in:
Keiran 2025-08-07 19:16:12 +01:00
parent efd008f12a
commit 10e0c22108
4 changed files with 59 additions and 33 deletions

View File

@ -21,3 +21,7 @@ DB_HEALTH_CHECK_PERIOD=5s
# User Defaults and Billing # User Defaults and Billing
DEFAULT_STORAGE_LIMIT_GB=1 DEFAULT_STORAGE_LIMIT_GB=1
PRICE_PER_GB_USD=0.50 PRICE_PER_GB_USD=0.50
# Bitcoin Payment Configuration
BITCOIN_MASTER_ADDRESS=bc1qyour_bitcoin_address_here
BITCOIN_NETWORK=mainnet

View File

@ -1,5 +1,6 @@
BINARY = termcloud BINARY = termcloud
ADMIN_BINARY = termcloud-admin ADMIN_BINARY = termcloud-admin
CLI_BINARY = tcman
include .env include .env
export export
@ -7,6 +8,7 @@ export
build: clean build: clean
go build -o build/${BINARY} cmd/${BINARY}/main.go go build -o build/${BINARY} cmd/${BINARY}/main.go
go build -o build/${ADMIN_BINARY} cmd/admin/main.go go build -o build/${ADMIN_BINARY} cmd/admin/main.go
go build -o build/${CLI_BINARY} cmd/${CLI_BINARY}/main.go
run: build run: build
./build/${BINARY} ./build/${BINARY}
@ -14,9 +16,15 @@ run: build
admin: build admin: build
./build/${ADMIN_BINARY} $(ARGS) ./build/${ADMIN_BINARY} $(ARGS)
cli: build
./build/${CLI_BINARY} $(ARGS)
dev: dev:
go run cmd/${BINARY}/main.go go run cmd/${BINARY}/main.go
cli-dev:
go run cmd/${CLI_BINARY}/main.go $(ARGS)
clean: clean:
go clean ./... go clean ./...
rm -rf build rm -rf build
@ -24,4 +32,8 @@ clean:
test: test:
go test ./... go test ./...
.PHONY: build run admin dev clean test install: build
cp build/${CLI_BINARY} /usr/local/bin/tcman
chmod +x /usr/local/bin/tcman
.PHONY: build run admin cli dev cli-dev clean test install

View File

@ -7,38 +7,42 @@ import (
) )
type Config struct { type Config struct {
DatabaseURL string DatabaseURL string
Port string Port string
StorageDir string StorageDir string
MaxFileSize int64 MaxFileSize int64
RateLimit float64 RateLimit float64
CORSOrigins []string CORSOrigins []string
GzipLevel int GzipLevel int
MaxConnections int32 MaxConnections int32
MinConnections int32 MinConnections int32
ConnLifetime time.Duration ConnLifetime time.Duration
ConnIdleTime time.Duration ConnIdleTime time.Duration
HealthCheckPeriod time.Duration HealthCheckPeriod time.Duration
DefaultStorageLimit int64 DefaultStorageLimit int64
PricePerGBUSD float64 PricePerGBUSD float64
BitcoinMasterAddress string
BitcoinNetwork string
} }
func Load() *Config { func Load() *Config {
return &Config{ return &Config{
DatabaseURL: getEnv("DATABASE_URL", ""), DatabaseURL: getEnv("DATABASE_URL", ""),
Port: getEnv("PORT", "8080"), Port: getEnv("PORT", "8080"),
StorageDir: getEnv("STORAGE_DIR", "storage"), StorageDir: getEnv("STORAGE_DIR", "storage"),
MaxFileSize: getEnvInt64("MAX_FILE_SIZE_MB", 100) * 1024 * 1024, MaxFileSize: getEnvInt64("MAX_FILE_SIZE_MB", 100) * 1024 * 1024,
RateLimit: getEnvFloat64("RATE_LIMIT", 20.0), RateLimit: getEnvFloat64("RATE_LIMIT", 20.0),
CORSOrigins: getEnvSlice("CORS_ORIGINS", []string{"*"}), CORSOrigins: getEnvSlice("CORS_ORIGINS", []string{"*"}),
GzipLevel: getEnvInt("GZIP_LEVEL", 5), GzipLevel: getEnvInt("GZIP_LEVEL", 5),
MaxConnections: getEnvInt32("DB_MAX_CONNECTIONS", 100), MaxConnections: getEnvInt32("DB_MAX_CONNECTIONS", 100),
MinConnections: getEnvInt32("DB_MIN_CONNECTIONS", 10), MinConnections: getEnvInt32("DB_MIN_CONNECTIONS", 10),
ConnLifetime: getEnvDuration("DB_CONN_LIFETIME", time.Hour), ConnLifetime: getEnvDuration("DB_CONN_LIFETIME", time.Hour),
ConnIdleTime: getEnvDuration("DB_CONN_IDLE_TIME", time.Minute), ConnIdleTime: getEnvDuration("DB_CONN_IDLE_TIME", time.Minute),
HealthCheckPeriod: getEnvDuration("DB_HEALTH_CHECK_PERIOD", 5*time.Second), HealthCheckPeriod: getEnvDuration("DB_HEALTH_CHECK_PERIOD", 5*time.Second),
DefaultStorageLimit: getEnvInt64("DEFAULT_STORAGE_LIMIT_GB", 1) * 1024 * 1024 * 1024, DefaultStorageLimit: getEnvInt64("DEFAULT_STORAGE_LIMIT_GB", 1) * 1024 * 1024 * 1024,
PricePerGBUSD: getEnvFloat64("PRICE_PER_GB_USD", 0.50), PricePerGBUSD: getEnvFloat64("PRICE_PER_GB_USD", 0.50),
BitcoinMasterAddress: getEnv("BITCOIN_MASTER_ADDRESS", ""),
BitcoinNetwork: getEnv("BITCOIN_NETWORK", "mainnet"),
} }
} }

View File

@ -55,8 +55,9 @@ type UsageRecord struct {
} }
type AccountService struct { type AccountService struct {
pool *pgxpool.Pool pool *pgxpool.Pool
pricePerGB float64 pricePerGB float64
bitcoinMasterAddr string
} }
func NewAccountService(pool *pgxpool.Pool, cfg *config.Config) *AccountService { func NewAccountService(pool *pgxpool.Pool, cfg *config.Config) *AccountService {
@ -66,8 +67,9 @@ func NewAccountService(pool *pgxpool.Pool, cfg *config.Config) *AccountService {
} }
return &AccountService{ return &AccountService{
pool: pool, pool: pool,
pricePerGB: pricePerGB, pricePerGB: pricePerGB,
bitcoinMasterAddr: cfg.BitcoinMasterAddress,
} }
} }
@ -422,6 +424,10 @@ func (s *AccountService) CheckResourceLimits(ctx context.Context, accountID int6
} }
func (s *AccountService) generateBTCAddress() string { func (s *AccountService) generateBTCAddress() string {
if s.bitcoinMasterAddr != "" {
return s.bitcoinMasterAddr
}
bytes := make([]byte, 20) bytes := make([]byte, 20)
rand.Read(bytes) rand.Read(bytes)
return fmt.Sprintf("bc1q%x", bytes) return fmt.Sprintf("bc1q%x", bytes)