- Add artifact_server.go for edge node artifact serving - Refactor bootstrap/runtime.go to use new artifact server - Update Makefile for new build workflow - Remove deprecated bin/build/field-binaries.sh - Update edge README with new development workflow - Update edge-local-dev-guide.md with artifact server info - Add config and hostsetup updates for artifact serving - Update agent-ops rules and testing domain rules
72 lines
1.9 KiB
Go
72 lines
1.9 KiB
Go
package bootstrap
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"net"
|
|
"net/http"
|
|
"os"
|
|
"time"
|
|
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
// ArtifactServer serves node bootstrap scripts and node binaries from the
|
|
// configured artifact directory. It is intentionally static: iop-edge prepares
|
|
// the directory, then serve exposes it without mutating the artifacts.
|
|
type ArtifactServer struct {
|
|
listen string
|
|
dir string
|
|
logger *zap.Logger
|
|
server *http.Server
|
|
}
|
|
|
|
func NewArtifactServer(listen, dir string, logger *zap.Logger) *ArtifactServer {
|
|
return &ArtifactServer{listen: listen, dir: dir, logger: logger}
|
|
}
|
|
|
|
func (s *ArtifactServer) Start(ctx context.Context) error {
|
|
if s == nil || s.listen == "" || s.dir == "" {
|
|
return nil
|
|
}
|
|
if _, err := os.Stat(s.dir); err != nil {
|
|
if errors.Is(err, os.ErrNotExist) {
|
|
s.logger.Warn("bootstrap artifact directory does not exist", zap.String("dir", s.dir))
|
|
} else {
|
|
return fmt.Errorf("stat bootstrap artifact dir: %w", err)
|
|
}
|
|
}
|
|
|
|
mux := http.NewServeMux()
|
|
mux.Handle("/", http.FileServer(http.Dir(s.dir)))
|
|
s.server = &http.Server{
|
|
Addr: s.listen,
|
|
Handler: mux,
|
|
ReadHeaderTimeout: 5 * time.Second,
|
|
}
|
|
ln, err := net.Listen("tcp", s.listen)
|
|
if err != nil {
|
|
return fmt.Errorf("bootstrap artifact server listen %s: %w", s.listen, err)
|
|
}
|
|
go func() {
|
|
<-ctx.Done()
|
|
shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
defer cancel()
|
|
_ = s.server.Shutdown(shutdownCtx)
|
|
}()
|
|
go func() {
|
|
s.logger.Info("bootstrap artifact server listening", zap.String("addr", s.listen), zap.String("dir", s.dir))
|
|
if err := s.server.Serve(ln); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
|
s.logger.Warn("bootstrap artifact server exited", zap.Error(err))
|
|
}
|
|
}()
|
|
return nil
|
|
}
|
|
|
|
func (s *ArtifactServer) Stop(ctx context.Context) error {
|
|
if s == nil || s.server == nil {
|
|
return nil
|
|
}
|
|
return s.server.Shutdown(ctx)
|
|
}
|