From df65d20e070d518cf85d961770ada72b5e5e168c Mon Sep 17 00:00:00 2001 From: Robert Church Date: Thu, 25 Apr 2019 12:03:34 -0400 Subject: [PATCH] Enable platform helm repo for RPM installed charts Add a new helm repository, 'stx-platform', designed to hold charts that need to be delivered as part of the basic platform. These charts will be installed via RPMs as part of install and patching. Update the existing stx-openstack armada application manifests to reference the new location of the existing 'starlingx' repo. The 'starlingx' repo will be renamed with a future commit to 'stx-apps'. Enable multiple repository support when generating helm overrides for the chart location. This updates both the puppet manifests and ansible playbook for initial and subsequent configuration scenarios. Change-Id: I0caaa878a6c6781d038b48b8caa2aa507ee9568a Depends-On: I4b1a3615a6bd5d0bdd834a1cdf27c05d5a1057a0 Depends-On: I096d5ac126efc97f9a0a0f54f1e02323d936281c Story: 2005424 Task: 30644 Signed-off-by: Robert Church --- .../stx-openstack-helm/centos/build_srpm.data | 2 +- .../manifests/manifest.yaml | 48 +++--- .../tasks/bringup_helm.yml | 123 ++++++++++----- .../bringup-essential-services/vars/main.yml | 6 +- .../src/modules/platform/manifests/helm.pp | 141 +++++++++++------- .../src/modules/platform/manifests/sm.pp | 6 +- sysinv/sysinv/centos/build_srpm.data | 2 +- sysinv/sysinv/sysinv/sysinv/cmd/helm.py | 4 +- .../sysinv/sysinv/conductor/kube_app.py | 46 +++++- sysinv/sysinv/sysinv/sysinv/helm/base.py | 8 +- sysinv/sysinv/sysinv/sysinv/helm/common.py | 4 + sysinv/sysinv/sysinv/sysinv/helm/helm.py | 68 +++++++-- 12 files changed, 307 insertions(+), 151 deletions(-) diff --git a/kubernetes/applications/stx-openstack/stx-openstack-helm/centos/build_srpm.data b/kubernetes/applications/stx-openstack/stx-openstack-helm/centos/build_srpm.data index d16f0452b6..38f9cdcbc1 100644 --- a/kubernetes/applications/stx-openstack/stx-openstack-helm/centos/build_srpm.data +++ b/kubernetes/applications/stx-openstack/stx-openstack-helm/centos/build_srpm.data @@ -1,3 +1,3 @@ SRC_DIR="stx-openstack-helm" COPY_LIST_TO_TAR="$PKG_BASE/../../../helm-charts/rbd-provisioner $PKG_BASE/../../../helm-charts/garbd $PKG_BASE/../../../helm-charts/ceph-pools-audit" -TIS_PATCH_VER=11 +TIS_PATCH_VER=12 diff --git a/kubernetes/applications/stx-openstack/stx-openstack-helm/stx-openstack-helm/manifests/manifest.yaml b/kubernetes/applications/stx-openstack/stx-openstack-helm/stx-openstack-helm/manifests/manifest.yaml index 578e6d5a37..8015934770 100644 --- a/kubernetes/applications/stx-openstack/stx-openstack-helm/stx-openstack-helm/manifests/manifest.yaml +++ b/kubernetes/applications/stx-openstack/stx-openstack-helm/stx-openstack-helm/manifests/manifest.yaml @@ -10,7 +10,7 @@ data: values: {} source: type: tar - location: http://172.17.0.1/helm_charts/helm-toolkit-0.1.0.tgz + location: http://172.17.0.1/helm_charts/starlingx/helm-toolkit-0.1.0.tgz subpath: helm-toolkit reference: master dependencies: [] @@ -54,7 +54,7 @@ data: default: requiredDuringSchedulingIgnoredDuringExecution source: type: tar - location: http://172.17.0.1/helm_charts/ingress-0.1.0.tgz + location: http://172.17.0.1/helm_charts/starlingx/ingress-0.1.0.tgz subpath: ingress reference: master dependencies: @@ -99,7 +99,7 @@ data: default: requiredDuringSchedulingIgnoredDuringExecution source: type: tar - location: http://172.17.0.1/helm_charts/ingress-0.1.0.tgz + location: http://172.17.0.1/helm_charts/starlingx/ingress-0.1.0.tgz subpath: ingress reference: master dependencies: @@ -128,7 +128,7 @@ data: app: rbd-provisioner source: type: tar - location: http://172.17.0.1/helm_charts/rbd-provisioner-0.1.0.tgz + location: http://172.17.0.1/helm_charts/starlingx/rbd-provisioner-0.1.0.tgz subpath: rbd-provisioner reference: master dependencies: @@ -157,7 +157,7 @@ data: app: osh-openstack-ceph-pools-audit source: type: tar - location: http://172.17.0.1/helm_charts/ceph-pools-audit-0.1.0.tgz + location: http://172.17.0.1/helm_charts/starlingx/ceph-pools-audit-0.1.0.tgz subpath: ceph-pools-audit reference: master dependencies: @@ -205,7 +205,7 @@ data: default: requiredDuringSchedulingIgnoredDuringExecution source: type: tar - location: http://172.17.0.1/helm_charts/mariadb-0.1.0.tgz + location: http://172.17.0.1/helm_charts/starlingx/mariadb-0.1.0.tgz subpath: mariadb dependencies: - helm-toolkit @@ -241,7 +241,7 @@ data: garbd: docker.io/starlingx/stx-mariadb:master-centos-stable-latest source: type: tar - location: http://172.17.0.1/helm_charts/garbd-0.1.0.tgz + location: http://172.17.0.1/helm_charts/starlingx/garbd-0.1.0.tgz subpath: garbd dependencies: - helm-toolkit @@ -280,7 +280,7 @@ data: enabled: false source: type: tar - location: http://172.17.0.1/helm_charts/memcached-0.1.0.tgz + location: http://172.17.0.1/helm_charts/starlingx/memcached-0.1.0.tgz subpath: memcached reference: master dependencies: @@ -340,7 +340,7 @@ data: size: 1Gi source: type: tar - location: http://172.17.0.1/helm_charts/rabbitmq-0.1.0.tgz + location: http://172.17.0.1/helm_charts/starlingx/rabbitmq-0.1.0.tgz subpath: rabbitmq reference: master dependencies: @@ -414,7 +414,7 @@ data: runAsUser: 0 source: type: tar - location: http://172.17.0.1/helm_charts/keystone-0.1.0.tgz + location: http://172.17.0.1/helm_charts/starlingx/keystone-0.1.0.tgz subpath: keystone reference: master dependencies: @@ -515,7 +515,7 @@ data: default: requiredDuringSchedulingIgnoredDuringExecution source: type: tar - location: http://172.17.0.1/helm_charts/barbican-0.1.0.tgz + location: http://172.17.0.1/helm_charts/starlingx/barbican-0.1.0.tgz subpath: barbican reference: master dependencies: @@ -580,7 +580,7 @@ data: default: requiredDuringSchedulingIgnoredDuringExecution source: type: tar - location: http://172.17.0.1/helm_charts/glance-0.1.0.tgz + location: http://172.17.0.1/helm_charts/starlingx/glance-0.1.0.tgz subpath: glance reference: master dependencies: @@ -661,7 +661,7 @@ data: storage: rbd source: type: tar - location: http://172.17.0.1/helm_charts/cinder-0.1.0.tgz + location: http://172.17.0.1/helm_charts/starlingx/cinder-0.1.0.tgz subpath: cinder reference: master dependencies: @@ -697,7 +697,7 @@ data: libvirt: docker.io/starlingx/stx-libvirt:master-centos-stable-latest source: type: tar - location: http://172.17.0.1/helm_charts/libvirt-0.1.0.tgz + location: http://172.17.0.1/helm_charts/starlingx/libvirt-0.1.0.tgz subpath: libvirt reference: master dependencies: @@ -733,7 +733,7 @@ data: node_selector_value: enabled source: type: tar - location: http://172.17.0.1/helm_charts/openvswitch-0.1.0.tgz + location: http://172.17.0.1/helm_charts/starlingx/openvswitch-0.1.0.tgz subpath: openvswitch reference: master dependencies: @@ -987,7 +987,7 @@ data: source: type: tar - location: http://172.17.0.1/helm_charts/nova-0.1.0.tgz + location: http://172.17.0.1/helm_charts/starlingx/nova-0.1.0.tgz subpath: nova reference: master dependencies: @@ -1027,7 +1027,7 @@ data: ks_endpoints: docker.io/starlingx/stx-heat:master-centos-stable-latest source: type: tar - location: http://172.17.0.1/helm_charts/nova-api-proxy-0.1.0.tgz + location: http://172.17.0.1/helm_charts/starlingx/nova-api-proxy-0.1.0.tgz subpath: nova-api-proxy reference: master dependencies: @@ -1233,7 +1233,7 @@ data: firewall_driver: openvswitch source: type: tar - location: http://172.17.0.1/helm_charts/neutron-0.1.0.tgz + location: http://172.17.0.1/helm_charts/starlingx/neutron-0.1.0.tgz subpath: neutron reference: master dependencies: @@ -1318,7 +1318,7 @@ data: default: requiredDuringSchedulingIgnoredDuringExecution source: type: tar - location: http://172.17.0.1/helm_charts/heat-0.1.0.tgz + location: http://172.17.0.1/helm_charts/starlingx/heat-0.1.0.tgz subpath: heat reference: master dependencies: @@ -1380,7 +1380,7 @@ data: cron: "35 */24 * * *" source: type: tar - location: http://172.17.0.1/helm_charts/aodh-0.1.0.tgz + location: http://172.17.0.1/helm_charts/starlingx/aodh-0.1.0.tgz subpath: aodh reference: master dependencies: @@ -1529,7 +1529,7 @@ data: default: memcached source: type: tar - location: http://172.17.0.1/helm_charts/gnocchi-0.1.0.tgz + location: http://172.17.0.1/helm_charts/starlingx/gnocchi-0.1.0.tgz subpath: gnocchi reference: master dependencies: @@ -1588,7 +1588,7 @@ data: cron: "10 * * * *" source: type: tar - location: http://172.17.0.1/helm_charts/panko-0.1.0.tgz + location: http://172.17.0.1/helm_charts/starlingx/panko-0.1.0.tgz subpath: panko reference: master dependencies: @@ -2116,7 +2116,7 @@ data: default: requiredDuringSchedulingIgnoredDuringExecution source: type: tar - location: http://172.17.0.1/helm_charts/ceilometer-0.1.0.tgz + location: http://172.17.0.1/helm_charts/starlingx/ceilometer-0.1.0.tgz subpath: ceilometer reference: master dependencies: @@ -2959,7 +2959,7 @@ data: {{- end }} source: type: tar - location: http://172.17.0.1/helm_charts/horizon-0.1.0.tgz + location: http://172.17.0.1/helm_charts/starlingx/horizon-0.1.0.tgz subpath: horizon reference: master dependencies: diff --git a/playbookconfig/playbookconfig/playbooks/bootstrap/roles/bringup-essential-services/tasks/bringup_helm.yml b/playbookconfig/playbookconfig/playbooks/bootstrap/roles/bringup-essential-services/tasks/bringup_helm.yml index 8936e21dd6..f02f096ee0 100644 --- a/playbookconfig/playbookconfig/playbooks/bootstrap/roles/bringup-essential-services/tasks/bringup_helm.yml +++ b/playbookconfig/playbookconfig/playbooks/bootstrap/roles/bringup-essential-services/tasks/bringup_helm.yml @@ -107,7 +107,7 @@ - "{{ tiller_img }}" - "{{ armada_img }}" -- name: Create source and target helm repos +- name: Create source and target helm bind directories file: path: "{{ item }}" state: directory @@ -115,8 +115,19 @@ group: root mode: 0755 with_items: - - "{{ source_helm_repo }}" - - "{{ target_helm_repo }}" + - "{{ source_helm_bind_dir }}" + - "{{ target_helm_bind_dir }}" + +- name: Create helm repository directories + file: + path: "{{ item }}" + state: directory + owner: www + group: root + mode: 0755 + with_items: + - "{{ source_helm_bind_dir }}/{{ helm_repo_name_apps }}" + - "{{ source_helm_bind_dir }}/{{ helm_repo_name_platform }}" - name: Create service account for Tiller command: > @@ -160,39 +171,12 @@ recurse: yes when: inventory_hostname != 'localhost' -- name: Restart lighttpd for Helm - systemd: - name: lighttpd - state: restarted - -- name: Generate Helm repo index on target - command: helm repo index {{ target_helm_repo }} +- name: Generate Helm repo indicies + command: helm repo index "{{ source_helm_bind_dir }}/{{ item }}" become_user: www - -- name: Add local StarlingX Helm repo (local host) - command: helm repo add starlingx http://127.0.0.1/helm_charts - become_user: wrsroot - environment: - KUBECONFIG: /etc/kubernetes/admin.conf - HOME: /home/wrsroot - when: inventory_hostname == 'localhost' - -# Workaround for helm repo add remotely -- block: - - name: Add StarlingX Helm repo (remote host) - command: helm repo add starlingx http://127.0.0.1/helm_charts - environment: - KUBECONFIG: /etc/kubernetes/admin.conf - HOME: /home/wrsroot - - - name: Change helm directory ownership to pick up newly generated files (remote host) - file: - dest: /home/wrsroot/.helm - owner: wrsroot - group: wrs - mode: 0755 - recurse: yes - when: inventory_hostname != 'localhost' + with_items: + - "{{ helm_repo_name_apps }}" + - "{{ helm_repo_name_platform }}" - name: Stop lighttpd systemd: @@ -203,12 +187,71 @@ # Systemd module does not support disabled state. Resort to command command: systemctl disable lighttpd -- name: Bind mount {{ target_helm_repo }} +- name: Bind mount on {{ target_helm_bind_dir }} # Due to deficiency of mount module, resort to command for now - command: mount -o bind -t ext4 {{ source_helm_repo }} {{ target_helm_repo }} + command: mount -o bind -t ext4 {{ source_helm_bind_dir }} {{ target_helm_bind_dir }} args: warn: false -- name: Generate Helm repo index on source - command: helm repo index {{ source_helm_repo }} - become_user: www +- name: Enable lighttpd + command: systemctl enable lighttpd + +- name: Restart lighttpd for Helm + systemd: + name: lighttpd + state: restarted + +- name: Add Helm repos (local host) + command: helm repo add "{{ item }}" "http://127.0.0.1:$PORT/helm_charts/{{ item }}" + become_user: wrsroot + environment: + KUBECONFIG: /etc/kubernetes/admin.conf + HOME: /home/wrsroot + PORT: 80 + with_items: + - "{{ helm_repo_name_apps }}" + - "{{ helm_repo_name_platform }}" + when: inventory_hostname == 'localhost' + +# Workaround for helm repo add remotely +- block: + - name: Add Helm repos (remote host) + command: helm repo add "{{ item }}" "http://127.0.0.1:$PORT/helm_charts/{{ item }}" + environment: + KUBECONFIG: /etc/kubernetes/admin.conf + HOME: /home/wrsroot + PORT: 80 + with_items: + - "{{ helm_repo_name_apps }}" + - "{{ helm_repo_name_platform }}" + + - name: Change helm directory ownership to pick up newly generated files (remote host) + file: + dest: /home/wrsroot/.helm + owner: wrsroot + group: wrs + mode: 0755 + recurse: yes + when: inventory_hostname != 'localhost' + +- name: Update info of available charts locally from chart repos + command: helm repo update + become_user: wrsroot + when: inventory_hostname == 'localhost' + +# Workaround for helm update remotely. Not sure why the task cannot be executed +# successfully as wrsroot on remote host. +- block: + - name: Update info of available charts locally from chart repos (remote host) + command: helm repo update + environment: + HOME: /home/wrsroot + + - name: Change helm directory ownership (remote host) + file: + dest: /home/wrsroot/.helm + owner: wrsroot + group: wrs + mode: 0755 + recurse: yes + when: inventory_hostname != 'localhost' diff --git a/playbookconfig/playbookconfig/playbooks/bootstrap/roles/bringup-essential-services/vars/main.yml b/playbookconfig/playbookconfig/playbooks/bootstrap/roles/bringup-essential-services/vars/main.yml index 73bfb10d0a..89070141e6 100644 --- a/playbookconfig/playbookconfig/playbooks/bootstrap/roles/bringup-essential-services/vars/main.yml +++ b/playbookconfig/playbookconfig/playbooks/bootstrap/roles/bringup-essential-services/vars/main.yml @@ -1,8 +1,10 @@ --- tiller_img: gcr.io/kubernetes-helm/tiller:v2.13.1 armada_img: quay.io/airshipit/armada:af8a9ffd0873c2fbc915794e235dbd357f2adab1 -source_helm_repo: /opt/cgcs/helm_charts -target_helm_repo: /www/pages/helm_charts +source_helm_bind_dir: /opt/cgcs/helm_charts +target_helm_bind_dir: /www/pages/helm_charts +helm_repo_name_apps: starlingx +helm_repo_name_platform: stx-platform kube_admin_yaml_template: /usr/share/puppet/modules/platform/templates/kubeadm.yaml.erb multus_yaml_template: /usr/share/puppet/modules/platform/templates/multus.yaml.erb calico_yaml_template: /usr/share/puppet/modules/platform/templates/calico.yaml.erb diff --git a/puppet-manifests/src/modules/platform/manifests/helm.pp b/puppet-manifests/src/modules/platform/manifests/helm.pp index 5ef9b2965f..c42adf7f60 100644 --- a/puppet-manifests/src/modules/platform/manifests/helm.pp +++ b/puppet-manifests/src/modules/platform/manifests/helm.pp @@ -1,23 +1,93 @@ -class platform::helm::repository::params( - $source_helm_repo_dir = '/opt/cgcs/helm_charts', - $target_helm_repo_dir = '/www/pages/helm_charts', +class platform::helm::repositories::params( + $source_helm_repos_base_dir = '/opt/cgcs/helm_charts', + $target_helm_repos_base_dir = '/www/pages/helm_charts', + $helm_repositories = [ 'stx-platform', 'starlingx' ], ) {} +define platform::helm::repository ( + $repo_base = undef, + $repo_port = undef, + $create = false, + $primary = false, +) { + + $repo_path = "${repo_base}/${name}" + + if str2bool($create) { + file {$repo_path: + ensure => directory, + path => $repo_path, + owner => 'www', + require => User['www'], + } + + -> exec { "Generate index: ${repo_path}": + command => "helm repo index ${repo_path}", + logoutput => true, + user => 'www', + group => 'www', + require => User['www'], + } + + $before_relationship = Exec['Stop lighttpd'] + $require_relationship = [ User['wrsroot'], Exec["Generate index: ${repo_path}"] ] + } else { + $before_relationship = undef + $require_relationship = User['wrsroot'] + } + + exec { "Adding StarlingX helm repo: ${name}": + before => $before_relationship, + environment => [ 'KUBECONFIG=/etc/kubernetes/admin.conf' , 'HOME=/home/wrsroot'], + command => "helm repo add ${name} http://127.0.0.1:${repo_port}/helm_charts/${name}", + logoutput => true, + user => 'wrsroot', + group => 'wrs', + require => $require_relationship + } +} + +class platform::helm::repositories + inherits ::platform::helm::repositories::params { + include ::openstack::horizon::params + include ::platform::users + + Anchor['platform::services'] + + -> platform::helm::repository { $helm_repositories: + repo_base => $target_helm_repos_base_dir, + repo_port => $::openstack::horizon::params::http_port, + create => $::is_initial_config, + primary => $::is_initial_config_primary, + } + + -> exec { 'Updating info of available charts locally from chart repo': + environment => [ 'KUBECONFIG=/etc/kubernetes/admin.conf', 'HOME=/home/wrsroot' ], + command => 'helm repo update', + logoutput => true, + user => 'wrsroot', + group => 'wrs', + require => User['wrsroot'] + } +} + class platform::helm - inherits ::platform::helm::repository::params { + inherits ::platform::helm::repositories::params { include ::platform::docker::params - file {$source_helm_repo_dir: + file {$target_helm_repos_base_dir: ensure => directory, - path => $source_helm_repo_dir, + path => $target_helm_repos_base_dir, owner => 'www', require => User['www'] } - -> file {$target_helm_repo_dir: + Drbd::Resource <| |> + + -> file {$source_helm_repos_base_dir: ensure => directory, - path => $target_helm_repo_dir, + path => $source_helm_repos_base_dir, owner => 'www', require => User['www'] } @@ -70,18 +140,9 @@ class platform::helm require => User['wrsroot'] } - exec { "bind mount ${target_helm_repo_dir}": - command => "mount -o bind -t ext4 ${source_helm_repo_dir} ${target_helm_repo_dir}", - require => Exec['add local starlingx helm repo'] - } - # it needs to create the index file after the bind mount, otherwise - # helm repo could not be updated until application-upload adds index - -> exec { 'generate helm repo index on source': - command => "helm repo index ${source_helm_repo_dir}", - logoutput => true, - user => 'www', - group => 'www', - require => User['www'] + exec { "bind mount ${target_helm_repos_base_dir}": + command => "mount -o bind -t ext4 ${source_helm_repos_base_dir} ${target_helm_repos_base_dir}", + require => File[ $source_helm_repos_base_dir, $target_helm_repos_base_dir ] } } else { @@ -98,47 +159,21 @@ class platform::helm } } + include ::platform::helm::repositories include ::openstack::horizon::params $port = $::openstack::horizon::params::http_port + exec { 'restart lighttpd for helm': - require => [File['/etc/lighttpd/lighttpd.conf', $target_helm_repo_dir], Exec['initialize helm']], + require => [File['/etc/lighttpd/lighttpd.conf', $target_helm_repos_base_dir, $source_helm_repos_base_dir], + Exec['initialize helm']], command => 'systemctl restart lighttpd.service', logoutput => true, } - -> exec { 'generate helm repo index on target': - command => "helm repo index ${target_helm_repo_dir}", - logoutput => true, - user => 'www', - group => 'www', - require => User['www'] - } - - -> exec { 'add local starlingx helm repo': - before => Exec['Stop lighttpd'], - environment => [ 'KUBECONFIG=/etc/kubernetes/admin.conf' , 'HOME=/home/wrsroot'], - command => "helm repo add starlingx http://127.0.0.1:${port}/helm_charts", - logoutput => true, - user => 'wrsroot', - group => 'wrs', - require => User['wrsroot'] - } + -> Class['::platform::helm::repositories'] } } -class platform::helm::runtime -{ - include ::platform::users - - include ::openstack::horizon::params - $port = $::openstack::horizon::params::http_port - - exec { 'update local starlingx helm repo': - environment => [ 'KUBECONFIG=/etc/kubernetes/admin.conf' , 'HOME=/home/wrsroot'], - command => "helm repo add starlingx http://127.0.0.1:${port}/helm_charts", - logoutput => true, - user => 'wrsroot', - group => 'wrs', - require => User['wrsroot'] - } +class platform::helm::runtime { + include ::platform::helm::repositories } diff --git a/puppet-manifests/src/modules/platform/manifests/sm.pp b/puppet-manifests/src/modules/platform/manifests/sm.pp index 6b63c0e057..a80ed24da1 100644 --- a/puppet-manifests/src/modules/platform/manifests/sm.pp +++ b/puppet-manifests/src/modules/platform/manifests/sm.pp @@ -82,9 +82,9 @@ class platform::sm $dockerdistribution_fs_device = $::platform::drbd::dockerdistribution::params::device $dockerdistribution_fs_directory = $::platform::drbd::dockerdistribution::params::mountpoint - include ::platform::helm::repository::params - $helmrepo_fs_source_dir = $::platform::helm::repository::params::source_helm_repo_dir - $helmrepo_fs_target_dir = $::platform::helm::repository::params::target_helm_repo_dir + include ::platform::helm::repositories::params + $helmrepo_fs_source_dir = $::platform::helm::repositories::params::source_helm_repos_base_dir + $helmrepo_fs_target_dir = $::platform::helm::repositories::params::target_helm_repos_base_dir include ::platform::drbd::cephmon::params $cephmon_drbd_resource = $::platform::drbd::cephmon::params::resource_name diff --git a/sysinv/sysinv/centos/build_srpm.data b/sysinv/sysinv/centos/build_srpm.data index d443276ca0..e25835b3c5 100644 --- a/sysinv/sysinv/centos/build_srpm.data +++ b/sysinv/sysinv/centos/build_srpm.data @@ -1,2 +1,2 @@ SRC_DIR="sysinv" -TIS_PATCH_VER=312 +TIS_PATCH_VER=313 diff --git a/sysinv/sysinv/sysinv/sysinv/cmd/helm.py b/sysinv/sysinv/sysinv/sysinv/cmd/helm.py index 1d263cbb62..14017ba9ac 100644 --- a/sysinv/sysinv/sysinv/sysinv/cmd/helm.py +++ b/sysinv/sysinv/sysinv/sysinv/cmd/helm.py @@ -30,7 +30,9 @@ def create_armada_app_overrides_action(path, app_name=None, namespace=None): dbapi = api.get_instance() operator = helm.HelmOperator(dbapi=dbapi, path=path) operator.generate_helm_application_overrides(app_name, mode=None, cnamespace=namespace, - armada_format=True) + armada_format=True, + armada_chart_info=None, + combined=False) def create_chart_override_action(path, chart_name=None, namespace=None): diff --git a/sysinv/sysinv/sysinv/sysinv/conductor/kube_app.py b/sysinv/sysinv/sysinv/sysinv/conductor/kube_app.py index 362a529025..eccacbf656 100644 --- a/sysinv/sysinv/sysinv/sysinv/conductor/kube_app.py +++ b/sysinv/sysinv/sysinv/sysinv/conductor/kube_app.py @@ -115,7 +115,7 @@ def get_local_docker_registry_auth(): password=registry_password) -Chart = namedtuple('Chart', 'name namespace') +Chart = namedtuple('Chart', 'name namespace location') class AppOperator(object): @@ -439,9 +439,10 @@ class AppOperator(object): # so it can be sync'ed. if app.system_app: LOG.info("Generating application overrides...") - self._helm.generate_helm_application_overrides( - app.name, mode=None, cnamespace=None, armada_format=True, combined=True) app.charts = self._get_list_of_charts(app.armada_mfile_abs) + self._helm.generate_helm_application_overrides( + app.name, mode=None, cnamespace=None, armada_format=True, + armada_chart_info=app.charts, combined=True) self._save_images_list_by_charts(app) # Get the list of images from the updated images overrides images_to_download = self._get_image_tags_by_charts( @@ -555,6 +556,29 @@ class AppOperator(object): raise exception.KubeAppUploadFailure( name=app.name, version=app.version, reason="one or more charts failed validation.") + def _get_helm_repo_from_metadata(self, app): + """Get helm repo from application metadata + + This extracts the helm repo from the application metadata where the + chart should be loaded. + + :param app: application + """ + repo = common.HELM_REPO_FOR_APPS + lfile = os.path.join(app.path, 'metadata.yaml') + + if os.path.exists(lfile) and os.path.getsize(lfile) > 0: + with open(lfile, 'r') as f: + try: + y = yaml.safe_load(f) + repo = y['helm_repo'] + except KeyError: + pass + + LOG.info("Application %s will load charts to chart repo %s" % ( + app.name, repo)) + return repo + def _upload_helm_charts(self, app): # Set env path for helm-upload execution env = os.environ.copy() @@ -563,14 +587,15 @@ class AppOperator(object): for r, f in cutils.get_files_matching(app.charts_dir, '.tgz')] orig_uid, orig_gid = get_app_install_root_path_ownership() + helm_repo = self._get_helm_repo_from_metadata(app) try: # Temporarily change /scratch group ownership to wrs_protected os.chown(constants.APP_INSTALL_ROOT_PATH, orig_uid, grp.getgrnam(constants.SYSINV_WRS_GRPNAME).gr_gid) with open(os.devnull, "w") as fnull: for chart in charts: - subprocess.check_call(['helm-upload', chart], env=env, - stdout=fnull, stderr=fnull) + subprocess.check_call(['helm-upload', helm_repo, chart], + env=env, stdout=fnull, stderr=fnull) LOG.info("Helm chart %s uploaded" % os.path.basename(chart)) except Exception as e: raise exception.KubeAppUploadFailure( @@ -748,7 +773,14 @@ class AppOperator(object): if "armada/Chart/" in doc['schema']: charts.append(Chart( name=doc['data']['chart_name'], - namespace=doc['data']['namespace'])) + namespace=doc['data']['namespace'], + location=doc['data']['source']['location'])) + LOG.debug("Manifest: Chart: {} Namespace: {} " + "Location: {}".format( + doc['data']['chart_name'], + doc['data']['namespace'], + doc['data']['source']['location'])) + except KeyError: pass return charts @@ -987,7 +1019,7 @@ class AppOperator(object): LOG.info("Generating application overrides...") self._helm.generate_helm_application_overrides( app.name, mode, cnamespace=None, armada_format=True, - combined=True) + armada_chart_info=app.charts, combined=True) overrides_files = self._get_overrides_files(app.charts, app.name, mode) if overrides_files: LOG.info("Application overrides generated.") diff --git a/sysinv/sysinv/sysinv/sysinv/helm/base.py b/sysinv/sysinv/sysinv/sysinv/helm/base.py index 5ca54a29e2..a387a6e70e 100644 --- a/sysinv/sysinv/sysinv/sysinv/helm/base.py +++ b/sysinv/sysinv/sysinv/sysinv/helm/base.py @@ -47,9 +47,11 @@ class BaseHelm(object): def quoted_str(value): return quoted_str(value) - def get_chart_location(self, chart_name): - return 'http://controller:%s/helm_charts/%s-0.1.0.tgz' % ( - utils.get_http_port(self.dbapi), chart_name) + def get_chart_location(self, chart_name, repo_name): + if repo_name is None: + repo_name = common.HELM_REPO_FOR_APPS + return 'http://controller:{}/helm_charts/{}/{}-0.1.0.tgz'.format( + utils.get_http_port(self.dbapi), repo_name, chart_name) @staticmethod def _generate_random_password(length=16): diff --git a/sysinv/sysinv/sysinv/sysinv/helm/common.py b/sysinv/sysinv/sysinv/sysinv/helm/common.py index 1bfec2818d..c8d89d73a8 100644 --- a/sysinv/sysinv/sysinv/sysinv/helm/common.py +++ b/sysinv/sysinv/sysinv/sysinv/helm/common.py @@ -17,6 +17,10 @@ LOG = logging.getLogger(__name__) HELM_OVERRIDES_PATH = os.path.join(tsconfig.PLATFORM_PATH, 'helm', tsconfig.SW_VERSION) +# Supported chart repositories +HELM_REPO_FOR_APPS = 'starlingx' +HELM_REPO_FOR_PLATFORM = 'stx-platform' + # Namespaces HELM_NS_CEPH = 'ceph' HELM_NS_DEFAULT = 'default' diff --git a/sysinv/sysinv/sysinv/sysinv/helm/helm.py b/sysinv/sysinv/sysinv/sysinv/helm/helm.py index 53f23df2dd..47d2ee3205 100644 --- a/sysinv/sysinv/sysinv/sysinv/helm/helm.py +++ b/sysinv/sysinv/sysinv/sysinv/helm/helm.py @@ -10,6 +10,7 @@ from __future__ import absolute_import import eventlet import os +import re import subprocess import tempfile import yaml @@ -231,7 +232,7 @@ class HelmOperator(object): LOG.info(e) return overrides - def _get_helm_chart_location(self, chart_name): + def _get_helm_chart_location(self, chart_name, repo_name): """Get supported chart location. This method returns the download location for a given chart. @@ -241,10 +242,11 @@ class HelmOperator(object): """ if chart_name in self.chart_operators: return self.chart_operators[chart_name].get_chart_location( - chart_name) + chart_name, repo_name) return None - def _add_armada_override_header(self, chart_name, namespace, overrides): + def _add_armada_override_header(self, chart_name, repo_name, namespace, + overrides): use_chart_name_only = [common.HELM_NS_HELM_TOOLKIT] if namespace in use_chart_name_only: name = chart_name @@ -260,7 +262,7 @@ class HelmOperator(object): 'values': overrides } } - location = self._get_helm_chart_location(chart_name) + location = self._get_helm_chart_location(chart_name, repo_name) if location: new_overrides['data'].update({ 'source': { @@ -269,6 +271,32 @@ class HelmOperator(object): }) return new_overrides + def _get_repo_from_armada_chart_info(self, chart_name, chart_info_list): + """ Extract the repo from the armada manifest chart location. + + :param chart_name: name of the chart from the (application list) + :param chart_info_list: a list of chart objects containing information + extracted from the armada manifest + :returns: the supported StarlingX repository or None if not present + """ + + # Could be called without any armada_manifest info. Returning 'None' + # will enable helm defaults to point to common.HELM_REPO_FOR_APPS + repo = None + if chart_info_list is None: + return repo + + location = next( + (c.location for c in chart_info_list if c.name == chart_name), + None) + + if location: + match = re.search('/helm_charts/(.*)/', location) + if match: + repo = match.group(1) + LOG.debug("Chart %s can be found in repo: %s" % (chart_name, repo)) + return repo + def merge_overrides(self, file_overrides=[], set_overrides=[]): """ Merge helm overrides together. @@ -381,6 +409,7 @@ class HelmOperator(object): def generate_helm_application_overrides(self, app_name, mode=None, cnamespace=None, armada_format=False, + armada_chart_info=None, combined=False): """Create the system overrides files for a supported application @@ -390,13 +419,16 @@ class HelmOperator(object): be written.. :param app_name: name of the bundle of charts required to support an - application + application :param mode: mode to control how to apply application manifest :param cnamespace: (optional) namespace :param armada_format: (optional) whether to emit in armada format - instead of helm format (with extra header) + instead of helm format (with extra header) + :param armada_chart_info: (optional) supporting chart information + extracted from the armada manifest which is used to influence + overrides :param combined: (optional) whether to apply user overrides on top of - system overrides + system overrides """ if app_name in self.helm_applications: @@ -404,15 +436,16 @@ class HelmOperator(object): cnamespace) for (chart_name, overrides) in iteritems(app_overrides): if combined: - # The overrides at this point is the system overrides. For charts - # with multiple namespaces, the overrides would contain multiple keys, - # one for each namespace. + # The overrides at this point are the system overrides. For + # charts with multiple namespaces, the overrides would + # contain multiple keys, one for each namespace. # - # Retrieve the user overrides of each namespace from the database - # and merge this list of user overrides if exists with the - # system overrides. Both system and user overrides contents - # are then merged based on the namespace, prepended with required - # header and written to corresponding files (-.yaml). + # Retrieve the user overrides of each namespace from the + # database and merge this list of user overrides, if they + # exist, with the system overrides. Both system and user + # override contents are then merged based on the namespace, + # prepended with required header and written to + # corresponding files (-.yaml). file_overrides = [] for chart_namespace in overrides.keys(): try: @@ -438,8 +471,11 @@ class HelmOperator(object): # structure of the yaml file somewhat if armada_format: for key in overrides: + armada_chart_repo_name = self._get_repo_from_armada_chart_info( + chart_name, armada_chart_info) new_overrides = self._add_armada_override_header( - chart_name, key, overrides[key]) + chart_name, armada_chart_repo_name, + key, overrides[key]) overrides[key] = new_overrides self._write_chart_overrides(chart_name, cnamespace, overrides)