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
1 change: 1 addition & 0 deletions api/v1/agentconfig_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ func NewAgentConfigSpecAdapter(spec AgentConfigSpec) AgentConfigSpecAdapter {
}

// GetPluginsPVCName returns a name used for this agent config plugin persistent volume claim.
// Returns an empty string when no plugins are specified, in which case the PVC should not be mounted
func (c AgentConfigSpecAdapter) GetPluginsPVCName(namespace string) string {
return c.Plugins.GetPVCName(namespace)
}
Expand Down
7 changes: 4 additions & 3 deletions api/v1/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,15 @@ const (
// .docker/config.json file.
VolumeImgPullSecretName = "img-pull-secret"

// VolumeImagePullSecretPath is the mount path of the volume containing for docker
// VolumeImgPullSecretPath is the mount path of the volume containing for docker
// auth for image pull secrets.
VolumeImgPullSecretPath = "/home/nonroot"
// VolumePorterSharedName is the name of the volume shared between the porter

// VolumePorterPluginsName is the name of the volume shared between the porter
// agent and the invocation image.
VolumePorterPluginsName = "porter-plugins"

// VolumePorterConfigPath is the mount path of the volume containing Porter's
// VolumePorterPluginsPath is the mount path of the volume containing Porter's
// config file.
VolumePorterPluginsPath = "/app/.porter/plugins"
)
43 changes: 29 additions & 14 deletions controllers/agentaction_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
porterv1 "get.porter.sh/operator/api/v1"
"github.com/go-logr/logr"
"github.com/pkg/errors"
"gopkg.in/yaml.v3"
batchv1 "k8s.io/api/batch/v1"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
Expand Down Expand Up @@ -459,6 +460,16 @@ func (r *AgentActionReconciler) createAgentJob(ctx context.Context, log logr.Log
}

if err := r.Create(ctx, &porterJob); err != nil {
// If we can't create the job, try to log the job's yaml to help with troubleshooting
// It will be base64 encoded because logs are all output on a single line.
// You can pipe the value to base64 --decode to see the yaml, e.g. copy the value to a file, then `cat RESULT | base64 --decode`
badJobYaml, yamlErr := yaml.Marshal(porterJob)
if yamlErr != nil {
log.Error(yamlErr, "error marshaling job to yaml to trace in logs")
} else {
log.V(Log0Error).Error(err, "error creating Porter agent job", "base64EncodedJob", badJobYaml)
}

return batchv1.Job{}, errors.Wrap(err, "error creating Porter agent job")
}

Expand Down Expand Up @@ -722,21 +733,25 @@ func (r *AgentActionReconciler) getAgentVolumes(ctx context.Context, log logr.Lo
}
// Only add the plugin volume if the action is not created to configure porter itself
if !action.CreatedByAgentConfig() {
claimName := agentCfg.GetPluginsPVCName(action.Namespace)
log.V(Log4Debug).Info("mounting porter plugin volume", "claim name", claimName)
volumes = append(volumes, corev1.Volume{
Name: porterv1.VolumePorterPluginsName,
VolumeSource: corev1.VolumeSource{
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
ClaimName: claimName,
pluginsPVCName := agentCfg.GetPluginsPVCName(action.Namespace)

// Check if we should mount a PVC for plugins, it will be an empty string if no plugins are used
if pluginsPVCName != "" {
log.V(Log4Debug).Info("mounting porter plugin volume", "claim name", pluginsPVCName)
volumes = append(volumes, corev1.Volume{
Name: porterv1.VolumePorterPluginsName,
VolumeSource: corev1.VolumeSource{
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
ClaimName: pluginsPVCName,
},
},
},
})
volumeMounts = append(volumeMounts, corev1.VolumeMount{
Name: porterv1.VolumePorterPluginsName,
MountPath: porterv1.VolumePorterPluginsPath,
SubPath: "plugins",
})
})
volumeMounts = append(volumeMounts, corev1.VolumeMount{
Name: porterv1.VolumePorterPluginsName,
MountPath: porterv1.VolumePorterPluginsPath,
SubPath: "plugins",
})
}
}

volumes = append(volumes, action.Spec.Volumes...)
Expand Down
26 changes: 26 additions & 0 deletions controllers/agentaction_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -900,6 +900,32 @@ func TestAgentActionReconciler_getAgentVolumes_agentconfigaction(t *testing.T) {
assertVolumeMount(t, volumeMountsForAgentCfg, porterv1.VolumePorterWorkDirName, porterv1.VolumePorterWorkDirPath)
}

// Ensure that we can create a valid AgentAction when no plugins were specified for the AgentConfig
// In which case we should not mount porter-plugins into the agent
func TestAgentActionReconciler_NoPluginsSpecified(t *testing.T) {
controller := setupAgentActionController()
action := testAgentAction()
agentCfg := testAgentCfgSpec()

// Do not set any plugins on the agent config
agentCfg.Plugins = porterv1.PluginsConfigList{}

pvc := &corev1.PersistentVolumeClaim{ObjectMeta: metav1.ObjectMeta{Name: "mypvc"}}
configSecret := &corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: "my-agent-config"}}
workDirSecret := &corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: "myagentconfig"}}
volumes, volumeMounts := controller.getAgentVolumes(context.Background(), logr.Discard(), action, agentCfg, pvc, configSecret, workDirSecret, nil)

assert.Len(t, volumes, 3, "incorrect pod volumes")
for _, v := range volumes {
assert.NotEqual(t, porterv1.VolumePorterPluginsName, v.Name, "the porter-plugins volume should not be present when no plugins are specified")
}

assert.Len(t, volumeMounts, 3)
for _, v := range volumeMounts {
assert.NotEqual(t, porterv1.VolumePorterPluginsName, v.Name, "the porter-plugins volume mount should not be present when no plugins are specified")
}
}

func TestAgentActionReconciler_resolveAgentConfig(t *testing.T) {
systemCfg := porterv1.AgentConfig{
ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: operatorNamespace},
Expand Down