Merge "Add local volume provisioner chart"
This commit is contained in:
commit
0b1ae682e0
24
local-volume-provisioner/Chart.yaml
Normal file
24
local-volume-provisioner/Chart.yaml
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License 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.
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
appVersion: v1.0.0
|
||||||
|
description: OpenStack-Helm local-volume-provisioner
|
||||||
|
name: local-volume-provisioner
|
||||||
|
version: 0.1.0
|
||||||
|
home: https://github.com/kubernetes-sigs/sig-storage-local-static-provisioner
|
||||||
|
sources:
|
||||||
|
- https://opendev.org/openstack/openstack-helm
|
||||||
|
maintainers:
|
||||||
|
- name: OpenStack-Helm Authors
|
||||||
|
...
|
18
local-volume-provisioner/requirements.yaml
Normal file
18
local-volume-provisioner/requirements.yaml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License 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.
|
||||||
|
|
||||||
|
---
|
||||||
|
dependencies:
|
||||||
|
- name: helm-toolkit
|
||||||
|
repository: file://../helm-toolkit
|
||||||
|
version: ">= 0.1.0"
|
||||||
|
...
|
377
local-volume-provisioner/templates/bin/_fakemount.py.tpl
Normal file
377
local-volume-provisioner/templates/bin/_fakemount.py.tpl
Normal file
@ -0,0 +1,377 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
#
|
||||||
|
# Copyright 2019 Mirantis, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License 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.
|
||||||
|
"""Fakemount python module
|
||||||
|
The module is aimed to crate fake mountpoints (--bind).
|
||||||
|
Example:
|
||||||
|
python3 fakemount --config-file '/root/mymount.yml'
|
||||||
|
Attributes:
|
||||||
|
config-file - file path to config file that contains fake mounts.
|
||||||
|
"""
|
||||||
|
__version__ = "1.0"
|
||||||
|
import argparse
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
from collections import defaultdict
|
||||||
|
import yaml
|
||||||
|
logging.basicConfig(stream=sys.stdout, level=logging.INFO)
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
MOUNT_BIN = "/bin/mount"
|
||||||
|
###Fork https://github.com/b10011/pyfstab/ #####################################
|
||||||
|
# Latest commit 828540d
|
||||||
|
class InvalidEntry(Exception):
|
||||||
|
"""
|
||||||
|
Raised when a string cannot be generated because of the Entry is invalid.
|
||||||
|
"""
|
||||||
|
class InvalidFstabLine(Exception):
|
||||||
|
"""
|
||||||
|
Raised when a line is invalid in fstab. This doesn't just mean that the
|
||||||
|
Entry will be invalid but also that the system can not process the fstab
|
||||||
|
file fully either.
|
||||||
|
"""
|
||||||
|
class Entry:
|
||||||
|
"""
|
||||||
|
Handles parsing and formatting fstab line entries.
|
||||||
|
:var device:
|
||||||
|
(str or None) -
|
||||||
|
Fstab device (1st parameter in the fstab entry)
|
||||||
|
:var dir:
|
||||||
|
(str or None) -
|
||||||
|
Fstab device (2nd parameter in the fstab entry)
|
||||||
|
:var type:
|
||||||
|
(str or None) -
|
||||||
|
Fstab device (3rd parameter in the fstab entry)
|
||||||
|
:var options:
|
||||||
|
(str or None) -
|
||||||
|
Fstab device (4th parameter in the fstab entry)
|
||||||
|
:var dump:
|
||||||
|
(int or None) -
|
||||||
|
Fstab device (5th parameter in the fstab entry)
|
||||||
|
:var fsck:
|
||||||
|
(int or None) -
|
||||||
|
Fstab device (6th parameter in the fstab entry)
|
||||||
|
:var valid:
|
||||||
|
(bool) -
|
||||||
|
Whether the Entry is valid or not. Can be checked with "if entry:".
|
||||||
|
"""
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
_device=None,
|
||||||
|
_dir=None,
|
||||||
|
_type=None,
|
||||||
|
_options=None,
|
||||||
|
_dump=None,
|
||||||
|
_fsck=None,
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
:param _device: Fstab device (1st parameter in the fstab entry)
|
||||||
|
:type _device: str
|
||||||
|
:param _dir: Fstab device (2nd parameter in the fstab entry)
|
||||||
|
:type _dir: str
|
||||||
|
:param _type: Fstab device (3rd parameter in the fstab entry)
|
||||||
|
:type _type: str
|
||||||
|
:param _options: Fstab device (4th parameter in the fstab entry)
|
||||||
|
:type _options: str
|
||||||
|
:param _dump: Fstab device (5th parameter in the fstab entry)
|
||||||
|
:type _dump: int
|
||||||
|
:param _fsck: Fstab device (6th parameter in the fstab entry)
|
||||||
|
:type _fsck: int
|
||||||
|
"""
|
||||||
|
self.device = _device
|
||||||
|
self.dir = _dir
|
||||||
|
self.type = _type
|
||||||
|
self.options = _options
|
||||||
|
self.dump = _dump
|
||||||
|
self.fsck = _fsck
|
||||||
|
self.valid = True
|
||||||
|
self.valid &= self.device is not None
|
||||||
|
self.valid &= self.dir is not None
|
||||||
|
self.valid &= self.type is not None
|
||||||
|
self.valid &= self.options is not None
|
||||||
|
self.valid &= self.dump is not None
|
||||||
|
self.valid &= self.fsck is not None
|
||||||
|
def read_string(self, line):
|
||||||
|
"""
|
||||||
|
Parses an entry from a string
|
||||||
|
:param line: Fstab entry line.
|
||||||
|
:type line: str
|
||||||
|
:return: self
|
||||||
|
:rtype: Entry
|
||||||
|
:raises InvalidEntry: If the data in the string cannot be parsed.
|
||||||
|
"""
|
||||||
|
line = line.strip()
|
||||||
|
if line and not line[0] == "#":
|
||||||
|
parts = re.split(r"\s+", line)
|
||||||
|
if len(parts) == 6:
|
||||||
|
[_device, _dir, _type, _options, _dump, _fsck] = parts
|
||||||
|
_dump = int(_dump)
|
||||||
|
_fsck = int(_fsck)
|
||||||
|
self.device = _device
|
||||||
|
self.dir = _dir
|
||||||
|
self.type = _type
|
||||||
|
self.options = _options
|
||||||
|
self.dump = _dump
|
||||||
|
self.fsck = _fsck
|
||||||
|
self.valid = True
|
||||||
|
return self
|
||||||
|
else:
|
||||||
|
raise InvalidFstabLine()
|
||||||
|
self.device = None
|
||||||
|
self.dir = None
|
||||||
|
self.type = None
|
||||||
|
self.options = None
|
||||||
|
self.dump = None
|
||||||
|
self.fsck = None
|
||||||
|
self.valid = False
|
||||||
|
raise InvalidEntry("Entry cannot be parsed")
|
||||||
|
def write_string(self):
|
||||||
|
"""
|
||||||
|
Formats the Entry into fstab entry line.
|
||||||
|
:return: Fstab entry line.
|
||||||
|
:rtype: str
|
||||||
|
:raises InvalidEntry:
|
||||||
|
A string cannot be generated because the entry is invalid.
|
||||||
|
"""
|
||||||
|
if self:
|
||||||
|
return "{} {} {} {} {} {}".format(
|
||||||
|
self.device,
|
||||||
|
self.dir,
|
||||||
|
self.type,
|
||||||
|
self.options,
|
||||||
|
self.dump,
|
||||||
|
self.fsck,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise InvalidEntry("Entry cannot be formatted")
|
||||||
|
def __bool__(self):
|
||||||
|
return self.valid
|
||||||
|
def __str__(self):
|
||||||
|
return self.write_string()
|
||||||
|
def __repr__(self):
|
||||||
|
try:
|
||||||
|
return "<Entry {}>".format(str(self))
|
||||||
|
except InvalidEntry:
|
||||||
|
return "<Entry Invalid>"
|
||||||
|
class Fstab:
|
||||||
|
"""
|
||||||
|
Handles reading, parsing, formatting and writing of fstab files.
|
||||||
|
:var entries:
|
||||||
|
(list[Entry]) -
|
||||||
|
List of entries.
|
||||||
|
When writing to a file, entries are listed from this list.
|
||||||
|
:var entries_by_device:
|
||||||
|
(dict[str, list[Entry]]) -
|
||||||
|
Fstab entries by device.
|
||||||
|
:var entry_by_dir:
|
||||||
|
(dict[str, Entry]) -
|
||||||
|
Fstab entry by directory.
|
||||||
|
:var entries_by_type:
|
||||||
|
(dict[str, list[Entry]]) -
|
||||||
|
Fstab entries by type.
|
||||||
|
"""
|
||||||
|
def __init__(self):
|
||||||
|
self.entries = []
|
||||||
|
# A single device can have multiple mountpoints
|
||||||
|
self.entries_by_device = defaultdict(list)
|
||||||
|
# If multiple devices have same mountpoint, only the last entry in the
|
||||||
|
# fstab file is taken into consideration
|
||||||
|
self.entry_by_dir = dict()
|
||||||
|
# And the most obvious one, many entries can have mountpoints of same
|
||||||
|
# type
|
||||||
|
self.entries_by_type = defaultdict(list)
|
||||||
|
def read_string(self, data, only_valid=False):
|
||||||
|
"""
|
||||||
|
Parses entries from a data string
|
||||||
|
:param data: Contents of the fstab file
|
||||||
|
:type data: str
|
||||||
|
:param only_valid:
|
||||||
|
Skip the entries that do not actually mount. For example, if device
|
||||||
|
A is mounted to directory X and later device B is mounted to
|
||||||
|
directory X, the A mount to X is undone by the system.
|
||||||
|
:type only_valid: bool
|
||||||
|
:return: self
|
||||||
|
:rtype: Fstab
|
||||||
|
"""
|
||||||
|
for line in reversed(data.splitlines()):
|
||||||
|
try:
|
||||||
|
entry = Entry().read_string(line)
|
||||||
|
if entry and (
|
||||||
|
not only_valid or entry.dir not in self.entry_by_dir
|
||||||
|
):
|
||||||
|
self.entries.insert(0, entry)
|
||||||
|
self.entries_by_device[entry.device].insert(0, entry)
|
||||||
|
self.entry_by_dir[entry.dir] = entry
|
||||||
|
self.entries_by_type[entry.type].insert(0, entry)
|
||||||
|
except InvalidEntry:
|
||||||
|
pass
|
||||||
|
return self
|
||||||
|
def write_string(self):
|
||||||
|
"""
|
||||||
|
Formats entries into a string.
|
||||||
|
:return: Formatted fstab file.
|
||||||
|
:rtype: str
|
||||||
|
:raises InvalidEntry:
|
||||||
|
A string cannot be generated because one of the entries is invalid.
|
||||||
|
"""
|
||||||
|
return "\n".join(str(entry) for entry in self.entries)
|
||||||
|
def read_file(self, handle, only_valid=False):
|
||||||
|
"""
|
||||||
|
Parses entries from a file
|
||||||
|
:param handle: File handle
|
||||||
|
:type handle: file
|
||||||
|
:param only_valid:
|
||||||
|
Skip the entries that do not actually mount. For example, if device
|
||||||
|
A is mounted to directory X and later device B is mounted to
|
||||||
|
directory X, the A mount to X is undone by the system.
|
||||||
|
:type only_valid: bool
|
||||||
|
:return: self
|
||||||
|
:rtype: Fstab
|
||||||
|
"""
|
||||||
|
self.read_string(handle.read(), only_valid)
|
||||||
|
return self
|
||||||
|
def write_file(self, handle):
|
||||||
|
"""
|
||||||
|
Parses entries in data string
|
||||||
|
:param path: File handle
|
||||||
|
:type path: file
|
||||||
|
:return: self
|
||||||
|
:rtype: Fstab
|
||||||
|
"""
|
||||||
|
handle.write(str(self))
|
||||||
|
return self
|
||||||
|
def __bool__(self):
|
||||||
|
return len(self.entries) > 0
|
||||||
|
def __str__(self):
|
||||||
|
return self.write_string()
|
||||||
|
def __repr__(self):
|
||||||
|
res = "<Fstab [{} entries]".format(len(self.entries))
|
||||||
|
if self.entries:
|
||||||
|
res += "\n"
|
||||||
|
for entry in self.entries:
|
||||||
|
res += " {}\n".format(entry)
|
||||||
|
res += ">"
|
||||||
|
return res
|
||||||
|
###End Fork https://github.com/b10011/pyfstab/ #################################
|
||||||
|
def fstab_bindmount(src, mountpoint, fstab_path="/mnt/host/fstab", opts=None):
|
||||||
|
if opts is None:
|
||||||
|
opts = ["bind"]
|
||||||
|
mountpoint = os.path.normpath(mountpoint.strip())
|
||||||
|
with open(fstab_path, "r") as f:
|
||||||
|
fstab = Fstab().read_file(f)
|
||||||
|
if mountpoint in fstab.entry_by_dir:
|
||||||
|
LOG.info(f'Mount point {mountpoint} already defined in {fstab_path}')
|
||||||
|
return
|
||||||
|
fstab.entries.append(Entry(src, mountpoint, "none", ",".join(opts), 0, 0))
|
||||||
|
str_fstab = str(fstab)
|
||||||
|
LOG.info(f'Attempt to overwrite file:{fstab_path}, with data:\n'
|
||||||
|
f'{str_fstab}')
|
||||||
|
with open(fstab_path, "w") as f:
|
||||||
|
f.write(str_fstab)
|
||||||
|
def get_volumes(mount_point, i):
|
||||||
|
vol_template = "vol%d%%d" % i
|
||||||
|
volumes = mount_point.get("mounts")
|
||||||
|
if volumes is not None:
|
||||||
|
return volumes
|
||||||
|
return [vol_template % vol_number for vol_number in
|
||||||
|
range(mount_point["volPerNode"])]
|
||||||
|
def ensure_directories_exists(storage_class):
|
||||||
|
target_root = storage_class.get("mountDir", storage_class["hostDir"])
|
||||||
|
for i, bind_mount in enumerate(storage_class["bindMounts"]):
|
||||||
|
for vol_name in get_volumes(bind_mount, i):
|
||||||
|
source = os.path.normpath(f"{bind_mount['srcRoot']}/{vol_name}")
|
||||||
|
target = os.path.normpath(f"{target_root}/{vol_name}")
|
||||||
|
os.makedirs(target, exist_ok=True)
|
||||||
|
os.makedirs(source, exist_ok=True)
|
||||||
|
def is_mount(directory):
|
||||||
|
# Do not use os.path.ismount due to bug
|
||||||
|
# https://bugs.python.org/issue29707
|
||||||
|
directory = os.path.normpath(directory.strip())
|
||||||
|
with open("/proc/mounts") as f:
|
||||||
|
for line in f.readlines():
|
||||||
|
if line.split(" ")[1] == directory:
|
||||||
|
return True
|
||||||
|
def mount_directories(storage_class):
|
||||||
|
failed_mounts = []
|
||||||
|
target_root = storage_class.get("mountDir", storage_class["hostDir"])
|
||||||
|
additional_opts = storage_class.get("additionalMountOptions", [])
|
||||||
|
opts = ["bind"] + additional_opts
|
||||||
|
for i, bind_mount in enumerate(storage_class["bindMounts"]):
|
||||||
|
for vol_name in get_volumes(bind_mount, i):
|
||||||
|
source = os.path.normpath(f"{bind_mount['srcRoot']}/{vol_name}")
|
||||||
|
target = os.path.normpath(f"{target_root}/{vol_name}")
|
||||||
|
LOG.info(f"Trying to mount {source} to {target}")
|
||||||
|
if is_mount(target):
|
||||||
|
LOG.info(
|
||||||
|
f"The directory {target} already mounted, skipping it...")
|
||||||
|
else:
|
||||||
|
cmd = [MOUNT_BIN, "-o", ",".join(opts), source, target]
|
||||||
|
LOG.info(f"Running {cmd}")
|
||||||
|
obj = None
|
||||||
|
try:
|
||||||
|
obj = subprocess.run(
|
||||||
|
cmd,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.PIPE,
|
||||||
|
)
|
||||||
|
obj.check_returncode()
|
||||||
|
except Exception as e:
|
||||||
|
LOG.exception(
|
||||||
|
f"Failed to mount {source} {target}\n"
|
||||||
|
f"stdout: {obj.stdout}\n"
|
||||||
|
f"stderr: {obj.stderr}"
|
||||||
|
)
|
||||||
|
failed_mounts.append((source, target))
|
||||||
|
else:
|
||||||
|
LOG.info(f"Successfully mount {source} {target}")
|
||||||
|
fstab_bindmount(source, target, opts=opts)
|
||||||
|
if failed_mounts:
|
||||||
|
raise Exception(f"Failed to mount some directories: {failed_mounts}")
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description="Create fake mountpotins with specified directories."
|
||||||
|
)
|
||||||
|
group = parser.add_mutually_exclusive_group(required=True)
|
||||||
|
group.add_argument(
|
||||||
|
"--config-file", help="Path to file with image layout",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--create-only",
|
||||||
|
help="Ensure target directories exists.",
|
||||||
|
dest="create_only",
|
||||||
|
action="store_true",
|
||||||
|
)
|
||||||
|
parser.set_defaults(create_only=False)
|
||||||
|
args = parser.parse_args()
|
||||||
|
with open(args.config_file) as f:
|
||||||
|
data = yaml.safe_load(f)
|
||||||
|
if data is None:
|
||||||
|
LOG.exception("Invalid data supplied from the config file.")
|
||||||
|
raise Exception
|
||||||
|
classes_data = data.get("classes", [])
|
||||||
|
if isinstance(classes_data, list):
|
||||||
|
for storage_class in classes_data:
|
||||||
|
ensure_directories_exists(storage_class)
|
||||||
|
if not args.create_only:
|
||||||
|
for storage_class in classes_data:
|
||||||
|
mount_directories(storage_class)
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
except Exception as e:
|
||||||
|
LOG.exception("Can't create volume mounts.")
|
||||||
|
sys.exit(1)
|
58
local-volume-provisioner/templates/configmap-bin.yaml
Normal file
58
local-volume-provisioner/templates/configmap-bin.yaml
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
{{/*
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License 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.
|
||||||
|
*/}}
|
||||||
|
|
||||||
|
{{- define "lvp.configmap.bin" }}
|
||||||
|
{{- $configMapName := index . 0 }}
|
||||||
|
{{- $envAll := index . 1 }}
|
||||||
|
{{- with $envAll }}
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: {{ $configMapName }}
|
||||||
|
data:
|
||||||
|
{{- if .Values.images.local_registry.active }}
|
||||||
|
image-repo-sync.sh: |
|
||||||
|
{{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }}
|
||||||
|
{{- end }}
|
||||||
|
fakemount.py: |
|
||||||
|
{{ tuple "bin/_fakemount.py.tpl" . | include "helm-toolkit.utils.template" | indent 4 }}
|
||||||
|
storageClassMap: |
|
||||||
|
{{- range $classConfig := $envAll.Values.conf.fake_mounts.classes }}
|
||||||
|
{{ $classConfig.name }}:
|
||||||
|
hostDir: {{ $classConfig.hostDir }}
|
||||||
|
mountDir: {{ $classConfig.mountDir | default $classConfig.hostDir }}
|
||||||
|
{{- if $classConfig.blockCleanerCommand }}
|
||||||
|
blockCleanerCommand:
|
||||||
|
{{- range $val := $classConfig.blockCleanerCommand }}
|
||||||
|
- {{ $val | quote }}
|
||||||
|
{{- end}}
|
||||||
|
{{- end }}
|
||||||
|
{{- if $classConfig.volumeMode }}
|
||||||
|
volumeMode: {{ $classConfig.volumeMode }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if $classConfig.fsType }}
|
||||||
|
fsType: {{ $classConfig.fsType }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if $classConfig.namePattern }}
|
||||||
|
namePattern: {{ $classConfig.namePattern | quote }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{- if .Values.manifests.configmap_bin }}
|
||||||
|
{{- list "local-volume-provisioner-bin" . | include "lvp.configmap.bin" }}
|
||||||
|
{{- end }}
|
33
local-volume-provisioner/templates/configmap-etc.yaml
Normal file
33
local-volume-provisioner/templates/configmap-etc.yaml
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
{{/*
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License 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.
|
||||||
|
*/}}
|
||||||
|
|
||||||
|
{{- define "lvp.configmap.etc" }}
|
||||||
|
{{- $configMapName := index . 0 }}
|
||||||
|
{{- $envAll := index . 1 }}
|
||||||
|
{{- with $envAll }}
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: {{ $configMapName }}
|
||||||
|
type: Opaque
|
||||||
|
data:
|
||||||
|
fake_mounts.conf: {{ $envAll.Values.conf.fake_mounts | toJson | b64enc }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{- if .Values.manifests.configmap_etc }}
|
||||||
|
{{- list "local-volume-provisioner-etc" . | include "lvp.configmap.etc" }}
|
||||||
|
{{- end }}
|
212
local-volume-provisioner/templates/daemonset-lvp.yaml
Normal file
212
local-volume-provisioner/templates/daemonset-lvp.yaml
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
{{/*
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License 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.
|
||||||
|
*/}}
|
||||||
|
|
||||||
|
{{- define "lvp.daemonset" }}
|
||||||
|
{{- $daemonset := index . 0 }}
|
||||||
|
{{- $configMapName := index . 1 }}
|
||||||
|
{{- $serviceAccountName := index . 2 }}
|
||||||
|
{{- $envAll := index . 3 }}
|
||||||
|
|
||||||
|
{{- with $envAll }}
|
||||||
|
|
||||||
|
{{- $mounts_lvp := $envAll.Values.pod.mounts.local_volume_provisioner.lvp }}
|
||||||
|
{{- $mounts_lvp_init := $envAll.Values.pod.mounts.local_volume_provisioner.init_container }}
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: DaemonSet
|
||||||
|
metadata:
|
||||||
|
name: local-volume-provisioner
|
||||||
|
annotations:
|
||||||
|
{{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }}
|
||||||
|
labels:
|
||||||
|
{{ tuple $envAll .Chart.Name $daemonset | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }}
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
{{ tuple $envAll .Chart.Name $daemonset | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }}
|
||||||
|
{{ tuple $envAll $daemonset | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }}
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
{{ tuple $envAll .Chart.Name $daemonset | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }}
|
||||||
|
annotations:
|
||||||
|
{{- dict "envAll" $envAll "podName" "local-volume-provisioner" "containerNames" (list "lvp") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }}
|
||||||
|
{{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }}
|
||||||
|
configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }}
|
||||||
|
configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }}
|
||||||
|
spec:
|
||||||
|
{{ dict "envAll" $envAll "application" "local-volume-provisioner" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }}
|
||||||
|
serviceAccountName: {{ $serviceAccountName }}
|
||||||
|
nodeSelector:
|
||||||
|
{{ $envAll.Values.labels.local_volume_provisioner.node_selector_key }}: {{ $envAll.Values.labels.local_volume_provisioner.node_selector_value }}
|
||||||
|
initContainers:
|
||||||
|
- name: init-mounts
|
||||||
|
{{ tuple $envAll "local_volume_provisioner_mounts" | include "helm-toolkit.snippets.image" | indent 10 }}
|
||||||
|
{{ dict "envAll" $envAll "application" "local_volume_provisioner" "container" "init_mounts" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }}
|
||||||
|
terminationMessagePath: /var/log/termination-log
|
||||||
|
env:
|
||||||
|
- name: POD_NAME
|
||||||
|
valueFrom:
|
||||||
|
fieldRef:
|
||||||
|
apiVersion: v1
|
||||||
|
fieldPath: metadata.name
|
||||||
|
- name: NAMESPACE
|
||||||
|
valueFrom:
|
||||||
|
fieldRef:
|
||||||
|
apiVersion: v1
|
||||||
|
fieldPath: metadata.namespace
|
||||||
|
- name: PATH
|
||||||
|
value: /var/lib/openstack/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/
|
||||||
|
command:
|
||||||
|
- /tmp/fakemount.py
|
||||||
|
- --config-file
|
||||||
|
- /etc/provisioner/fake_mounts.conf
|
||||||
|
volumeMounts:
|
||||||
|
- name: fstab
|
||||||
|
mountPath: /mnt/host/fstab
|
||||||
|
- name: local-volume-provisioner-etc
|
||||||
|
mountPath: /etc/provisioner/fake_mounts.conf
|
||||||
|
subPath: fake_mounts.conf
|
||||||
|
readOnly: true
|
||||||
|
- name: local-volume-provisioner-bin
|
||||||
|
mountPath: /tmp/fakemount.py
|
||||||
|
subPath: fakemount.py
|
||||||
|
readOnly: true
|
||||||
|
{{- range $classConfig := $envAll.Values.conf.fake_mounts.classes }}
|
||||||
|
{{- range $bindMount := $classConfig.bindMounts }}
|
||||||
|
- mountPath: {{ $bindMount.srcRoot }}
|
||||||
|
mountPropagation: Bidirectional
|
||||||
|
name: {{ replace "/" "" $bindMount.srcRoot }}
|
||||||
|
{{- end }}
|
||||||
|
- mountPath: {{ if $classConfig.mountDir }} {{- $classConfig.mountDir -}} {{ else }} {{- $classConfig.hostDir -}} {{ end }}
|
||||||
|
mountPropagation: Bidirectional
|
||||||
|
name: {{ $classConfig.name }}
|
||||||
|
{{- end }}
|
||||||
|
- mountPath: /run
|
||||||
|
name: run
|
||||||
|
containers:
|
||||||
|
- name: lvp
|
||||||
|
{{ tuple $envAll "local_volume_provisioner" | include "helm-toolkit.snippets.image" | indent 10 }}
|
||||||
|
{{ tuple $envAll $envAll.Values.pod.resources.local_volume_provisioner | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }}
|
||||||
|
{{ dict "envAll" $envAll "application" "local_volume_provisioner" "container" "lvp" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }}
|
||||||
|
env:
|
||||||
|
- name: MY_NODE_NAME
|
||||||
|
valueFrom:
|
||||||
|
fieldRef:
|
||||||
|
fieldPath: spec.nodeName
|
||||||
|
- name: NAMESPACE
|
||||||
|
valueFrom:
|
||||||
|
fieldRef:
|
||||||
|
apiVersion: v1
|
||||||
|
fieldPath: metadata.namespace
|
||||||
|
command:
|
||||||
|
- /local-provisioner
|
||||||
|
volumeMounts:
|
||||||
|
- name: local-volume-provisioner-bin
|
||||||
|
mountPath: /etc/provisioner/config/storageClassMap
|
||||||
|
subPath: storageClassMap
|
||||||
|
readOnly: true
|
||||||
|
- name: dev
|
||||||
|
mountPath: /dev
|
||||||
|
{{- range $classConfig := $envAll.Values.conf.fake_mounts.classes }}
|
||||||
|
- name: {{ $classConfig.name }}
|
||||||
|
mountPath: {{ $classConfig.mountDir | default $classConfig.hostDir }}
|
||||||
|
mountPropagation: HostToContainer
|
||||||
|
{{- end }}
|
||||||
|
volumes:
|
||||||
|
- name: fstab
|
||||||
|
hostPath:
|
||||||
|
type: File
|
||||||
|
path: /etc/fstab
|
||||||
|
- name: local-volume-provisioner-bin
|
||||||
|
configMap:
|
||||||
|
name: local-volume-provisioner-bin
|
||||||
|
defaultMode: 0555
|
||||||
|
- name: local-volume-provisioner-etc
|
||||||
|
secret:
|
||||||
|
secretName: {{ $configMapName }}
|
||||||
|
defaultMode: 0444
|
||||||
|
- name: run
|
||||||
|
hostPath:
|
||||||
|
path: /run
|
||||||
|
- name: dev
|
||||||
|
hostPath:
|
||||||
|
path: /dev
|
||||||
|
{{- range $classConfig := $envAll.Values.conf.fake_mounts.classes }}
|
||||||
|
{{- range $bindMount := $classConfig.bindMounts }}
|
||||||
|
- name: {{ replace "/" "" $bindMount.srcRoot }}
|
||||||
|
hostPath:
|
||||||
|
path: {{ $bindMount.srcRoot }}
|
||||||
|
type: ""
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- range $classConfig := $envAll.Values.conf.fake_mounts.classes }}
|
||||||
|
- name: {{ $classConfig.name }}
|
||||||
|
hostPath:
|
||||||
|
path: {{ $classConfig.hostDir }}
|
||||||
|
{{- end }}
|
||||||
|
{{ if $mounts_lvp.volumes }}{{ toYaml $mounts_lvp.volumes | indent 8 }}{{ end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{- if .Values.manifests.daemonset_local_volume_provisioner }}
|
||||||
|
|
||||||
|
{{- $envAll := . }}
|
||||||
|
{{- $daemonset := "local_volume_provisioner" }}
|
||||||
|
{{- $configMapName := "local_volume_provisioner-etc" }}
|
||||||
|
{{- $serviceAccountName := "local-volume-provisioner" }}
|
||||||
|
|
||||||
|
{{ tuple $envAll "lvp" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }}
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRole
|
||||||
|
metadata:
|
||||||
|
name: {{ $serviceAccountName }}-nodes
|
||||||
|
rules:
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["nodes"]
|
||||||
|
verbs: ["get"]
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRoleBinding
|
||||||
|
metadata:
|
||||||
|
name: {{ $serviceAccountName }}-nodes
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: {{ $serviceAccountName }}
|
||||||
|
namespace: {{ .Release.Namespace }}
|
||||||
|
roleRef:
|
||||||
|
kind: ClusterRole
|
||||||
|
name: {{ $serviceAccountName }}-nodes
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRoleBinding
|
||||||
|
metadata:
|
||||||
|
name: {{ $serviceAccountName }}-cluter-admin
|
||||||
|
roleRef:
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
kind: ClusterRole
|
||||||
|
name: cluster-admin
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: {{ $serviceAccountName }}
|
||||||
|
namespace: {{ .Release.Namespace }}
|
||||||
|
|
||||||
|
{{- $daemonset_yaml := list $daemonset $configMapName $serviceAccountName . | include "lvp.daemonset" | toString | fromYaml }}
|
||||||
|
{{- $configmap_yaml := "lvp.configmap.etc" }}
|
||||||
|
{{- list $daemonset $daemonset_yaml $configmap_yaml $configMapName . | include "helm-toolkit.utils.daemonset_overrides" }}
|
||||||
|
|
||||||
|
{{- end }}
|
18
local-volume-provisioner/templates/job-image-repo-sync.yaml
Normal file
18
local-volume-provisioner/templates/job-image-repo-sync.yaml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{{/*
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License 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.
|
||||||
|
*/}}
|
||||||
|
|
||||||
|
{{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }}
|
||||||
|
{{- $imageRepoSyncJob := dict "envAll" . "serviceName" "local-volume-provisioner" -}}
|
||||||
|
{{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }}
|
||||||
|
{{- end }}
|
17
local-volume-provisioner/templates/secret-registry.yaml
Normal file
17
local-volume-provisioner/templates/secret-registry.yaml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{{/*
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License 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.
|
||||||
|
*/}}
|
||||||
|
|
||||||
|
{{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }}
|
||||||
|
{{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }}
|
||||||
|
{{- end }}
|
27
local-volume-provisioner/templates/storageclasses.yaml
Normal file
27
local-volume-provisioner/templates/storageclasses.yaml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
{{- if .Values.manifests.storageclass }}
|
||||||
|
{{- $envAll := . }}
|
||||||
|
{{- range $val := $envAll.Values.conf.fake_mounts.classes }}
|
||||||
|
{{- if $val.storageClass }}
|
||||||
|
---
|
||||||
|
apiVersion: storage.k8s.io/v1
|
||||||
|
kind: StorageClass
|
||||||
|
metadata:
|
||||||
|
name: {{ $val.name }}
|
||||||
|
{{- if kindIs "map" $val.storageClass }}
|
||||||
|
{{- if $val.storageClass.isDefaultClass }}
|
||||||
|
annotations:
|
||||||
|
storageclass.kubernetes.io/is-default-class: "true"
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
labels:
|
||||||
|
{{ tuple $envAll $envAll.Chart.Name "storageclass" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }}
|
||||||
|
provisioner: kubernetes.io/no-provisioner
|
||||||
|
volumeBindingMode: WaitForFirstConsumer
|
||||||
|
{{- if kindIs "map" $val.storageClass }}
|
||||||
|
reclaimPolicy: {{ $val.storageClass.reclaimPolicy | default "Delete" }}
|
||||||
|
{{- else }}
|
||||||
|
reclaimPolicy: Delete
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
153
local-volume-provisioner/values.yaml
Normal file
153
local-volume-provisioner/values.yaml
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License 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.
|
||||||
|
|
||||||
|
# Default values for local-volume-provisioner.
|
||||||
|
# This is a YAML-formatted file.
|
||||||
|
# Declare name/value pairs to be passed into your templates.
|
||||||
|
# name: value
|
||||||
|
|
||||||
|
---
|
||||||
|
release_group: null
|
||||||
|
|
||||||
|
labels:
|
||||||
|
local_volume_provisioner:
|
||||||
|
node_selector_key: openstack-compute-node
|
||||||
|
node_selector_value: enabled
|
||||||
|
|
||||||
|
images:
|
||||||
|
tags:
|
||||||
|
local_volume_provisioner: mirantis.azurecr.io/bm/external/local-volume-provisioner:v2.4.0
|
||||||
|
dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal
|
||||||
|
image_repo_sync: docker.io/library/docker:17.07.0
|
||||||
|
local_volume_provisioner_mounts: mirantis.azurecr.io/openstack/openstack-controller:0.1.1
|
||||||
|
pull_policy: "IfNotPresent"
|
||||||
|
local_registry:
|
||||||
|
active: false
|
||||||
|
exclude:
|
||||||
|
- dep_check
|
||||||
|
- image_repo_sync
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
static: {}
|
||||||
|
dynamic: {}
|
||||||
|
|
||||||
|
endpoints:
|
||||||
|
cluster_domain_suffix: cluster.local
|
||||||
|
local_image_registry:
|
||||||
|
name: docker-registry
|
||||||
|
namespace: docker-registry
|
||||||
|
hosts:
|
||||||
|
default: localhost
|
||||||
|
internal: docker-registry
|
||||||
|
node: localhost
|
||||||
|
host_fqdn_override:
|
||||||
|
default: null
|
||||||
|
port:
|
||||||
|
registry:
|
||||||
|
node: 5000
|
||||||
|
oci_image_registry:
|
||||||
|
name: oci-image-registry
|
||||||
|
namespace: oci-image-registry
|
||||||
|
auth:
|
||||||
|
enabled: false
|
||||||
|
local_volume_provisioner:
|
||||||
|
username: local_volume_provisioner
|
||||||
|
password: password
|
||||||
|
hosts:
|
||||||
|
default: localhost
|
||||||
|
host_fqdn_override:
|
||||||
|
default: null
|
||||||
|
port:
|
||||||
|
registry:
|
||||||
|
default: null
|
||||||
|
|
||||||
|
conf:
|
||||||
|
fake_mounts:
|
||||||
|
classes:
|
||||||
|
- bindMounts:
|
||||||
|
- mounts:
|
||||||
|
- vol1
|
||||||
|
- vol2
|
||||||
|
- vol3
|
||||||
|
- vol4
|
||||||
|
- vol5
|
||||||
|
- vol6
|
||||||
|
- vol7
|
||||||
|
- vol8
|
||||||
|
- vol9
|
||||||
|
- vol10
|
||||||
|
- vol11
|
||||||
|
- vol12
|
||||||
|
- vol13
|
||||||
|
- vol14
|
||||||
|
- vol15
|
||||||
|
srcRoot: /var/lib/local-volume-provisioner
|
||||||
|
hostDir: /mnt/local-volume-provisioner
|
||||||
|
mountDir: /mnt/local-volume-provisioner
|
||||||
|
name: lvp-fake-root
|
||||||
|
storageClass: true
|
||||||
|
volumeMode: Filesystem
|
||||||
|
pod:
|
||||||
|
security_context:
|
||||||
|
local_volume_provisioner:
|
||||||
|
pod:
|
||||||
|
runAsUser: 0
|
||||||
|
container:
|
||||||
|
lvp:
|
||||||
|
privileged: true
|
||||||
|
readOnlyRootFilesystem: true
|
||||||
|
init_mounts:
|
||||||
|
privileged: true
|
||||||
|
readOnlyRootFilesystem: true
|
||||||
|
dns_policy: "ClusterFirstWithHostNet"
|
||||||
|
mounts:
|
||||||
|
local_volume_provisioner:
|
||||||
|
init_container: null
|
||||||
|
lvp: null
|
||||||
|
lifecycle:
|
||||||
|
upgrades:
|
||||||
|
daemonsets:
|
||||||
|
pod_replacement_strategy: RollingUpdate
|
||||||
|
local_volume_provisioner:
|
||||||
|
enabled: true
|
||||||
|
min_ready_seconds: 0
|
||||||
|
max_unavailable: 1
|
||||||
|
resources:
|
||||||
|
enabled: false
|
||||||
|
local_volume_provisioner:
|
||||||
|
requests:
|
||||||
|
memory: "128Mi"
|
||||||
|
cpu: "100m"
|
||||||
|
limits:
|
||||||
|
memory: "1024Mi"
|
||||||
|
cpu: "2000m"
|
||||||
|
jobs:
|
||||||
|
image_repo_sync:
|
||||||
|
requests:
|
||||||
|
memory: "128Mi"
|
||||||
|
cpu: "100m"
|
||||||
|
limits:
|
||||||
|
memory: "1024Mi"
|
||||||
|
cpu: "2000m"
|
||||||
|
|
||||||
|
manifests:
|
||||||
|
configmap_bin: true
|
||||||
|
configmap_etc: true
|
||||||
|
daemonset_local_volume_provisioner: true
|
||||||
|
job_image_repo_sync: true
|
||||||
|
secret_registry: true
|
||||||
|
storageclass: true
|
||||||
|
|
||||||
|
secrets:
|
||||||
|
oci_image_registry:
|
||||||
|
local_volume_provisioner: local-volume-provisioner-oci-image-registry-key
|
||||||
|
...
|
4
releasenotes/notes/local-volume-provisioner.yaml
Normal file
4
releasenotes/notes/local-volume-provisioner.yaml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
local-volume-provisioner:
|
||||||
|
- 0.1.0 Initial Chart
|
||||||
|
...
|
Loading…
Reference in New Issue
Block a user