mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-01-03 11:45:20 +00:00
Add --plugins flag to velero install (#1930)
* Add plugins flag to install Signed-off-by: Nolan Brubaker <brubakern@vmware.com>
This commit is contained in:
committed by
KubeKween
parent
db59d8d4bc
commit
f009fe9bd1
1
changelogs/unreleased/1930-nrb
Normal file
1
changelogs/unreleased/1930-nrb
Normal file
@@ -0,0 +1 @@
|
||||
Add a new required --plugins flag for velero install command. --plugins takes a list of container images to add as initcontainers.
|
||||
@@ -17,6 +17,8 @@ limitations under the License.
|
||||
package builder
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
corev1api "k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
@@ -35,6 +37,32 @@ func ForContainer(name, image string) *ContainerBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
// ForPluginContainer is a helper builder specifically for plugin init containers
|
||||
func ForPluginContainer(image string, pullPolicy corev1api.PullPolicy) *ContainerBuilder {
|
||||
volumeMount := ForVolumeMount("plugins", "/target").Result()
|
||||
return ForContainer(getName(image), image).PullPolicy(pullPolicy).VolumeMounts(volumeMount)
|
||||
}
|
||||
|
||||
// getName returns the 'name' component of a docker
|
||||
// image (i.e. everything after the last '/' and before
|
||||
// any subsequent ':')
|
||||
func getName(image string) string {
|
||||
slashIndex := strings.LastIndex(image, "/")
|
||||
colonIndex := strings.LastIndex(image, ":")
|
||||
|
||||
start := 0
|
||||
if slashIndex > 0 {
|
||||
start = slashIndex + 1
|
||||
}
|
||||
|
||||
end := len(image)
|
||||
if colonIndex > slashIndex {
|
||||
end = colonIndex
|
||||
}
|
||||
|
||||
return image[start:end]
|
||||
}
|
||||
|
||||
// Result returns the built Container.
|
||||
func (b *ContainerBuilder) Result() *corev1api.Container {
|
||||
return b.object
|
||||
@@ -66,3 +94,8 @@ func (b *ContainerBuilder) Env(vars ...*corev1api.EnvVar) *ContainerBuilder {
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *ContainerBuilder) PullPolicy(pullPolicy corev1api.PullPolicy) *ContainerBuilder {
|
||||
b.object.ImagePullPolicy = pullPolicy
|
||||
return b
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2018 the Velero contributors.
|
||||
Copyright 2018, 2019 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -13,7 +13,7 @@ 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 plugin
|
||||
package builder
|
||||
|
||||
import (
|
||||
"testing"
|
||||
@@ -64,6 +64,7 @@ type InstallOptions struct {
|
||||
Wait bool
|
||||
UseVolumeSnapshots bool
|
||||
DefaultResticMaintenanceFrequency time.Duration
|
||||
Plugins flag.StringArray
|
||||
}
|
||||
|
||||
// BindFlags adds command line values to the options struct.
|
||||
@@ -92,6 +93,7 @@ func (o *InstallOptions) BindFlags(flags *pflag.FlagSet) {
|
||||
flags.BoolVar(&o.UseRestic, "use-restic", o.UseRestic, "create restic deployment. Optional.")
|
||||
flags.BoolVar(&o.Wait, "wait", o.Wait, "wait for Velero deployment to be ready. Optional.")
|
||||
flags.DurationVar(&o.DefaultResticMaintenanceFrequency, "default-restic-prune-frequency", o.DefaultResticMaintenanceFrequency, "how often 'restic prune' is run for restic repositories by default. Optional.")
|
||||
flags.Var(&o.Plugins, "plugins", "Plugin container images to install into the Velero Deployment. Optional.")
|
||||
}
|
||||
|
||||
// NewInstallOptions instantiates a new, default InstallOptions struct.
|
||||
@@ -155,6 +157,7 @@ func (o *InstallOptions) AsVeleroOptions() (*install.VeleroOptions, error) {
|
||||
BSLConfig: o.BackupStorageConfig.Data(),
|
||||
VSLConfig: o.VolumeSnapshotConfig.Data(),
|
||||
DefaultResticMaintenanceFrequency: o.DefaultResticMaintenanceFrequency,
|
||||
Plugins: o.Plugins,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
|
||||
"github.com/vmware-tanzu/velero/pkg/builder"
|
||||
"github.com/vmware-tanzu/velero/pkg/client"
|
||||
"github.com/vmware-tanzu/velero/pkg/cmd"
|
||||
"github.com/vmware-tanzu/velero/pkg/cmd/util/flag"
|
||||
@@ -104,17 +105,7 @@ func NewAddCommand(f client.Factory) *cobra.Command {
|
||||
}
|
||||
|
||||
// add the plugin as an init container
|
||||
plugin := v1.Container{
|
||||
Name: getName(args[0]),
|
||||
Image: args[0],
|
||||
ImagePullPolicy: v1.PullPolicy(imagePullPolicyFlag.String()),
|
||||
VolumeMounts: []v1.VolumeMount{
|
||||
{
|
||||
Name: pluginsVolumeName,
|
||||
MountPath: "/target",
|
||||
},
|
||||
},
|
||||
}
|
||||
plugin := *builder.ForPluginContainer(args[0], v1.PullPolicy(imagePullPolicyFlag.String())).Result()
|
||||
|
||||
veleroDeploy.Spec.Template.Spec.InitContainers = append(veleroDeploy.Spec.Template.Spec.InitContainers, plugin)
|
||||
|
||||
@@ -134,23 +125,3 @@ func NewAddCommand(f client.Factory) *cobra.Command {
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
// getName returns the 'name' component of a docker
|
||||
// image (i.e. everything after the last '/' and before
|
||||
// any subsequent ':')
|
||||
func getName(image string) string {
|
||||
slashIndex := strings.LastIndex(image, "/")
|
||||
colonIndex := strings.LastIndex(image, ":")
|
||||
|
||||
start := 0
|
||||
if slashIndex > 0 {
|
||||
start = slashIndex + 1
|
||||
}
|
||||
|
||||
end := len(image)
|
||||
if colonIndex > slashIndex {
|
||||
end = colonIndex
|
||||
}
|
||||
|
||||
return image[start:end]
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@ import (
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/vmware-tanzu/velero/pkg/builder"
|
||||
)
|
||||
|
||||
type podTemplateOption func(*podTemplateConfig)
|
||||
@@ -36,6 +38,7 @@ type podTemplateConfig struct {
|
||||
resources corev1.ResourceRequirements
|
||||
withSecret bool
|
||||
defaultResticMaintenanceFrequency time.Duration
|
||||
plugins []string
|
||||
}
|
||||
|
||||
func WithImage(image string) podTemplateOption {
|
||||
@@ -91,6 +94,12 @@ func WithDefaultResticMaintenanceFrequency(val time.Duration) podTemplateOption
|
||||
}
|
||||
}
|
||||
|
||||
func WithPlugins(plugins []string) podTemplateOption {
|
||||
return func(c *podTemplateConfig) {
|
||||
c.plugins = plugins
|
||||
}
|
||||
}
|
||||
|
||||
func Deployment(namespace string, opts ...podTemplateOption) *appsv1.Deployment {
|
||||
// TODO: Add support for server args
|
||||
c := &podTemplateConfig{
|
||||
@@ -236,5 +245,13 @@ func Deployment(namespace string, opts ...podTemplateOption) *appsv1.Deployment
|
||||
deployment.Spec.Template.Spec.Containers[0].Args = append(deployment.Spec.Template.Spec.Containers[0].Args, fmt.Sprintf("--default-restic-prune-frequency=%v", c.defaultResticMaintenanceFrequency))
|
||||
}
|
||||
|
||||
if len(c.plugins) > 0 {
|
||||
for _, image := range c.plugins {
|
||||
container := *builder.ForPluginContainer(image, pullPolicy).Result()
|
||||
deployment.Spec.Template.Spec.InitContainers = append(deployment.Spec.Template.Spec.InitContainers, container)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return deployment
|
||||
}
|
||||
|
||||
@@ -215,6 +215,7 @@ type VeleroOptions struct {
|
||||
BSLConfig map[string]string
|
||||
VSLConfig map[string]string
|
||||
DefaultResticMaintenanceFrequency time.Duration
|
||||
Plugins []string
|
||||
}
|
||||
|
||||
// AllResources returns a list of all resources necessary to install Velero, in the appropriate order, into a Kubernetes cluster.
|
||||
@@ -266,13 +267,16 @@ func AllResources(o *VeleroOptions) (*unstructured.UnstructuredList, error) {
|
||||
deployOpts = append(deployOpts, WithRestoreOnly())
|
||||
}
|
||||
|
||||
if len(o.Plugins) > 0 {
|
||||
deployOpts = append(deployOpts, WithPlugins(o.Plugins))
|
||||
}
|
||||
|
||||
deploy := Deployment(o.Namespace, deployOpts...)
|
||||
|
||||
appendUnstructured(resources, deploy)
|
||||
|
||||
if o.UseRestic {
|
||||
ds := DaemonSet(o.Namespace,
|
||||
|
||||
WithAnnotations(o.PodAnnotations),
|
||||
WithImage(o.Image),
|
||||
WithResources(o.ResticPodResources),
|
||||
|
||||
Reference in New Issue
Block a user