Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion pkg/admin/prerun/prerun.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,13 @@ func (hi *HealthInfo) IsHealthy() bool {

type PreRun struct {
dataManager data.Manager
config *config.Config
}

func New(dataManager data.Manager) *PreRun {
func New(dataManager data.Manager, config *config.Config) *PreRun {
return &PreRun{
dataManager: dataManager,
config: config,
}
}

Expand Down Expand Up @@ -187,6 +189,11 @@ func (pr *PreRun) regularPrerun() error {

if migrationNeeded {
_ = migrationNeeded
stop, err := runMinimalMicroshift(pr.config)
if err != nil {
return fmt.Errorf("minimal MicroShift run failed to be ready: %w", err)
}
defer stop()
Comment on lines +192 to +196
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can put these lines and L220-L224 to a separate function, like a migrateStorage that would call runMinimalMicroshift() and run the migrator

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds like a plan, do you want me to put that in a separate function in this PR, or do it in #1956 ?

// TODO: data migration

if err := writeExecVersionToData(); err != nil {
Expand All @@ -210,6 +217,11 @@ func (pr *PreRun) upgradeFrom413() error {
return fmt.Errorf("failed to create new backup %q: %w", backupName, err)
}

stop, err := runMinimalMicroshift(pr.config)
if err != nil {
return fmt.Errorf("minimal MicroShift run failed to be ready: %w", err)
}
defer stop()
// TODO: data migration

if err := writeExecVersionToData(); err != nil {
Expand Down
87 changes: 87 additions & 0 deletions pkg/admin/prerun/run_minimal.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package prerun

import (
"context"
"fmt"
"os"
"os/signal"
"syscall"
"time"

"github.com/openshift/microshift/pkg/config"
"github.com/openshift/microshift/pkg/controllers"
"github.com/openshift/microshift/pkg/node"
"github.com/openshift/microshift/pkg/servicemanager"
"github.com/openshift/microshift/pkg/util"

"k8s.io/klog/v2"
)

const (
gracefulShutdownTimeout = time.Second * 30
readyStateTimeout = time.Second * 10
)

// runMinimalMicroshift initializes a minimum run of microshift core services during pre-run
// to help with storage migration.
//
// Returns a handler to shutdown MicroShfit services and error if services never became ready.
func runMinimalMicroshift(cfg *config.Config) (context.CancelFunc, error) {
// Establish the context we will use to control execution
runCtx, runCancel := context.WithCancel(context.Background())
m := servicemanager.NewServiceManager()
util.Must(m.AddService(node.NewNetworkConfiguration(cfg)))
util.Must(m.AddService(controllers.NewEtcd(cfg)))
util.Must(m.AddService(controllers.NewKubeAPIServer(cfg)))

// Start core services up
ready, stopped := make(chan struct{}), make(chan struct{})
go func() {
klog.Infof("Started %s", m.Name())
if err := m.Run(runCtx, ready, stopped); err != nil {
klog.Errorf("Stopped %s: %v", m.Name(), err)
} else {
klog.Infof("%s completed", m.Name())
}
}()

// Connect os signal handler
sigTerm := make(chan os.Signal, 1)
signal.Notify(sigTerm, os.Interrupt, syscall.SIGTERM)

go func() {
select {
case <-sigTerm:
klog.Info("Interrupt received")
klog.Info("Stopping services")
runCancel()
case <-runCtx.Done():
klog.Info("Done signal from context received")
}
}()

// Provides a function to call when you want to stop the services
// because this is a blocking call it serves as a call and wait for
// all the services to stop.
stopFunc := func() {
runCancel()
select {
case <-stopped:
case <-time.After(gracefulShutdownTimeout):
klog.Infof("Timed out waiting for services to stop")
}
klog.Infof("MicroShift Sevices stopped")
}

// If Microshift does not become ready by the deadline, we consider that an error
select {
case <-ready:
klog.Infof("MicroShift is ready in minimal state")
case <-time.After(readyStateTimeout):
klog.Error("MicroShift never became ready in minimal state")
stopFunc()
return nil, fmt.Errorf("services failed to be in ready state by timeout(%s)", readyStateTimeout)
}

return stopFunc, nil
}
6 changes: 3 additions & 3 deletions pkg/cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,13 @@ func logConfig(cfg *config.Config) {
}
}

func performPrerun() error {
func performPrerun(cfg *config.Config) error {
dataManager, err := data.NewManager(config.BackupsDir)
if err != nil {
return err
}

return prerun.New(dataManager).Perform()
return prerun.New(dataManager, cfg).Perform()
}

func RunMicroshift(cfg *config.Config) error {
Expand All @@ -93,7 +93,7 @@ func RunMicroshift(cfg *config.Config) error {
klog.Fatalf("MicroShift must be run privileged")
}

if err := performPrerun(); err != nil {
if err := performPrerun(cfg); err != nil {
klog.ErrorS(err, "Pre-run procedure failed")
return err
}
Expand Down