diff --git a/snap/local/hooks/cmd/configure/configure.go b/snap/local/hooks/cmd/configure/configure.go index 91a2bbe639..35bdc67f98 100644 --- a/snap/local/hooks/cmd/configure/configure.go +++ b/snap/local/hooks/cmd/configure/configure.go @@ -28,8 +28,6 @@ import ( hooks "github.com/canonical/edgex-snap-hooks/v2" ) -var cli *hooks.CtlCli = hooks.NewSnapCtl() - const ( // iota is reset to 0 kuiperService = iota secProxyService @@ -310,7 +308,6 @@ func handleAllServices(deferStartup bool) error { // grab and log the current service configuration for _, s := range hooks.Services { - var envJSON string var serviceList []string status, err := cli.Config(s) @@ -320,18 +317,9 @@ func handleAllServices(deferStartup bool) error { hooks.Debug(fmt.Sprintf("edgexfoundry:configure: service: %s status: %s", s, status)) - serviceCfg := hooks.EnvConfig + "." + s - envJSON, err = cli.Config(serviceCfg) + err = applyConfigOptions(s) if err != nil { - err = fmt.Errorf("edgexfoundry:configure failed to read service %s configuration - %v", s, err) - return err - } - - if envJSON != "" { - hooks.Debug(fmt.Sprintf("edgexfoundry:configure: service: %s envJSON: %s", s, envJSON)) - if err := hooks.HandleEdgeXConfig(s, envJSON, nil); err != nil { - return err - } + return fmt.Errorf("failed to apply config options for %s: %v", s, err) } // if deferStartup is set, don't start/stop services @@ -527,7 +515,7 @@ func checkSecurityConfig(services []string) ([]string, error) { return services, nil } -func main() { +func configure() { var debug = false var err error var startServices []string @@ -544,8 +532,8 @@ func main() { if err = hooks.Init(debug, "edgexfoundry"); err != nil { fmt.Println(fmt.Sprintf("edgexfoundry:configure: initialization failure: %v", err)) os.Exit(1) - } + hooks.Info("edgexfoundry:configure: started") val, err := cli.Config("install-mode") if err != nil { @@ -601,6 +589,7 @@ func main() { os.Exit(1) } + // NOTE - the services will be started after the configure hook finishes if err = cli.StartMultiple(true, startServices...); err != nil { hooks.Error(fmt.Sprintf("edgexfoundry:configure failure starting/enabling services: %v", err)) os.Exit(1) diff --git a/snap/local/hooks/cmd/configure/main.go b/snap/local/hooks/cmd/configure/main.go new file mode 100644 index 0000000000..d1b269d771 --- /dev/null +++ b/snap/local/hooks/cmd/configure/main.go @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2022 Canonical Ltd + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0' + */ + +package main + +import ( + "os" + + hooks "github.com/canonical/edgex-snap-hooks/v2" +) + +var cli *hooks.CtlCli = hooks.NewSnapCtl() + +func main() { + // no subcommand, as called by snapd + if len(os.Args) == 1 { + // configure everything + configure() + return + } + + subCommand := os.Args[1] + switch subCommand { + case "options": + // configure options + options() + default: + panic("Unknown CLI sub-command: " + subCommand) + } +} diff --git a/snap/local/hooks/cmd/configure/options.go b/snap/local/hooks/cmd/configure/options.go new file mode 100644 index 0000000000..2876ec7208 --- /dev/null +++ b/snap/local/hooks/cmd/configure/options.go @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2022 Canonical Ltd + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0' + */ + +package main + +import ( + "flag" + "fmt" + "os" + + hooks "github.com/canonical/edgex-snap-hooks/v2" +) + +func applyConfigOptions(service string) error { + envJSON, err := cli.Config(hooks.EnvConfig + "." + service) + if err != nil { + return fmt.Errorf("failed to read config options for %s: %v", service, err) + } + + if envJSON != "" { + hooks.Debug(fmt.Sprintf("edgexfoundry:configure-options: service: %s envJSON: %s", service, envJSON)) + if err := hooks.HandleEdgeXConfig(service, envJSON, nil); err != nil { + return err + } + } + return nil +} + +// options is called by the main function to configure options +func options() { + flagset := flag.NewFlagSet("options", flag.ExitOnError) + service := flagset.String("service", "", "Handle config options of a single service only") + flagset.Parse(os.Args[2:]) + + fmt.Println("Configuring options for service: " + *service) + + debug, err := cli.Config("debug") + if err != nil { + fmt.Println(fmt.Sprintf("edgexfoundry:configure-options: can't read value of 'debug': %v", err)) + os.Exit(1) + } + + if err = hooks.Init(debug == "true", "edgexfoundry"); err != nil { + fmt.Println(fmt.Sprintf("edgexfoundry:configure-options: initialization failure: %v", err)) + os.Exit(1) + } + + hooks.Info("edgexfoundry:configure-options: handling config options for a single service: " + *service) + + if err := applyConfigOptions(*service); err != nil { + hooks.Error(fmt.Sprintf("edgexfoundry:configure-options: error handling config options for %s: %v", *service, err)) + os.Exit(1) + } +} diff --git a/snap/local/hooks/go.mod b/snap/local/hooks/go.mod index d93df77acf..bd2e95b37d 100644 --- a/snap/local/hooks/go.mod +++ b/snap/local/hooks/go.mod @@ -1,5 +1,5 @@ module github.com/canonical/edgex-go/hooks -require github.com/canonical/edgex-snap-hooks/v2 v2.1.1 +require github.com/canonical/edgex-snap-hooks/v2 v2.1.3 go 1.16 diff --git a/snap/local/hooks/go.sum b/snap/local/hooks/go.sum index 0561495ce0..039e14dc08 100644 --- a/snap/local/hooks/go.sum +++ b/snap/local/hooks/go.sum @@ -1,5 +1,5 @@ -github.com/canonical/edgex-snap-hooks/v2 v2.1.1 h1:qmDJ2RYd19I/NYwIdjqC/kWGVJWLcrT+h9NevB+Gz/A= -github.com/canonical/edgex-snap-hooks/v2 v2.1.1/go.mod h1:rOxrwdYL7hJDhxFH3uV+nVgLPjWOhJWgM5PRD5YG1jI= +github.com/canonical/edgex-snap-hooks/v2 v2.1.3 h1:mcV/atn6k6sN6Uik+lSQGEZi4Q6r96epgBW+u6AGZ3Y= +github.com/canonical/edgex-snap-hooks/v2 v2.1.3/go.mod h1:rOxrwdYL7hJDhxFH3uV+nVgLPjWOhJWgM5PRD5YG1jI= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= diff --git a/snap/local/runtime-helpers/bin/security-proxy-post-setup.sh b/snap/local/runtime-helpers/bin/security-proxy-post-setup.sh new file mode 100755 index 0000000000..066decdb49 --- /dev/null +++ b/snap/local/runtime-helpers/bin/security-proxy-post-setup.sh @@ -0,0 +1,13 @@ +#!/bin/bash -e + +# This script is called as a post-stop-command when +# security-proxy-setup oneshot service stops. + +logger "edgexfoundry:security-proxy-post-setup" + +# add bin directory to have e.g. secret-config in PATH +export PATH="$SNAP/bin:$PATH" + +# Several config options depend on resources that only exist after proxy +# setup. This re-applies the config options logic after deferred startup: +$SNAP/snap/hooks/configure options --service=security-proxy diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 937b5cadee..096b51591c 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -221,6 +221,7 @@ apps: command: bin/security-proxy-setup -confdir $SNAP_DATA/config/security-proxy-setup/res $INIT_ARG command-chain: - bin/service-config-overrides.sh + post-stop-command: bin/security-proxy-post-setup.sh environment: INIT_ARG: "--init=true" SECRETSTORE_TOKENFILE: $SNAP_DATA/secrets/security-proxy-setup/secrets-token.json