agent/plugins/configurecontainers/configurecontainers.go (79 lines of code) (raw):
// Copyright 2016 Amazon.com, Inc. or its affiliates. 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. A copy of the
// License is located at
//
// http://aws.amazon.com/apache2.0/
//
// or in the "license" file accompanying this file. This file 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 configurecontainers
import (
"fmt"
"github.com/aws/amazon-ssm-agent/agent/appconfig"
"github.com/aws/amazon-ssm-agent/agent/context"
"github.com/aws/amazon-ssm-agent/agent/contracts"
"github.com/aws/amazon-ssm-agent/agent/executers"
"github.com/aws/amazon-ssm-agent/agent/fileutil"
"github.com/aws/amazon-ssm-agent/agent/framework/processor/executer/iohandler"
"github.com/aws/amazon-ssm-agent/agent/jsonutil"
"github.com/aws/amazon-ssm-agent/agent/log"
"github.com/aws/amazon-ssm-agent/agent/task"
)
const (
//Action values
INSTALL = "Install"
UNINSTALL = "Uninstall"
)
// Plugin is the type for the plugin.
type Plugin struct {
context context.T
// ExecuteCommand is an object that can execute commands.
CommandExecuter executers.T
}
// ConfigureContainerPluginInput represents one set of commands executed by the configure container plugin.
type ConfigureContainerPluginInput struct {
contracts.PluginInput
ID string
Action string
}
// NewPlugin returns a new instance of the plugin.
func NewPlugin(context context.T) (*Plugin, error) {
return &Plugin{
context: context,
CommandExecuter: executers.ShellCommandExecuter{},
}, nil
}
// Name returns the name of the plugin
func Name() string {
return appconfig.PluginNameConfigureDocker
}
func (p *Plugin) Execute(config contracts.Configuration, cancelFlag task.CancelFlag, output iohandler.IOHandler) {
log := p.context.Log()
log.Infof("%v started with configuration %v", Name(), config)
if cancelFlag.ShutDown() {
output.MarkAsShutdown()
} else if cancelFlag.Canceled() {
output.MarkAsCancelled()
} else {
p.runCommandsRawInput(log, config.PluginID, config.Properties, config.OrchestrationDirectory, cancelFlag, output)
}
return
}
// runCommandsRawInput executes one set of commands and returns their output.
// The input is in the default json unmarshal format (e.g. map[string]interface{}).
func (p *Plugin) runCommandsRawInput(log log.T, pluginID string, rawPluginInput interface{}, orchestrationDirectory string, cancelFlag task.CancelFlag, output iohandler.IOHandler) {
var pluginInput ConfigureContainerPluginInput
err := jsonutil.Remarshal(rawPluginInput, &pluginInput)
log.Debugf("Plugin input %v", pluginInput)
if err != nil {
errorString := fmt.Errorf("Invalid format in plugin properties %v;\nerror %v", rawPluginInput, err)
output.MarkAsFailed(errorString)
return
}
p.runCommands(log, pluginID, pluginInput, orchestrationDirectory, cancelFlag, output)
}
// runCommands executes one set of commands and returns their output.
func (p *Plugin) runCommands(log log.T, pluginID string, pluginInput ConfigureContainerPluginInput, orchestrationDirectory string, cancelFlag task.CancelFlag, output iohandler.IOHandler) {
var err error
// TODO:MF: This subdirectory is only needed because we could be running multiple sets of properties for the same plugin - otherwise the orchestration directory would already be unique
orchestrationDir := fileutil.BuildSafePath(orchestrationDirectory, pluginInput.ID)
log.Debugf("OrchestrationDir %v ", orchestrationDir)
// create orchestration dir if needed
if err = fileutil.MakeDirs(orchestrationDir); err != nil {
log.Debug("failed to create orchestrationDir directory", orchestrationDir, err)
output.MarkAsFailed(err)
return
}
log.Info("********************************starting configure Docker plugin**************************************")
switch pluginInput.Action {
case INSTALL:
runInstallCommands(p.context, pluginInput, orchestrationDir, output)
case UNINSTALL:
runUninstallCommands(p.context, pluginInput, orchestrationDir, output)
default:
output.MarkAsFailed(fmt.Errorf("configure Action is set to unsupported value: %v", pluginInput.Action))
}
log.Info("********************************completing configure Docker plugin**************************************")
return
}