From 9b06cc8229dae85320ab9f9965a3820a937524d3 Mon Sep 17 00:00:00 2001 From: Rashmi Gottipati Date: Tue, 7 Feb 2017 17:09:47 -0800 Subject: [PATCH] (SDI-2475) Configure the TempDir where the API loads plugins. --- control/config.go | 27 ++++++++++------ control/config_test.go | 3 -- control/flags.go | 8 ++++- docs/SNAPTELD.md | 1 + docs/SNAPTELD_CONFIGURATION.md | 3 ++ examples/configs/snap-config-sample.json | 1 + examples/configs/snap-config-sample.yaml | 3 ++ mgmt/rest/common/common.go | 39 ++++++++++++++++++++++++ mgmt/rest/v1/plugin.go | 33 ++------------------ mgmt/rest/v2/plugin.go | 35 ++------------------- snapteld.go | 2 ++ 11 files changed, 78 insertions(+), 77 deletions(-) create mode 100644 mgmt/rest/common/common.go diff --git a/control/config.go b/control/config.go index ef50897da..e456e4748 100644 --- a/control/config.go +++ b/control/config.go @@ -23,6 +23,7 @@ import ( "bytes" "encoding/json" "fmt" + "os" "reflect" "strconv" "time" @@ -36,16 +37,17 @@ import ( ) // default configuration values -const ( - defaultListenAddr string = "127.0.0.1" - defaultListenPort int = 8082 - defaultMaxRunningPlugins int = 3 - defaultPluginLoadTimeout int = 3 - defaultPluginTrust int = 1 - defaultAutoDiscoverPath string = "" - defaultKeyringPaths string = "" - defaultCacheExpiration time.Duration = 500 * time.Millisecond - defaultPprof bool = false +var ( + defaultListenAddr = "127.0.0.1" + defaultListenPort = 8082 + defaultMaxRunningPlugins = 3 + defaultPluginLoadTimeout = 3 + defaultPluginTrust = 1 + defaultAutoDiscoverPath = "" + defaultKeyringPaths = "" + defaultCacheExpiration = 500 * time.Millisecond + defaultPprof = false + defaultTempDirPath = os.TempDir() ) type pluginConfig struct { @@ -83,6 +85,7 @@ type Config struct { ListenPort int `json:"listen_port,omitempty"yaml:"listen_port"` Pprof bool `json:"pprof"yaml:"pprof"` MaxPluginRestarts int `json:"max_plugin_restarts"yaml:"max_plugin_restarts"` + TempDirPath string `json:"temp_dir_path"yaml:"temp_dir_path"` } const ( @@ -132,6 +135,9 @@ const ( "pprof": { "type": "boolean" }, + "temp_dir_path": { + "type": "string" + }, "max_plugin_restarts": { "type": "integer" } @@ -156,6 +162,7 @@ func GetDefaultConfig() *Config { Tags: newPluginTags(), Pprof: defaultPprof, MaxPluginRestarts: MaxPluginRestartCount, + TempDirPath: defaultTempDirPath, } } diff --git a/control/config_test.go b/control/config_test.go index a46b6ce6d..e74b2167b 100644 --- a/control/config_test.go +++ b/control/config_test.go @@ -309,9 +309,6 @@ func TestControlDefaultConfig(t *testing.T) { Convey("ListenPort should be set to 8082", func() { So(cfg.ListenPort, ShouldEqual, 8082) }) - Convey("KeyringPaths should be empty", func() { - So(cfg.KeyringPaths, ShouldEqual, "") - }) Convey("PluginTrust should equal 1", func() { So(cfg.PluginTrust, ShouldEqual, 1) }) diff --git a/control/flags.go b/control/flags.go index 03e7713c5..2e81f3d32 100644 --- a/control/flags.go +++ b/control/flags.go @@ -70,5 +70,11 @@ var ( EnvVar: "SNAP_CONTROL_LISTEN_ADDR", } - Flags = []cli.Flag{flNumberOfPLs, flPluginLoadTimeout, flAutoDiscover, flPluginTrust, flKeyringPaths, flCache, flControlRpcPort, flControlRpcAddr} + flTempDirPath = cli.StringFlag{ + Name: "temp_dir_path", + Usage: fmt.Sprintf("Temporary path for loading plugins (default: %v)", defaultTempDirPath), + EnvVar: "SNAP_TEMP_DIR_PATH", + } + + Flags = []cli.Flag{flNumberOfPLs, flPluginLoadTimeout, flAutoDiscover, flPluginTrust, flKeyringPaths, flCache, flControlRpcPort, flControlRpcAddr, flTempDirPath} ) diff --git a/docs/SNAPTELD.md b/docs/SNAPTELD.md index 08b5ec953..905859365 100644 --- a/docs/SNAPTELD.md +++ b/docs/SNAPTELD.md @@ -43,6 +43,7 @@ $ snapteld [global options] command [command options] [arguments...] --cache-expiration value The time limit for which a metric cache entry is valid (default: 500ms) [$SNAP_CACHE_EXPIRATION] --control-listen-port value Listen port for control RPC server (default: 8082) [$SNAP_CONTROL_LISTEN_PORT] --control-listen-addr value Listen address for control RPC server [$SNAP_CONTROL_LISTEN_ADDR] +--temp_dir_path value Temporary path for loading plugins [$SNAP_TEMP_DIR_PATH] --work-manager-queue-size value Size of the work manager queue (default: 25) [$WORK_MANAGER_QUEUE_SIZE] --work-manager-pool-size value Size of the work manager pool (default: 4) [$WORK_MANAGER_POOL_SIZE] --disable-api, -d Disable the agent REST API diff --git a/docs/SNAPTELD_CONFIGURATION.md b/docs/SNAPTELD_CONFIGURATION.md index 14217d83a..cb1d13f6d 100644 --- a/docs/SNAPTELD_CONFIGURATION.md +++ b/docs/SNAPTELD_CONFIGURATION.md @@ -101,6 +101,9 @@ control: # not be loaded. Valid values are 0 - Off, 1 - Enabled, 2 - Warning plugin_trust_level: 1 + # temp_dir_path sets the temporary directory which houses the temporary files + temp_dir_path: /tmp + # max_plugin_restarts controls how many times a plugin is allowed to be restarted # before failing. Snap will not disable a plugin due to failures when this value is -1. max_plugin_restarts: 10 diff --git a/examples/configs/snap-config-sample.json b/examples/configs/snap-config-sample.json index 6dcfd6d72..d27e24593 100644 --- a/examples/configs/snap-config-sample.json +++ b/examples/configs/snap-config-sample.json @@ -13,6 +13,7 @@ "max_running_plugins":1, "plugin_load_timeout":10, "keyring_paths":"/etc/snap/keyrings", + "temp_dir_path":"/tmp", "plugin_trust_level":0, "plugins":{ "all":{ diff --git a/examples/configs/snap-config-sample.yaml b/examples/configs/snap-config-sample.yaml index 0eb967f35..5a6a97c4e 100644 --- a/examples/configs/snap-config-sample.yaml +++ b/examples/configs/snap-config-sample.yaml @@ -65,6 +65,9 @@ control: # not be loaded. Valid values are 0 - Off, 1 - Enabled, 2 - Warning plugin_trust_level: 0 + # temp_dir_path sets the temporary directory which houses the temporary files + temp_dir_path: /tmp + # max_plugin_restarts controls how many times a plugin is allowed to be restarted # before failing. Snap will not disable a plugin due to failures when this value is -1. max_plugin_restarts: 10 diff --git a/mgmt/rest/common/common.go b/mgmt/rest/common/common.go new file mode 100644 index 000000000..a09f0712a --- /dev/null +++ b/mgmt/rest/common/common.go @@ -0,0 +1,39 @@ +package common + +import ( + "io/ioutil" + "os" + "path" + "runtime" + + log "github.com/Sirupsen/logrus" + "github.com/intelsdi-x/snap/control" +) + +func WriteFile(filename string, b []byte) (string, error) { + // Create temporary directory + dir, err := ioutil.TempDir(control.GetDefaultConfig().TempDirPath, "snap-plugin-") + if err != nil { + return "", err + } + + f, err := os.Create(path.Join(dir, filename)) + if err != nil { + return "", err + } + // Close before load + defer f.Close() + + n, err := f.Write(b) + log.Debugf("wrote %v to %v", n, f.Name()) + if err != nil { + return "", err + } + if runtime.GOOS != "windows" { + err = f.Chmod(0700) + if err != nil { + return "", err + } + } + return f.Name(), nil +} diff --git a/mgmt/rest/v1/plugin.go b/mgmt/rest/v1/plugin.go index 6451084b0..3e327b3b9 100644 --- a/mgmt/rest/v1/plugin.go +++ b/mgmt/rest/v1/plugin.go @@ -30,16 +30,14 @@ import ( "mime/multipart" "net/http" "os" - "path" "path/filepath" - "runtime" "strconv" "strings" - log "github.com/Sirupsen/logrus" "github.com/intelsdi-x/snap/core" "github.com/intelsdi-x/snap/core/serror" "github.com/intelsdi-x/snap/mgmt/rest/api" + "github.com/intelsdi-x/snap/mgmt/rest/common" "github.com/intelsdi-x/snap/mgmt/rest/v1/rbody" "github.com/julienschmidt/httprouter" ) @@ -128,7 +126,7 @@ func (s *apiV1) loadPlugin(w http.ResponseWriter, r *http.Request, _ httprouter. rbody.Write(500, rbody.FromError(e), w) return } - if pluginPath, err = writeFile(p.FileName(), b); err != nil { + if pluginPath, err = common.WriteFile(p.FileName(), b); err != nil { rbody.Write(500, rbody.FromError(err), w) return } @@ -187,33 +185,6 @@ func (s *apiV1) loadPlugin(w http.ResponseWriter, r *http.Request, _ httprouter. } } -func writeFile(filename string, b []byte) (string, error) { - // Create temporary directory - dir, err := ioutil.TempDir("", "") - if err != nil { - return "", err - } - f, err := os.Create(path.Join(dir, filename)) - if err != nil { - return "", err - } - // Close before load - defer f.Close() - - n, err := f.Write(b) - log.Debugf("wrote %v to %v", n, f.Name()) - if err != nil { - return "", err - } - if runtime.GOOS != "windows" { - err = f.Chmod(0700) - if err != nil { - return "", err - } - } - return f.Name(), nil -} - func (s *apiV1) unloadPlugin(w http.ResponseWriter, r *http.Request, p httprouter.Params) { plName := p.ByName("name") plType := p.ByName("type") diff --git a/mgmt/rest/v2/plugin.go b/mgmt/rest/v2/plugin.go index 78680ef3b..30b91e422 100644 --- a/mgmt/rest/v2/plugin.go +++ b/mgmt/rest/v2/plugin.go @@ -34,13 +34,10 @@ import ( "strconv" "strings" - "path" - "runtime" - - log "github.com/Sirupsen/logrus" "github.com/intelsdi-x/snap/control" "github.com/intelsdi-x/snap/core" "github.com/intelsdi-x/snap/core/serror" + "github.com/intelsdi-x/snap/mgmt/rest/common" "github.com/julienschmidt/httprouter" ) @@ -95,6 +92,7 @@ func (s *apiV2) loadPlugin(w http.ResponseWriter, r *http.Request, _ httprouter. Write(415, FromError(err), w) return } + if strings.HasPrefix(mediaType, "multipart/") { var pluginPath string var signature []byte @@ -146,7 +144,7 @@ func (s *apiV2) loadPlugin(w http.ResponseWriter, r *http.Request, _ httprouter. Write(400, FromError(e), w) return } - if pluginPath, err = writeFile(p.FileName(), b); err != nil { + if pluginPath, err = common.WriteFile(p.FileName(), b); err != nil { Write(500, FromError(err), w) return } @@ -204,33 +202,6 @@ func (s *apiV2) loadPlugin(w http.ResponseWriter, r *http.Request, _ httprouter. } } -func writeFile(filename string, b []byte) (string, error) { - // Create temporary directory - dir, err := ioutil.TempDir("", "") - if err != nil { - return "", err - } - f, err := os.Create(path.Join(dir, filename)) - if err != nil { - return "", err - } - // Close before load - defer f.Close() - - n, err := f.Write(b) - log.Debugf("wrote %v to %v", n, f.Name()) - if err != nil { - return "", err - } - if runtime.GOOS != "windows" { - err = f.Chmod(0700) - if err != nil { - return "", err - } - } - return f.Name(), nil -} - func pluginParameters(p httprouter.Params) (string, string, int, map[string]interface{}, serror.SnapError) { plName := p.ByName("name") plType := p.ByName("type") diff --git a/snapteld.go b/snapteld.go index 059f8ebe1..760d46f80 100644 --- a/snapteld.go +++ b/snapteld.go @@ -192,6 +192,7 @@ type managesTribe interface { func main() { // Add a check to see if gitversion is blank from the build process + if gitversion == "" { gitversion = "unknown" } @@ -797,6 +798,7 @@ func applyCmdLineFlags(cfg *Config, ctx *cli.Context) { cfg.Control.ListenAddr = setStringVal(cfg.Control.ListenAddr, ctx, "control-listen-addr") cfg.Control.ListenPort = setIntVal(cfg.Control.ListenPort, ctx, "control-listen-port") cfg.Control.Pprof = setBoolVal(cfg.Control.Pprof, ctx, "pprof") + cfg.Control.TempDirPath = setStringVal(cfg.Control.TempDirPath, ctx, "temp_dir_path") // next for the RESTful server related flags cfg.RestAPI.Enable = setBoolVal(cfg.RestAPI.Enable, ctx, "disable-api", invertBoolean) cfg.RestAPI.Port = setIntVal(cfg.RestAPI.Port, ctx, "api-port")