Add a script to migrate releases from helm2 to helm3

This commit introduces a custom script that will help
migrating helm releases/installs from helm2 to helm3.

The procedure is:

# install the /helm-2to3 plugin

$ mkdir plugin
$ wget https://github.com/helm/helm-2to3/releases/download/v0.9.0/helm-2to3_0.9.0_linux_amd64.tar.gz
$ pushd plugin/
$ tar -xvzf ../helm-2to3_0.9.0_linux_amd64.tar.gz
$ mkdir bin
$ cp 2to3 bin
$ popd
$ export HELM_LINTER_PLUGIN_NO_INSTALL_HOOK=true
$ helm plugin install ./plugin

# move the helm2 config to helm3

$ helm 2to3 move config

# chose a helmv2 release to migrate:

$ helmv2-cli -- helm list -a

# migrate a helm2 release e.g deployment manager

$ ./migrate_helm_release.py deployment-manager

# check if it migrated successfully:

$ helm list -A -a

# it should not be present anymore in helm2:

helmv2-cli -- helm list -a

Change-Id: I9a3370ddc10a307ba87d72837f8e284fbe2594bd
Signed-off-by: Mihnea Saracin <Mihnea.Saracin@windriver.com>
Closes-Bug: 1943834
This commit is contained in:
Mihnea Saracin 2021-09-15 15:16:22 +03:00
parent b18f501a3d
commit 6c3eeee22f
2 changed files with 119 additions and 0 deletions

View File

@ -61,6 +61,7 @@ install -d -m 755 %{buildroot}%{local_bindir}
install -p -D -m 700 scripts/openstack_update_admin_password %{buildroot}%{local_bindir}/openstack_update_admin_password
install -p -D -m 700 scripts/upgrade_swact_migration.py %{buildroot}%{local_bindir}/upgrade_swact_migration.py
install -p -D -m 755 scripts/image-backup.sh %{buildroot}%{local_bindir}/image-backup.sh
install -p -D -m 755 scripts/migrate_helm_release.py %{buildroot}%{local_bindir}/migrate_helm_release.py
install -d -m 755 %{buildroot}%{local_goenabledd}
install -p -D -m 700 scripts/config_goenabled_check.sh %{buildroot}%{local_goenabledd}/config_goenabled_check.sh

View File

@ -0,0 +1,118 @@
#!/usr/bin/env python
import keyring
import psycopg2
import subprocess
import sys
import os
from psycopg2.extras import RealDictCursor
def main():
if len(sys.argv) != 2:
raise Exception("Release name should be specified")
release = sys.argv[1]
print("Starting to migrate release {}".format(release))
conn = init_connection()
migrate_release(conn, release)
def init_connection():
helmv2_db_pw = keyring.get_password("helmv2", "database")
if not helmv2_db_pw:
raise Exception("Unable to get password to access helmv2 database.")
return psycopg2.connect(user="admin-helmv2",
password=helmv2_db_pw,
host="localhost",
database="helmv2")
def migrate_release(conn, release):
release_info = get_release_info(conn, release)
release_name = release_info["name"]
create_configmap(release_info)
helm2to3_migrate(release_name)
cleanup_release(conn, release_name)
def get_release_info(conn, release):
release_info = None
with conn:
with conn.cursor(cursor_factory=RealDictCursor) as cur:
cur.execute("select * from releases where name = %s", (release,))
release_info = cur.fetchone()
if not release_info:
raise Exception("Release name is not present in the DB")
return release_info
def create_configmap(release_info):
configmap_label_name = release_info["name"]
configmap = """
apiVersion: v1
kind: ConfigMap
metadata:
name: {key}
namespace: kube-system
labels:
NAME: {name}
STATUS: {status}
OWNER: {owner}
VERSION: "{version}"
data:
release: {release}
""".format(key=release_info["key"],
name=configmap_label_name,
status=release_info["status"],
owner=release_info["owner"],
version=release_info["version"],
release=release_info["body"])
configmap_path = os.path.join("/tmp", configmap_label_name + ".yaml")
with open(configmap_path, "w") as f:
f.write(configmap)
cmd = "kubectl --kubeconfig=/etc/kubernetes/admin.conf apply -f {}" \
.format(configmap_path)
execute_command(cmd)
print("Configmap {} created".format(configmap_label_name))
os.remove(configmap_path)
def helm2to3_migrate(release_name):
cmd = "helm 2to3 convert --kubeconfig=/etc/kubernetes/admin.conf \
--tiller-out-cluster -s configmaps {}" \
.format(release_name)
execute_command(cmd)
print("Migrated {} to helm3".format(release_name))
def cleanup_release(conn, release_name):
cmd = "helm 2to3 cleanup --kubeconfig=/etc/kubernetes/admin.conf --release-cleanup \
--tiller-out-cluster -s configmaps --skip-confirmation --name {}" \
.format(release_name)
execute_command(cmd)
with conn:
with conn.cursor() as cur:
cur.execute("delete from releases where name = %s",
(release_name,))
print("Cleaned up helm2 data for {}".format(release_name))
def execute_command(cmd):
sub = subprocess.Popen(cmd, shell=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = sub.communicate()
if sub.returncode != 0:
print("Command failed:\n %s\n%s\n%s" % (cmd, stdout, stderr))
raise Exception("Failed to execute command: %s" % cmd)
return stdout
if __name__ == "__main__":
main()