internal/service/service.go (48 lines of code) (raw):

// Copyright 2024 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package service is a package with os specific service handling logic. package service import ( "context" "os" "os/signal" "syscall" "github.com/GoogleCloudPlatform/galog" ) // State is the type used in the state mapping enum. type State int const ( // StateUnknown is the default state of the service. StateUnknown State = iota // StateRunning is a mapping of native representation for: running. StateRunning // StateStopped is a mapping of native representation for: stopped. StateStopped ) var ( // nativeServiceName is the string used to register with the service manager. nativeServiceName string // nativeHandler is the OS specific implementation of serviceHandler. nativeHandler serviceHandler // serviceManagerSignal is the channel handle cases when the OS service // manager notifies it is shutting down/stopping the service. serviceManagerSignal = make(chan bool) ) // serviceHandler is the OS specific implementation interface. type serviceHandler interface { // register registers the application into the service manager. It will // perform different steps depending on the OS in question. register(ctx context.Context) error // setState changes the service state with the service manager. setState(ctx context.Context, state State) error // serviceID returns the service implementation ID. serviceID() string } // Init initializes the service management channels and signal handling. func Init(ctx context.Context, cancel context.CancelFunc, serviceName string) error { nativeServiceName = serviceName sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGTERM, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGHUP) go func() { select { case sig := <-sigChan: galog.Infof("GCE Guest Agent got signal: %d, leaving...", sig) close(sigChan) cancel() case <-ctx.Done(): break case <-serviceManagerSignal: // Cancels the context case the OS service manager notifies us it's // shutting down/stopping. cancel() } }() return nativeHandler.register(ctx) } func registerNativeHandler(handler serviceHandler) { nativeHandler = handler } // SetState wraps the OS specific implementation for SetState operation. func SetState(ctx context.Context, state State) error { return nativeHandler.setState(ctx, state) }