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