Skip to content

Commit

Permalink
Merge pull request PelicanPlatform#569 from bbockelm/xrootd_tls_maint…
Browse files Browse the repository at this point in the history
…enance

Reload TLS certificates as needed
  • Loading branch information
bbockelm authored Dec 30, 2023
2 parents 847b81a + 49072a5 commit c84322f
Show file tree
Hide file tree
Showing 25 changed files with 641 additions and 52 deletions.
2 changes: 1 addition & 1 deletion cmd/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ var (
)

func initCache() error {
err := config.InitServer([]config.ServerType{config.CacheType}, config.CacheType)
err := config.InitServer(config.CacheType)
cobra.CheckErr(err)
metrics.SetComponentHealthStatus(metrics.OriginCache_XRootD, metrics.StatusCritical, "xrootd has not been started")
metrics.SetComponentHealthStatus(metrics.OriginCache_CMSD, metrics.StatusCritical, "cmsd has not been started")
Expand Down
10 changes: 9 additions & 1 deletion cmd/cache_serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"encoding/json"
"net/url"
"sync"
"time"

"github.com/pelicanplatform/pelican/cache_ui"
"github.com/pelicanplatform/pelican/config"
Expand Down Expand Up @@ -125,14 +126,21 @@ func serveCache( /*cmd*/ *cobra.Command /*args*/, []string) error {
return err
}

go web_ui.RunEngine(engine)
go func() {
if err := web_ui.RunEngine(shutdownCtx, engine); err != nil {
log.Panicln("Failure when running the web engine:", err)
}
shutdownCancel()
}()
go web_ui.InitServerWebLogin()

configPath, err := xrootd.ConfigXrootd(false)
if err != nil {
return err
}

xrootd.LaunchXrootdMaintenance(shutdownCtx, 2*time.Minute)

log.Info("Launching cache")
launchers, err := xrootd.ConfigureLaunchers(false, configPath, false)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion cmd/director.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func getDirectorEndpoint() (string, error) {
}

func initDirector() error {
err := config.InitServer([]config.ServerType{config.DirectorType}, config.DirectorType)
err := config.InitServer(config.DirectorType)
cobra.CheckErr(err)

return err
Expand Down
9 changes: 7 additions & 2 deletions cmd/director_serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func serveDirector( /*cmd*/ *cobra.Command /*args*/, []string) error {
// or to an origin
defaultResponse := param.Director_DefaultResponse.GetString()
if !(defaultResponse == "cache" || defaultResponse == "origin") {
return fmt.Errorf("The director's default response must either be set to 'cache' or 'origin',"+
return fmt.Errorf("the director's default response must either be set to 'cache' or 'origin',"+
" but you provided %q. Was there a typo?", defaultResponse)
}
log.Debugf("The director will redirect to %ss by default", defaultResponse)
Expand All @@ -93,7 +93,12 @@ func serveDirector( /*cmd*/ *cobra.Command /*args*/, []string) error {
director.RegisterDirector(rootGroup)

log.Info("Starting web engine...")
go web_ui.RunEngine(engine)
go func() {
if err := web_ui.RunEngine(shutdownCtx, engine); err != nil {
log.Panicln("Failure when running the web engine:", err)
}
shutdownCancel()
}()

go web_ui.InitServerWebLogin()

Expand Down
2 changes: 1 addition & 1 deletion cmd/origin.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ func configOrigin( /*cmd*/ *cobra.Command /*args*/, []string) {
}

func initOrigin() error {
err := config.InitServer([]config.ServerType{config.OriginType}, config.OriginType)
err := config.InitServer(config.OriginType)
cobra.CheckErr(err)
metrics.SetComponentHealthStatus(metrics.OriginCache_XRootD, metrics.StatusCritical, "xrootd has not been started")
metrics.SetComponentHealthStatus(metrics.OriginCache_CMSD, metrics.StatusCritical, "cmsd has not been started")
Expand Down
2 changes: 1 addition & 1 deletion cmd/origin_reset_password_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func TestResetPassword(t *testing.T) {
dirName := t.TempDir()
viper.Reset()
viper.Set("ConfigDir", dirName)
err := config.InitServer([]config.ServerType{config.OriginType}, config.OriginType)
err := config.InitServer(config.OriginType)
require.NoError(t, err)

rootCmd.SetArgs([]string{"origin", "web-ui", "reset-password", "--stdin"})
Expand Down
10 changes: 9 additions & 1 deletion cmd/origin_serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"context"
_ "embed"
"sync"
"time"

"github.com/pelicanplatform/pelican/config"
"github.com/pelicanplatform/pelican/daemon"
Expand Down Expand Up @@ -101,7 +102,12 @@ func serveOrigin( /*cmd*/ *cobra.Command /*args*/, []string) error {
}
}

go web_ui.RunEngine(engine)
go func() {
if err := web_ui.RunEngine(shutdownCtx, engine); err != nil {
log.Panicln("Failure when running the web engine:", err)
}
shutdownCancel()
}()

if param.Origin_EnableUI.GetBool() {
go web_ui.InitServerWebLogin()
Expand All @@ -116,6 +122,8 @@ func serveOrigin( /*cmd*/ *cobra.Command /*args*/, []string) error {
go origin_ui.PeriodicSelfTest()
}

xrootd.LaunchXrootdMaintenance(shutdownCtx, 2*time.Minute)

privileged := param.Origin_Multiuser.GetBool()
launchers, err := xrootd.ConfigureLaunchers(privileged, configPath, param.Origin_EnableCmsd.GetBool())
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion cmd/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ var (
)

func initRegistry() error {
err := config.InitServer([]config.ServerType{config.RegistryType}, config.RegistryType)
err := config.InitServer(config.RegistryType)
cobra.CheckErr(err)

return err
Expand Down
11 changes: 10 additions & 1 deletion cmd/registry_serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package main

import (
"context"
"os"
"os/signal"
"syscall"
Expand All @@ -35,6 +36,8 @@ import (

func serveRegistry( /*cmd*/ *cobra.Command /*args*/, []string) error {
log.Info("Initializing the namespace registry's database...")
shutdownCtx, shutdownCancel := context.WithCancel(context.Background())
defer shutdownCancel()

// Initialize the registry's sqlite database
err := registry.InitializeDB()
Expand Down Expand Up @@ -76,14 +79,20 @@ func serveRegistry( /*cmd*/ *cobra.Command /*args*/, []string) error {
// more complicated routing scenarios where we can't just use
// a wildcard. It removes duplicate / from the resource.
//engine.RemoveExtraSlash = true
go web_ui.RunEngine(engine)
go func() {
if err := web_ui.RunEngine(shutdownCtx, engine); err != nil {
log.Panicln("Failure when running the web engine:", err)
}
shutdownCancel()
}()

go web_ui.InitServerWebLogin()

sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
sig := <-sigs
_ = sig
shutdownCancel()

return nil
}
38 changes: 26 additions & 12 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,23 +123,34 @@ var (
)

// Set sets a list of newServers to ServerType instance
func (sType *ServerType) Set(newServers []ServerType) {
func (sType *ServerType) SetList(newServers []ServerType) {
for _, server := range newServers {
*sType |= server
}
}

// Enable a single server type in the bitmask
func (sType *ServerType) Set(server ServerType) ServerType {
*sType |= server
return *sType
}

// IsEnabled checks if a testServer is in the ServerType instance
func (sType ServerType) IsEnabled(testServer ServerType) bool {
return sType&testServer == testServer
}

// Clear all values in a server type
func (sType *ServerType) Clear() {
*sType = ServerType(0)
}

// setEnabledServer sets the global variable config.EnabledServers to include newServers.
// Since this function should only be called in config package, we mark it "private" to avoid
// reset value in other pacakge
//
// This will only be called once in a single process
func setEnabledServer(newServers []ServerType) {
func setEnabledServer(newServers ServerType) {
setServerOnce.Do(func() {
// For each process, we only want to set enabled servers once
enabledServers.Set(newServers)
Expand Down Expand Up @@ -376,7 +387,7 @@ func parseServerIssuerURL(sType ServerType) error {
return errors.New("If Server.IssuerHostname is configured, you must provide a valid port")
}

if sType == OriginType {
if sType.IsEnabled(OriginType) {
// If Origin.Mode is set to anything that isn't "posix" or "", assume we're running a plugin and
// that the origin's issuer URL actually uses the same port as OriginUI instead of XRootD. This is
// because under that condition, keys are being served by the Pelican process instead of by XRootD
Expand Down Expand Up @@ -505,20 +516,23 @@ func initConfigDir() error {
return nil
}

// Initialize Pelican server instance. Pass a list of "enabledServers" if you want to enable multiple servers,
// and pass your "current" server to instantiate through "currentServer" so that the functions
// knows which server it's being evoked for
func InitServer(enabledServers []ServerType, currentServer ServerType) error {
// Initialize Pelican server instance. Pass a list of `enabledServices` if you want to enable multiple services.
// Note not all configurations are supported: currently, if you enable both cache and origin then an error
// is thrown
func InitServer(enabledServices ServerType) error {
if err := initConfigDir(); err != nil {
return errors.Wrap(err, "Failed to initialize the server configuration")
}
if enabledServices.IsEnabled(OriginType) && enabledServices.IsEnabled(CacheType) {
return errors.New("A cache and origin cannot both be enabled in the same instance")
}

setEnabledServer(enabledServers)
setEnabledServer(enabledServices)

xrootdPrefix := ""
if currentServer == OriginType {
if enabledServices.IsEnabled(OriginType) {
xrootdPrefix = "origin"
} else if currentServer == CacheType {
} else if enabledServices.IsEnabled(CacheType) {
xrootdPrefix = "cache"
}
configDir := viper.GetString("ConfigDir")
Expand Down Expand Up @@ -590,7 +604,7 @@ func InitServer(enabledServers []ServerType, currentServer ServerType) error {
// they have overridden the defaults.
hostname = viper.GetString("Server.Hostname")

if currentServer == CacheType {
if enabledServices.IsEnabled(CacheType) {
viper.Set("Xrootd.Port", param.Cache_Port.GetInt())
}
xrootdPort := param.Xrootd_Port.GetInt()
Expand Down Expand Up @@ -650,7 +664,7 @@ func InitServer(enabledServers []ServerType, currentServer ServerType) error {

// Set up the server's issuer URL so we can access that data wherever we need to find keys and whatnot
// This populates Server.IssuerUrl, and can be safely fetched using server_utils.GetServerIssuerURL()
err = parseServerIssuerURL(currentServer)
err = parseServerIssuerURL(enabledServices)
if err != nil {
return err
}
Expand Down
13 changes: 9 additions & 4 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,25 +202,30 @@ func TestEnabledServers(t *testing.T) {
for _, server := range allServerTypes {
enabledServers = 0
// We didn't call setEnabledServer as it will only set once per process
enabledServers.Set([]ServerType{server})
enabledServers.SetList([]ServerType{server})
assert.True(t, IsServerEnabled(server))
}
})

t.Run("enable-multiple-servers", func(t *testing.T) {
enabledServers = 0
enabledServers.Set([]ServerType{OriginType, CacheType})
enabledServers.SetList([]ServerType{OriginType, CacheType})
assert.True(t, IsServerEnabled(OriginType))
assert.True(t, IsServerEnabled(CacheType))
})

t.Run("setEnabledServer-only-set-once", func(t *testing.T) {
enabledServers = 0
setEnabledServer([]ServerType{OriginType, CacheType})
sType := OriginType
sType.Set(CacheType)
setEnabledServer(sType)
assert.True(t, IsServerEnabled(OriginType))
assert.True(t, IsServerEnabled(CacheType))

setEnabledServer([]ServerType{DirectorType, RegistryType})
sType.Clear()
sType.Set(DirectorType)
sType.Set(RegistryType)
setEnabledServer(sType)
assert.True(t, IsServerEnabled(OriginType))
assert.True(t, IsServerEnabled(CacheType))
assert.False(t, IsServerEnabled(DirectorType))
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ require (
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/edsrzf/mmap-go v1.1.0 // indirect
github.com/felixge/httpsnoop v1.0.3 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/fsnotify/fsnotify v1.6.0
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/gin-contrib/sessions v0.0.5
github.com/gin-contrib/sse v0.1.0 // indirect
Expand Down
2 changes: 1 addition & 1 deletion registry/client_commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func registryMockup(t *testing.T, testName string) *httptest.Server {
ikey := filepath.Join(issuerTempDir, "issuer.jwk")
viper.Set("IssuerKey", ikey)
viper.Set("Registry.DbLocation", filepath.Join(issuerTempDir, "test.sql"))
err := config.InitServer([]config.ServerType{config.RegistryType}, config.RegistryType)
err := config.InitServer(config.RegistryType)
require.NoError(t, err)

err = InitializeDB()
Expand Down
2 changes: 1 addition & 1 deletion server_ui/register_namespace_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func TestRegistration(t *testing.T) {

config.InitConfig()
viper.Set("Registry.DbLocation", filepath.Join(tempConfigDir, "test.sql"))
err := config.InitServer([]config.ServerType{config.OriginType}, config.OriginType)
err := config.InitServer(config.OriginType)
require.NoError(t, err)

err = registry.InitializeDB()
Expand Down
Loading

0 comments on commit c84322f

Please sign in to comment.