mirror of https://github.com/knative/client.git
Added subpath functionality to --mount flag (#1655)
* Added subpath functionality to --mount flag * Added mount subpath test * Added e2e tests for volume subpath mount * Updated changelog
This commit is contained in:
parent
7e8a6727fe
commit
b858dab2b4
|
|
@ -32,6 +32,10 @@
|
||||||
| Added --scale-metric flag to configure metric name
|
| Added --scale-metric flag to configure metric name
|
||||||
| https://github.com/knative/client/pull/1653[#1653]
|
| https://github.com/knative/client/pull/1653[#1653]
|
||||||
|
|
||||||
|
| 🎁
|
||||||
|
| Added subpath functionality to --mount flag
|
||||||
|
| https://github.com/knative/client/pull/1655[#1655]
|
||||||
|
|
||||||
|===
|
|===
|
||||||
## v1.3.0 (2022-03-08)
|
## v1.3.0 (2022-03-08)
|
||||||
[cols="1,10,3", options="header", width="100%"]
|
[cols="1,10,3", options="header", width="100%"]
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ kn container add NAME
|
||||||
-h, --help help for add
|
-h, --help help for add
|
||||||
--image string Image to run.
|
--image string Image to run.
|
||||||
--limit strings The resource requirement limits for this Service. For example, 'cpu=100m,memory=256Mi'. You can use this flag multiple times. To unset a resource limit, append "-" to the resource name, e.g. '--limit memory-'.
|
--limit strings The resource requirement limits for this Service. For example, 'cpu=100m,memory=256Mi'. You can use this flag multiple times. To unset a resource limit, append "-" to the resource name, e.g. '--limit memory-'.
|
||||||
--mount stringArray Mount a ConfigMap (prefix cm: or config-map:), a Secret (prefix secret: or sc:), or an existing Volume (without any prefix) on the specified directory. Example: --mount /mydir=cm:myconfigmap, --mount /mydir=secret:mysecret, or --mount /mydir=myvolume. When a configmap or a secret is specified, a corresponding volume is automatically generated. You can use this flag multiple times. For unmounting a directory, append "-", e.g. --mount /mydir-, which also removes any auto-generated volume.
|
--mount stringArray Mount a ConfigMap (prefix cm: or config-map:), a Secret (prefix secret: or sc:), or an existing Volume (without any prefix) on the specified directory. Example: --mount /mydir=cm:myconfigmap, --mount /mydir=secret:mysecret, or --mount /mydir=myvolume. When a configmap or a secret is specified, a corresponding volume is automatically generated. You can specify a volume subpath by following the volume name with slash separated path. Example: --mount /mydir=cm:myconfigmap/subpath/to/be/mounted. You can use this flag multiple times. For unmounting a directory, append "-", e.g. --mount /mydir-, which also removes any auto-generated volume.
|
||||||
-p, --port string The port where application listens on, in the format 'NAME:PORT', where 'NAME' is optional. Examples: '--port h2c:8080' , '--port 8080'.
|
-p, --port string The port where application listens on, in the format 'NAME:PORT', where 'NAME' is optional. Examples: '--port h2c:8080' , '--port 8080'.
|
||||||
--pull-policy string Image pull policy. Valid values (case insensitive): Always | Never | IfNotPresent
|
--pull-policy string Image pull policy. Valid values (case insensitive): Always | Never | IfNotPresent
|
||||||
--pull-secret string Image pull secret to set. An empty argument ("") clears the pull secret. The referenced secret must exist in the service's namespace.
|
--pull-secret string Image pull secret to set. An empty argument ("") clears the pull secret. The referenced secret must exist in the service's namespace.
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ kn service apply s0 --filename my-svc.yml
|
||||||
--label-service stringArray Service label to set. name=value; you may provide this flag any number of times to set multiple labels. To unset, specify the label name followed by a "-" (e.g., name-). This flag takes precedence over the "label" flag.
|
--label-service stringArray Service label to set. name=value; you may provide this flag any number of times to set multiple labels. To unset, specify the label name followed by a "-" (e.g., name-). This flag takes precedence over the "label" flag.
|
||||||
--limit strings The resource requirement limits for this Service. For example, 'cpu=100m,memory=256Mi'. You can use this flag multiple times. To unset a resource limit, append "-" to the resource name, e.g. '--limit memory-'.
|
--limit strings The resource requirement limits for this Service. For example, 'cpu=100m,memory=256Mi'. You can use this flag multiple times. To unset a resource limit, append "-" to the resource name, e.g. '--limit memory-'.
|
||||||
--lock-to-digest Keep the running image for the service constant when not explicitly specifying the image. (--no-lock-to-digest pulls the image tag afresh with each new revision) (default true)
|
--lock-to-digest Keep the running image for the service constant when not explicitly specifying the image. (--no-lock-to-digest pulls the image tag afresh with each new revision) (default true)
|
||||||
--mount stringArray Mount a ConfigMap (prefix cm: or config-map:), a Secret (prefix secret: or sc:), or an existing Volume (without any prefix) on the specified directory. Example: --mount /mydir=cm:myconfigmap, --mount /mydir=secret:mysecret, or --mount /mydir=myvolume. When a configmap or a secret is specified, a corresponding volume is automatically generated. You can use this flag multiple times. For unmounting a directory, append "-", e.g. --mount /mydir-, which also removes any auto-generated volume.
|
--mount stringArray Mount a ConfigMap (prefix cm: or config-map:), a Secret (prefix secret: or sc:), or an existing Volume (without any prefix) on the specified directory. Example: --mount /mydir=cm:myconfigmap, --mount /mydir=secret:mysecret, or --mount /mydir=myvolume. When a configmap or a secret is specified, a corresponding volume is automatically generated. You can specify a volume subpath by following the volume name with slash separated path. Example: --mount /mydir=cm:myconfigmap/subpath/to/be/mounted. You can use this flag multiple times. For unmounting a directory, append "-", e.g. --mount /mydir-, which also removes any auto-generated volume.
|
||||||
-n, --namespace string Specify the namespace to operate in.
|
-n, --namespace string Specify the namespace to operate in.
|
||||||
--no-cluster-local Do not specify that the service be private. (--no-cluster-local will make the service publicly available) (default true)
|
--no-cluster-local Do not specify that the service be private. (--no-cluster-local will make the service publicly available) (default true)
|
||||||
--no-lock-to-digest Do not keep the running image for the service constant when not explicitly specifying the image. (--no-lock-to-digest pulls the image tag afresh with each new revision)
|
--no-lock-to-digest Do not keep the running image for the service constant when not explicitly specifying the image. (--no-lock-to-digest pulls the image tag afresh with each new revision)
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ kn service create NAME --image IMAGE
|
||||||
--label-service stringArray Service label to set. name=value; you may provide this flag any number of times to set multiple labels. To unset, specify the label name followed by a "-" (e.g., name-). This flag takes precedence over the "label" flag.
|
--label-service stringArray Service label to set. name=value; you may provide this flag any number of times to set multiple labels. To unset, specify the label name followed by a "-" (e.g., name-). This flag takes precedence over the "label" flag.
|
||||||
--limit strings The resource requirement limits for this Service. For example, 'cpu=100m,memory=256Mi'. You can use this flag multiple times. To unset a resource limit, append "-" to the resource name, e.g. '--limit memory-'.
|
--limit strings The resource requirement limits for this Service. For example, 'cpu=100m,memory=256Mi'. You can use this flag multiple times. To unset a resource limit, append "-" to the resource name, e.g. '--limit memory-'.
|
||||||
--lock-to-digest Keep the running image for the service constant when not explicitly specifying the image. (--no-lock-to-digest pulls the image tag afresh with each new revision) (default true)
|
--lock-to-digest Keep the running image for the service constant when not explicitly specifying the image. (--no-lock-to-digest pulls the image tag afresh with each new revision) (default true)
|
||||||
--mount stringArray Mount a ConfigMap (prefix cm: or config-map:), a Secret (prefix secret: or sc:), or an existing Volume (without any prefix) on the specified directory. Example: --mount /mydir=cm:myconfigmap, --mount /mydir=secret:mysecret, or --mount /mydir=myvolume. When a configmap or a secret is specified, a corresponding volume is automatically generated. You can use this flag multiple times. For unmounting a directory, append "-", e.g. --mount /mydir-, which also removes any auto-generated volume.
|
--mount stringArray Mount a ConfigMap (prefix cm: or config-map:), a Secret (prefix secret: or sc:), or an existing Volume (without any prefix) on the specified directory. Example: --mount /mydir=cm:myconfigmap, --mount /mydir=secret:mysecret, or --mount /mydir=myvolume. When a configmap or a secret is specified, a corresponding volume is automatically generated. You can specify a volume subpath by following the volume name with slash separated path. Example: --mount /mydir=cm:myconfigmap/subpath/to/be/mounted. You can use this flag multiple times. For unmounting a directory, append "-", e.g. --mount /mydir-, which also removes any auto-generated volume.
|
||||||
-n, --namespace string Specify the namespace to operate in.
|
-n, --namespace string Specify the namespace to operate in.
|
||||||
--no-cluster-local Do not specify that the service be private. (--no-cluster-local will make the service publicly available) (default true)
|
--no-cluster-local Do not specify that the service be private. (--no-cluster-local will make the service publicly available) (default true)
|
||||||
--no-lock-to-digest Do not keep the running image for the service constant when not explicitly specifying the image. (--no-lock-to-digest pulls the image tag afresh with each new revision)
|
--no-lock-to-digest Do not keep the running image for the service constant when not explicitly specifying the image. (--no-lock-to-digest pulls the image tag afresh with each new revision)
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ kn service update NAME
|
||||||
--label-service stringArray Service label to set. name=value; you may provide this flag any number of times to set multiple labels. To unset, specify the label name followed by a "-" (e.g., name-). This flag takes precedence over the "label" flag.
|
--label-service stringArray Service label to set. name=value; you may provide this flag any number of times to set multiple labels. To unset, specify the label name followed by a "-" (e.g., name-). This flag takes precedence over the "label" flag.
|
||||||
--limit strings The resource requirement limits for this Service. For example, 'cpu=100m,memory=256Mi'. You can use this flag multiple times. To unset a resource limit, append "-" to the resource name, e.g. '--limit memory-'.
|
--limit strings The resource requirement limits for this Service. For example, 'cpu=100m,memory=256Mi'. You can use this flag multiple times. To unset a resource limit, append "-" to the resource name, e.g. '--limit memory-'.
|
||||||
--lock-to-digest Keep the running image for the service constant when not explicitly specifying the image. (--no-lock-to-digest pulls the image tag afresh with each new revision) (default true)
|
--lock-to-digest Keep the running image for the service constant when not explicitly specifying the image. (--no-lock-to-digest pulls the image tag afresh with each new revision) (default true)
|
||||||
--mount stringArray Mount a ConfigMap (prefix cm: or config-map:), a Secret (prefix secret: or sc:), or an existing Volume (without any prefix) on the specified directory. Example: --mount /mydir=cm:myconfigmap, --mount /mydir=secret:mysecret, or --mount /mydir=myvolume. When a configmap or a secret is specified, a corresponding volume is automatically generated. You can use this flag multiple times. For unmounting a directory, append "-", e.g. --mount /mydir-, which also removes any auto-generated volume.
|
--mount stringArray Mount a ConfigMap (prefix cm: or config-map:), a Secret (prefix secret: or sc:), or an existing Volume (without any prefix) on the specified directory. Example: --mount /mydir=cm:myconfigmap, --mount /mydir=secret:mysecret, or --mount /mydir=myvolume. When a configmap or a secret is specified, a corresponding volume is automatically generated. You can specify a volume subpath by following the volume name with slash separated path. Example: --mount /mydir=cm:myconfigmap/subpath/to/be/mounted. You can use this flag multiple times. For unmounting a directory, append "-", e.g. --mount /mydir-, which also removes any auto-generated volume.
|
||||||
-n, --namespace string Specify the namespace to operate in.
|
-n, --namespace string Specify the namespace to operate in.
|
||||||
--no-cluster-local Do not specify that the service be private. (--no-cluster-local will make the service publicly available) (default true)
|
--no-cluster-local Do not specify that the service be private. (--no-cluster-local will make the service publicly available) (default true)
|
||||||
--no-lock-to-digest Do not keep the running image for the service constant when not explicitly specifying the image. (--no-lock-to-digest pulls the image tag afresh with each new revision)
|
--no-lock-to-digest Do not keep the running image for the service constant when not explicitly specifying the image. (--no-lock-to-digest pulls the image tag afresh with each new revision)
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ kn source container create NAME --image IMAGE --sink SINK
|
||||||
-h, --help help for create
|
-h, --help help for create
|
||||||
--image string Image to run.
|
--image string Image to run.
|
||||||
--limit strings The resource requirement limits for this Service. For example, 'cpu=100m,memory=256Mi'. You can use this flag multiple times. To unset a resource limit, append "-" to the resource name, e.g. '--limit memory-'.
|
--limit strings The resource requirement limits for this Service. For example, 'cpu=100m,memory=256Mi'. You can use this flag multiple times. To unset a resource limit, append "-" to the resource name, e.g. '--limit memory-'.
|
||||||
--mount stringArray Mount a ConfigMap (prefix cm: or config-map:), a Secret (prefix secret: or sc:), or an existing Volume (without any prefix) on the specified directory. Example: --mount /mydir=cm:myconfigmap, --mount /mydir=secret:mysecret, or --mount /mydir=myvolume. When a configmap or a secret is specified, a corresponding volume is automatically generated. You can use this flag multiple times. For unmounting a directory, append "-", e.g. --mount /mydir-, which also removes any auto-generated volume.
|
--mount stringArray Mount a ConfigMap (prefix cm: or config-map:), a Secret (prefix secret: or sc:), or an existing Volume (without any prefix) on the specified directory. Example: --mount /mydir=cm:myconfigmap, --mount /mydir=secret:mysecret, or --mount /mydir=myvolume. When a configmap or a secret is specified, a corresponding volume is automatically generated. You can specify a volume subpath by following the volume name with slash separated path. Example: --mount /mydir=cm:myconfigmap/subpath/to/be/mounted. You can use this flag multiple times. For unmounting a directory, append "-", e.g. --mount /mydir-, which also removes any auto-generated volume.
|
||||||
-n, --namespace string Specify the namespace to operate in.
|
-n, --namespace string Specify the namespace to operate in.
|
||||||
-p, --port string The port where application listens on, in the format 'NAME:PORT', where 'NAME' is optional. Examples: '--port h2c:8080' , '--port 8080'.
|
-p, --port string The port where application listens on, in the format 'NAME:PORT', where 'NAME' is optional. Examples: '--port h2c:8080' , '--port 8080'.
|
||||||
--pull-policy string Image pull policy. Valid values (case insensitive): Always | Never | IfNotPresent
|
--pull-policy string Image pull policy. Valid values (case insensitive): Always | Never | IfNotPresent
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ kn source container update NAME --image IMAGE
|
||||||
-h, --help help for update
|
-h, --help help for update
|
||||||
--image string Image to run.
|
--image string Image to run.
|
||||||
--limit strings The resource requirement limits for this Service. For example, 'cpu=100m,memory=256Mi'. You can use this flag multiple times. To unset a resource limit, append "-" to the resource name, e.g. '--limit memory-'.
|
--limit strings The resource requirement limits for this Service. For example, 'cpu=100m,memory=256Mi'. You can use this flag multiple times. To unset a resource limit, append "-" to the resource name, e.g. '--limit memory-'.
|
||||||
--mount stringArray Mount a ConfigMap (prefix cm: or config-map:), a Secret (prefix secret: or sc:), or an existing Volume (without any prefix) on the specified directory. Example: --mount /mydir=cm:myconfigmap, --mount /mydir=secret:mysecret, or --mount /mydir=myvolume. When a configmap or a secret is specified, a corresponding volume is automatically generated. You can use this flag multiple times. For unmounting a directory, append "-", e.g. --mount /mydir-, which also removes any auto-generated volume.
|
--mount stringArray Mount a ConfigMap (prefix cm: or config-map:), a Secret (prefix secret: or sc:), or an existing Volume (without any prefix) on the specified directory. Example: --mount /mydir=cm:myconfigmap, --mount /mydir=secret:mysecret, or --mount /mydir=myvolume. When a configmap or a secret is specified, a corresponding volume is automatically generated. You can specify a volume subpath by following the volume name with slash separated path. Example: --mount /mydir=cm:myconfigmap/subpath/to/be/mounted. You can use this flag multiple times. For unmounting a directory, append "-", e.g. --mount /mydir-, which also removes any auto-generated volume.
|
||||||
-n, --namespace string Specify the namespace to operate in.
|
-n, --namespace string Specify the namespace to operate in.
|
||||||
-p, --port string The port where application listens on, in the format 'NAME:PORT', where 'NAME' is optional. Examples: '--port h2c:8080' , '--port 8080'.
|
-p, --port string The port where application listens on, in the format 'NAME:PORT', where 'NAME' is optional. Examples: '--port h2c:8080' , '--port 8080'.
|
||||||
--pull-policy string Image pull policy. Valid values (case insensitive): Always | Never | IfNotPresent
|
--pull-policy string Image pull policy. Valid values (case insensitive): Always | Never | IfNotPresent
|
||||||
|
|
|
||||||
|
|
@ -140,6 +140,8 @@ func (p *PodSpecFlags) AddFlags(flagset *pflag.FlagSet) []string {
|
||||||
"Mount a ConfigMap (prefix cm: or config-map:), a Secret (prefix secret: or sc:), or an existing Volume (without any prefix) on the specified directory. "+
|
"Mount a ConfigMap (prefix cm: or config-map:), a Secret (prefix secret: or sc:), or an existing Volume (without any prefix) on the specified directory. "+
|
||||||
"Example: --mount /mydir=cm:myconfigmap, --mount /mydir=secret:mysecret, or --mount /mydir=myvolume. "+
|
"Example: --mount /mydir=cm:myconfigmap, --mount /mydir=secret:mysecret, or --mount /mydir=myvolume. "+
|
||||||
"When a configmap or a secret is specified, a corresponding volume is automatically generated. "+
|
"When a configmap or a secret is specified, a corresponding volume is automatically generated. "+
|
||||||
|
"You can specify a volume subpath by following the volume name with slash separated path. "+
|
||||||
|
"Example: --mount /mydir=cm:myconfigmap/subpath/to/be/mounted. "+
|
||||||
"You can use this flag multiple times. "+
|
"You can use this flag multiple times. "+
|
||||||
"For unmounting a directory, append \"-\", e.g. --mount /mydir-, which also removes any auto-generated volume.")
|
"For unmounting a directory, append \"-\", e.g. --mount /mydir-, which also removes any auto-generated volume.")
|
||||||
flagNames = append(flagNames, "mount")
|
flagNames = append(flagNames, "mount")
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,11 @@ const (
|
||||||
PortFormatErr = "the port specification '%s' is not valid. Please provide in the format 'NAME:PORT', where 'NAME' is optional. Examples: '--port h2c:8080' , '--port 8080'."
|
PortFormatErr = "the port specification '%s' is not valid. Please provide in the format 'NAME:PORT', where 'NAME' is optional. Examples: '--port h2c:8080' , '--port 8080'."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type MountInfo struct {
|
||||||
|
VolumeName string
|
||||||
|
SubPath string
|
||||||
|
}
|
||||||
|
|
||||||
func (vt VolumeSourceType) String() string {
|
func (vt VolumeSourceType) String() string {
|
||||||
names := [...]string{"config-map", "secret"}
|
names := [...]string{"config-map", "secret"}
|
||||||
if vt < ConfigMapVolumeSourceType || vt > SecretVolumeSourceType {
|
if vt < ConfigMapVolumeSourceType || vt > SecretVolumeSourceType {
|
||||||
|
|
@ -473,26 +478,32 @@ func updateVolumeMountsFromMap(volumeMounts []corev1.VolumeMount, toUpdate *util
|
||||||
|
|
||||||
for i := range volumeMounts {
|
for i := range volumeMounts {
|
||||||
volumeMount := &volumeMounts[i]
|
volumeMount := &volumeMounts[i]
|
||||||
name, present := toUpdate.GetString(volumeMount.MountPath)
|
mountInfo, present := toUpdate.Get(volumeMount.MountPath)
|
||||||
|
|
||||||
if present {
|
if present {
|
||||||
|
volumeMountInfo := mountInfo.(*MountInfo)
|
||||||
|
name := volumeMountInfo.VolumeName
|
||||||
if !existsVolumeNameInVolumes(name, volumes) {
|
if !existsVolumeNameInVolumes(name, volumes) {
|
||||||
return nil, fmt.Errorf("There is no volume matched with %q", name)
|
return nil, fmt.Errorf("There is no volume matched with %q", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
volumeMount.ReadOnly = true
|
volumeMount.ReadOnly = true
|
||||||
volumeMount.Name = name
|
volumeMount.Name = name
|
||||||
|
volumeMount.SubPath = volumeMountInfo.SubPath
|
||||||
set[volumeMount.MountPath] = true
|
set[volumeMount.MountPath] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
it := toUpdate.Iterator()
|
it := toUpdate.Iterator()
|
||||||
for mountPath, name, ok := it.NextString(); ok; mountPath, name, ok = it.NextString() {
|
for mountPath, mountInfo, ok := it.Next(); ok; mountPath, mountInfo, ok = it.Next() {
|
||||||
|
volumeMountInfo := mountInfo.(*MountInfo)
|
||||||
|
name := volumeMountInfo.VolumeName
|
||||||
if !set[mountPath] {
|
if !set[mountPath] {
|
||||||
volumeMounts = append(volumeMounts, corev1.VolumeMount{
|
volumeMounts = append(volumeMounts, corev1.VolumeMount{
|
||||||
Name: name,
|
Name: name,
|
||||||
ReadOnly: true,
|
ReadOnly: true,
|
||||||
MountPath: mountPath,
|
MountPath: mountPath,
|
||||||
|
SubPath: volumeMountInfo.SubPath,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -658,6 +669,19 @@ func existsVolumeNameInVolumeMounts(volumeName string, volumeMounts []corev1.Vol
|
||||||
|
|
||||||
// =======================================================================================
|
// =======================================================================================
|
||||||
|
|
||||||
|
func getMountInfo(volume string) *MountInfo {
|
||||||
|
slices := strings.SplitN(volume, "/", 2)
|
||||||
|
if len(slices) == 1 || slices[1] == "" {
|
||||||
|
return &MountInfo{
|
||||||
|
VolumeName: slices[0],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &MountInfo{
|
||||||
|
VolumeName: slices[0],
|
||||||
|
SubPath: slices[1],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func reviseVolumeInfoAndMountsToUpdate(mountsToUpdate *util.OrderedMap, volumesToUpdate *util.OrderedMap) (*util.OrderedMap, *util.OrderedMap, error) {
|
func reviseVolumeInfoAndMountsToUpdate(mountsToUpdate *util.OrderedMap, volumesToUpdate *util.OrderedMap) (*util.OrderedMap, *util.OrderedMap, error) {
|
||||||
volumeSourceInfoByName := util.NewOrderedMap() //make(map[string]*volumeSourceInfo)
|
volumeSourceInfoByName := util.NewOrderedMap() //make(map[string]*volumeSourceInfo)
|
||||||
mountsToUpdateRevised := util.NewOrderedMap() //make(map[string]string)
|
mountsToUpdateRevised := util.NewOrderedMap() //make(map[string]string)
|
||||||
|
|
@ -668,23 +692,28 @@ func reviseVolumeInfoAndMountsToUpdate(mountsToUpdate *util.OrderedMap, volumesT
|
||||||
// slices[1] -> secret, config-map, or volume name
|
// slices[1] -> secret, config-map, or volume name
|
||||||
slices := strings.SplitN(value, ":", 2)
|
slices := strings.SplitN(value, ":", 2)
|
||||||
if len(slices) == 1 {
|
if len(slices) == 1 {
|
||||||
mountsToUpdateRevised.Set(path, slices[0])
|
mountInfo := getMountInfo(slices[0])
|
||||||
|
mountsToUpdateRevised.Set(path, mountInfo)
|
||||||
} else {
|
} else {
|
||||||
switch volumeType := slices[0]; volumeType {
|
switch volumeType := slices[0]; volumeType {
|
||||||
case "config-map", "cm":
|
case "config-map", "cm":
|
||||||
generatedName := util.GenerateVolumeName(path)
|
generatedName := util.GenerateVolumeName(path)
|
||||||
|
mountInfo := getMountInfo(slices[1])
|
||||||
volumeSourceInfoByName.Set(generatedName, &volumeSourceInfo{
|
volumeSourceInfoByName.Set(generatedName, &volumeSourceInfo{
|
||||||
volumeSourceType: ConfigMapVolumeSourceType,
|
volumeSourceType: ConfigMapVolumeSourceType,
|
||||||
volumeSourceName: slices[1],
|
volumeSourceName: mountInfo.VolumeName,
|
||||||
})
|
})
|
||||||
mountsToUpdateRevised.Set(path, generatedName)
|
mountInfo.VolumeName = generatedName
|
||||||
|
mountsToUpdateRevised.Set(path, mountInfo)
|
||||||
case "secret", "sc":
|
case "secret", "sc":
|
||||||
generatedName := util.GenerateVolumeName(path)
|
generatedName := util.GenerateVolumeName(path)
|
||||||
|
mountInfo := getMountInfo(slices[1])
|
||||||
volumeSourceInfoByName.Set(generatedName, &volumeSourceInfo{
|
volumeSourceInfoByName.Set(generatedName, &volumeSourceInfo{
|
||||||
volumeSourceType: SecretVolumeSourceType,
|
volumeSourceType: SecretVolumeSourceType,
|
||||||
volumeSourceName: slices[1],
|
volumeSourceName: mountInfo.VolumeName,
|
||||||
})
|
})
|
||||||
mountsToUpdateRevised.Set(path, generatedName)
|
mountInfo.VolumeName = generatedName
|
||||||
|
mountsToUpdateRevised.Set(path, mountInfo)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return nil, nil, fmt.Errorf("unsupported volume type \"%q\"; supported volume types are \"config-map or cm\", \"secret or sc\", and \"volume or vo\"", slices[0])
|
return nil, nil, fmt.Errorf("unsupported volume type \"%q\"; supported volume types are \"config-map or cm\", \"secret or sc\", and \"volume or vo\"", slices[0])
|
||||||
|
|
|
||||||
|
|
@ -136,6 +136,54 @@ func TestPodSpecResolve(t *testing.T) {
|
||||||
testCmd.Execute()
|
testCmd.Execute()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPodSpecMountResolveSubPath(t *testing.T) {
|
||||||
|
args := map[string]*MountInfo{
|
||||||
|
"/mydir=cm:my-cm": {
|
||||||
|
VolumeName: "my-cm",
|
||||||
|
},
|
||||||
|
"/mydir=sc:my-sec": {
|
||||||
|
VolumeName: "my-sec",
|
||||||
|
},
|
||||||
|
"/mydir=myvol": {
|
||||||
|
VolumeName: "myvol",
|
||||||
|
},
|
||||||
|
|
||||||
|
"/mydir=cm:my-cm/subpath/to/mount": {
|
||||||
|
VolumeName: "my-cm",
|
||||||
|
SubPath: "subpath/to/mount",
|
||||||
|
},
|
||||||
|
"/mydir=sc:my-sec/subpath/to/mount": {
|
||||||
|
VolumeName: "my-sec",
|
||||||
|
SubPath: "subpath/to/mount",
|
||||||
|
},
|
||||||
|
"/mydir=myvol/subpath/to/mount": {
|
||||||
|
VolumeName: "myvol",
|
||||||
|
SubPath: "subpath/to/mount",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for arg, mountInfo := range args {
|
||||||
|
outBuf := bytes.Buffer{}
|
||||||
|
flags := &PodSpecFlags{}
|
||||||
|
inputArgs := append([]string{"--image", "repo/user/imageID:tag", "--mount"}, arg)
|
||||||
|
testCmd := &cobra.Command{
|
||||||
|
Use: "test",
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
podSpec := &corev1.PodSpec{Containers: []corev1.Container{{}}}
|
||||||
|
err := flags.ResolvePodSpec(podSpec, cmd.Flags(), inputArgs)
|
||||||
|
assert.NilError(t, err)
|
||||||
|
assert.Equal(t, podSpec.Containers[0].VolumeMounts[0].SubPath, mountInfo.SubPath)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
testCmd.SetOut(&outBuf)
|
||||||
|
|
||||||
|
testCmd.SetArgs(inputArgs)
|
||||||
|
flags.AddFlags(testCmd.Flags())
|
||||||
|
flags.AddCreateFlags(testCmd.Flags())
|
||||||
|
testCmd.Execute()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestPodSpecResolveContainers(t *testing.T) {
|
func TestPodSpecResolveContainers(t *testing.T) {
|
||||||
rawInput := `
|
rawInput := `
|
||||||
containers:
|
containers:
|
||||||
|
|
|
||||||
|
|
@ -18,17 +18,19 @@
|
||||||
package e2e
|
package e2e
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
|
v1 "k8s.io/api/core/v1"
|
||||||
"knative.dev/client/lib/test"
|
"knative.dev/client/lib/test"
|
||||||
"knative.dev/client/pkg/util"
|
"knative.dev/client/pkg/util"
|
||||||
network "knative.dev/networking/pkg"
|
network "knative.dev/networking/pkg"
|
||||||
pkgtest "knative.dev/pkg/test"
|
pkgtest "knative.dev/pkg/test"
|
||||||
"knative.dev/serving/pkg/apis/serving"
|
"knative.dev/serving/pkg/apis/serving"
|
||||||
|
servingv1 "knative.dev/serving/pkg/apis/serving/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestService(t *testing.T) {
|
func TestService(t *testing.T) {
|
||||||
|
|
@ -70,6 +72,9 @@ func TestService(t *testing.T) {
|
||||||
test.ServiceCreate(r, "service2")
|
test.ServiceCreate(r, "service2")
|
||||||
test.ServiceCreate(r, "ksvc3")
|
test.ServiceCreate(r, "ksvc3")
|
||||||
serviceDeleteAll(r)
|
serviceDeleteAll(r)
|
||||||
|
|
||||||
|
t.Log("create services with volume mounts and subpaths")
|
||||||
|
serviceCreateWithMount(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
func serviceCreatePrivate(r *test.KnRunResultCollector, serviceName string) {
|
func serviceCreatePrivate(r *test.KnRunResultCollector, serviceName string) {
|
||||||
|
|
@ -170,3 +175,55 @@ func serviceDeleteAll(r *test.KnRunResultCollector) {
|
||||||
// Check if no services present after kn service delete --all.
|
// Check if no services present after kn service delete --all.
|
||||||
assert.Check(r.T(), strings.Contains(out.Stdout, "No services found."), "Failed to show 'No services found' after kn service delete --all")
|
assert.Check(r.T(), strings.Contains(out.Stdout, "No services found."), "Failed to show 'No services found' after kn service delete --all")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func serviceCreateWithMount(r *test.KnRunResultCollector) {
|
||||||
|
it := r.KnTest()
|
||||||
|
kubectl := test.NewKubectl(it.Namespace())
|
||||||
|
|
||||||
|
r.T().Log("create cm test-cm")
|
||||||
|
_, err := kubectl.Run("create", "configmap", "test-cm", "--from-literal=key=value")
|
||||||
|
assert.NilError(r.T(), err)
|
||||||
|
|
||||||
|
r.T().Log("create service with configmap mounted")
|
||||||
|
out := r.KnTest().Kn().Run("service", "create", "test-svc", "--image", pkgtest.ImagePath("helloworld"), "--mount", "/mydir=cm:test-cm")
|
||||||
|
r.AssertNoError(out)
|
||||||
|
|
||||||
|
r.T().Log("update the subpath in mounted cm")
|
||||||
|
out = r.KnTest().Kn().Run("service", "update", "test-svc", "--mount", "/mydir=cm:test-cm/key")
|
||||||
|
r.AssertNoError(out)
|
||||||
|
|
||||||
|
r.T().Log("create secret test-sec")
|
||||||
|
_, err = kubectl.Run("create", "secret", "generic", "test-sec", "--from-literal", "key1=val1")
|
||||||
|
assert.NilError(r.T(), err)
|
||||||
|
|
||||||
|
r.T().Log("update service with a new mount")
|
||||||
|
out = r.KnTest().Kn().Run("service", "update", "test-svc", "--mount", "/mydir2=sc:test-sec/key1")
|
||||||
|
r.AssertNoError(out)
|
||||||
|
|
||||||
|
serviceDescribeMount(r, "test-svc", "/mydir", "key")
|
||||||
|
}
|
||||||
|
|
||||||
|
func getVolumeMountWithHostPath(svc *servingv1.Service, hostPath string) *v1.VolumeMount {
|
||||||
|
vols := svc.Spec.Template.Spec.Containers[0].VolumeMounts
|
||||||
|
|
||||||
|
for _, v := range vols {
|
||||||
|
if v.MountPath == hostPath {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func serviceDescribeMount(r *test.KnRunResultCollector, serviceName, hostPath, subPath string) {
|
||||||
|
out := r.KnTest().Kn().Run("service", "describe", serviceName, "-o=json")
|
||||||
|
r.AssertNoError(out)
|
||||||
|
|
||||||
|
svc := &servingv1.Service{}
|
||||||
|
assert.NilError(r.T(), json.Unmarshal([]byte(out.Stdout), &svc))
|
||||||
|
|
||||||
|
r.T().Log("check volume mounts not nil")
|
||||||
|
volumeMount := getVolumeMountWithHostPath(svc, hostPath)
|
||||||
|
assert.Check(r.T(), volumeMount != nil)
|
||||||
|
|
||||||
|
r.T().Log("check volume mount subpath is the same as given")
|
||||||
|
assert.Equal(r.T(), subPath, volumeMount.SubPath)
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue