├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── ansible
├── config.j2.template
├── creds.j2.template
├── ocp-deployment-ansible-tower.yml
├── ocp-deployment.yml
├── roles
│ ├── build-images
│ │ └── tasks
│ │ │ └── main.yml
│ ├── copy-hdb-nfs
│ │ └── tasks
│ │ │ └── main.yml
│ ├── create-overlay-share
│ │ └── tasks
│ │ │ └── main.yml
│ ├── deploy-images
│ │ └── tasks
│ │ │ └── main.yml
│ ├── ocp-prerequisites
│ │ └── tasks
│ │ │ ├── generate_ocp_secret.yml
│ │ │ └── main.yml
│ ├── os-prerequisites
│ │ └── tasks
│ │ │ ├── check_connection_to_ocp4_cluster.yml
│ │ │ ├── check_oc_tool.yml
│ │ │ ├── gen-config-creds.yml
│ │ │ ├── main.yml
│ │ │ ├── verify_nfs_hdb_directories.yml
│ │ │ └── verify_nfs_server.yml
│ └── push-images
│ │ └── tasks
│ │ └── main.yml
├── tasks
│ ├── copy-git-repo.yml
│ ├── oc-admin-login.yml
│ ├── oc-user-login.yml
│ ├── rhel8.x-prerequisites.yml
│ ├── stop-deployment.yml
│ ├── wait_for_n_min.yml
│ ├── wait_for_pod_running.yml
│ └── wait_for_system_running.yml
└── vars
│ └── ocp-extra-vars.yml
├── config.yaml.template
├── creds.yaml.template
├── docs
├── ANSIBLE-TOWER.md
├── ANSIBLE.md
├── ARCHITECTURE.md
├── BUILDING-CLI.md
├── CLEANUP.md
├── HOWTO.md
├── PORTFORWARD.md
├── POWERVS.md
├── PREREQUISITES.md
├── QUICKSTART.md
├── SCENARIOS.md
├── TOOLS.md
├── VERIFYING-MANAGING.md
└── images
│ ├── ArchitecturalOverview.png
│ ├── BuildingImages.png
│ ├── PowerSystemsVirtualServers_1.png
│ ├── PowerSystemsVirtualServers_2.png
│ ├── PowerSystemsVirtualServers_3.png
│ ├── PowerSystemsVirtualServers_4.png
│ ├── PowerSystemsVirtualServers_5.png
│ ├── ansible_tower_add_new_job_template.png
│ ├── ansible_tower_projects_view.png
│ ├── howto
│ ├── hana_studio_1.png
│ ├── hana_studio_10.png
│ ├── hana_studio_11.png
│ ├── hana_studio_2.png
│ ├── hana_studio_3.png
│ ├── hana_studio_4.png
│ ├── hana_studio_5.png
│ ├── hana_studio_6.png
│ ├── hana_studio_7.png
│ ├── hana_studio_8.png
│ └── hana_studio_9.png
│ ├── ocp-haproxy-cleanup.png
│ ├── ocp-haproxy-forwarding.png
│ ├── ocp-port-forwarding.png
│ └── sshkeyscopy.png
├── openshift
├── deployment.yaml.template
├── images
│ ├── hdb
│ │ ├── containerfile.template
│ │ └── image-content
│ │ │ ├── hdblcm-config.template
│ │ │ ├── soos-start.sh
│ │ │ ├── soos-stop.sh
│ │ │ └── soos.service
│ ├── init
│ │ ├── containerfile
│ │ └── image-content
│ │ │ └── soos-create-envdir.sh
│ └── nws4
│ │ ├── containerfile.template
│ │ └── image-content
│ │ ├── soos-start.sh
│ │ ├── soos-stop.sh
│ │ └── soos.service
├── secret.yaml.template
└── service-nodeport.yaml.template
└── tools
├── codingstyle
├── config
├── containerize
├── creds
├── gpg-key-gen
├── image-build
├── image-push
├── modules
├── __init__.py
├── args.py
├── argsdoc.py
├── command.py
├── config.py
├── configbase.py
├── constants.py
├── containerize.py
├── context.py
├── creds.py
├── deployment.py
├── exceptions.py
├── fail.py
├── imagebuilder.py
├── logger.py
├── messages.py
├── nestedns.py
├── nfs-ping-test
├── nfstools.py
├── ocp.py
├── quantity.py
├── remotecopy.py
├── ssh.py
├── startup.py
├── table.py
├── times.py
├── tools.py
└── verify.py
├── nfs-hdb-copy
├── nfs-overlay-list
├── nfs-overlay-setup
├── nfs-overlay-teardown
├── ocp-container-login
├── ocp-container-run
├── ocp-deployment
├── ocp-etc-hosts
├── ocp-haproxy-forwarding
├── ocp-hdb-secret-gen
├── ocp-login
├── ocp-pod-meminfo
├── ocp-pod-status
├── ocp-port-forwarding
├── ocp-service-account-gen
├── sap-system-status
├── ssh-key-gen
├── ssh-keys
├── tool-shortcuts
├── venv-setup
├── verify-config
└── verify-ocp-settings
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 |
18 |
19 | # Contributing
20 |
21 | This document contains information on how to contribute code or
22 | documentation to our project.
23 |
24 |
25 |
26 | ## Contents
27 |
28 |
29 | Table of Contents
30 |
31 | - [Contributing in General](#contributing-in-general)
32 | - [Proposing new Features](#proposing-new-features)
33 | - [Fixing Bugs](#fixing-bugs)
34 | - [Merge Approval](#merge-approval)
35 | - [Legal](#legal)
36 | - [Communication](#communication)
37 | - [Setup](#setup)
38 | - [Coding Style Guidelines](#coding-style-guidelines)
39 |
40 |
41 |
42 |
43 |
44 | ## Contributing in General
45 |
46 | Our project welcomes external contributions.
47 |
48 | To contribute code or documentation, please submit a [pull
49 | request](https://github.com/IBM/containerization-for-sap-s4hana/pulls).
50 |
51 | A good way to familiarize yourself with the code base and contribution
52 | process is to look for and tackle low-hanging fruit in the [issue
53 | tracker](https://github.com/IBM/containerization-for-sap-s4hana/issues).
54 |
55 |
56 | **Note: We appreciate your effort, and want to avoid a situation where
57 | a contribution requires extensive rework (by you or by us), sits in
58 | backlog for a long time, or cannot be accepted at all!**
59 |
60 | ### Proposing new Features
61 |
62 | If you would like to implement a new feature, please [raise an
63 | issue](https://github.com/IBM/containerization-for-sap-s4hana/issues)
64 | before sending a pull request so the feature can be discussed. This is
65 | to avoid you wasting your valuable time working on a feature that the
66 | project developers are not interested in accepting into the code base.
67 |
68 | ### Fixing Bugs
69 |
70 | If you would like to fix a bug, please [raise an
71 | issue](https://github.com/IBM/containerization-for-sap-s4hana/issues)
72 | before sending a pull request so it can be tracked.
73 |
74 | ### Merge Approval
75 |
76 | The project maintainers use LGTM (Looks Good To Me) in comments on the
77 | code review to indicate acceptance. A change requires LGTMs from two
78 | of the maintainers of each component affected.
79 |
80 |
83 |
84 | ## Legal
85 |
86 | Each source file must include a license header for the Apache Software
87 | License 2.0. Using the SPDX format is the simplest approach. e.g.
88 |
89 | ```
90 | /*
91 | Copyright All Rights Reserved.
92 |
93 | SPDX-License-Identifier: Apache-2.0
94 | */
95 | ```
96 |
97 | We have tried to make it as easy as possible to make
98 | contributions. This applies to how we handle the legal aspects of
99 | contribution. We use [CLA assistant](https://cla-assistant.io/) which
100 | automatically asks you to sign the [Developer's Certificate of Origin
101 | 1.1
102 | (DCO)](https://gist.github.com/jridfe/cb9ed03deb37baa644e64eea3a327065)
103 | when you open a pull request. For more information see the description
104 | of a pull request workflow in [this
105 | gist](https://gist.github.com/reicolina/f30d7475157f3bf21ec6807a6caff85a).
106 |
107 | ## Communication
108 |
109 | Please feel free to connect with us by using our [issue
110 | tracker](https://github.com/IBM/containerization-for-sap-s4hana/issues).
111 |
112 | ## Setup
113 |
114 | Please refer to our [README.md](README.md) for setup instructions.
115 |
116 |
120 |
121 | ## Coding Style Guidelines
122 |
123 | Please use the [tools/codingstyle](tools/codingstyle) script to check
124 | whether your Python code adheres to our coding style guidelines.
125 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
18 |
19 | # Containerization by IBM for SAP S/4HANA with Red Hat OpenShift
20 |
21 | [](https://www.apache.org/licenses/LICENSE-2.0)
22 | [](https://cla-assistant.io/IBM/containerization-for-sap-s4hana)
23 |
24 | Build container images from existing SAP® NetWeaver® and SAP® S/4HANA®
25 | systems deployed on Linux®, and run them on a Red Hat® OpenShift®
26 | cluster. Options for the build process allow to invoke it either from
27 | command line, or automated using Red Hat Ansible® or Red Hat Ansible
28 | Tower®.
29 |
30 |
31 |
32 | ## Contents
33 |
34 |
35 | Table of Contents
36 |
37 | - [Introduction](#introduction)
38 | - [Important Note](#important-note)
39 | - [Documentation](#documentation)
40 | - [Contributors](#contributors)
41 | - [License](#license)
42 | - [Acknowledgments](#acknowledgments)
43 |
44 |
45 |
46 |
47 |
48 | ## Introduction
49 |
50 | This project provides assets for building container images of existing
51 | SAP® systems and for deploying containers based on the created images
52 | in Red Hat® OpenShift® Container Platform running on IBM® Power
53 | Systems™.
54 |
55 | ## Important Note
56 |
57 | **This release targets test and other non-production landscapes. The
58 | created deliverables are not supported by SAP nor
59 | agreed to a roadmap for official support in current state (see also
60 | SAP Note 1122387 - *Linux: SAP Support in virtualized environments*)**
61 |
62 | ## Documentation
63 |
64 | The various aspects of this project are described in the following
65 | documents:
66 |
67 | - [*Architecture*](docs/ARCHITECTURE.md)
68 |
69 | - [*Customer Scenarios*](docs/SCENARIOS.md)
70 |
71 | - [*Quickstart*](docs/QUICKSTART.md)
72 |
73 | - [*Prerequisites*](docs/PREREQUISITES.md)
74 |
75 | - Setup Red Hat OpenShift on IBM PowerVM servers managed using HMC
76 |
77 | - Complete automated setup, see external project [*Red Hat OpenShift on IBM PowerVM servers managed using HMC*](https://github.com/ocp-power-automation/ocp4-upi-powervm-hmc) or
78 |
79 | - Complete setup with some manual steps, see external project [*Helper Node Quickstart Install*](https://github.com/redhat-cop/ocp4-helpernode/blob/main/docs/quickstart-powervm.md)
80 |
81 | - [*Containerization for SAP S/4HANA with Red Hat OpenShift on IBM Power Systems Virtual Servers*](docs/POWERVS.md#containerization-for-sap-s4hana-with-red-hat-openshift-on-ibm-power-systems-virtual-server)
82 |
83 | - Build and deployment options
84 |
85 | - [*Building Images and Starting Deployments from the Command
86 | Line*](docs/BUILDING-CLI.md)
87 |
88 | In addition, see [*Tools*](docs/TOOLS.md) about the
89 | available tools and their options.
90 |
91 | - [*Building Images and Starting Deployments with Red Hat®
92 | Ansible®*](docs/ANSIBLE.md)
93 |
94 | - [*Building Images and Starting Deployments with Red Hat® Ansible
95 | Tower®*](docs/ANSIBLE-TOWER.md)
96 |
97 | - [*Verifying and Managing the Deployment*](docs/VERIFYING-MANAGING.md)
98 |
99 | - How To
100 |
101 | - [*Introducing Options for End-User GUI Access to the Containerized Systems*](docs/PORTFORWARD.md#introducing-options-for-end-user-gui-access-to-the-containerized-systems).
102 |
103 | - [*Connecting to the SAP® S/4HANA® Database using SAP HANA
104 | Studio®*](docs/HOWTO.md#connecting-to-the-sap-s4hana-database-using-sap-hana-studio)
105 |
106 | - [*Cleaning up the Environment*](docs/CLEANUP.md#cleaning-up-the-environment)
107 |
108 | - Please refer also to this [IBM®
109 | Redpaper™](http://www.redbooks.ibm.com/Redbooks.nsf/RedpieceAbstracts/redp5619.html?Open)
110 | for more information on how to setup the required environment.
111 |
112 | ## Contributors
113 |
114 | See the list of
115 | [contributors](https://github.com/IBM/containerization-for-sap-s4hana/graphs/contributors)
116 | who participated in this project.
117 |
118 | ## License
119 |
120 | This project is licensed under the Apache 2 License - see the
121 | [LICENSE](LICENSE) file for details.
122 |
123 | ## Acknowledgments
124 |
125 | Thanks to all the people who contributed to all the amazing open
126 | source tools that made this project possible.
127 |
--------------------------------------------------------------------------------
/ansible/config.j2.template:
--------------------------------------------------------------------------------
1 | # ------------------------------------------------------------------------
2 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | # ------------------------------------------------------------------------
16 |
17 | build:
18 | description: Build machine
19 | repo:
20 | description: Github repository 'https://github.com/IBM/containerization-for-sap-s4hana'
21 | root:
22 | description: Path to the root directory of the repository clone
23 | on the build machine
24 | required: true
25 | value: '{{ path_to_ocp_tool }}'
26 |
27 | refsys:
28 | description: Reference SAP NetWeaver or SAP S/4HANA system
29 | nws4:
30 | description: ASCS and Dialog instance
31 | sid:
32 | description: SAP system ID
33 | required: true
34 | value: '{{ nws4_sid | upper }}'
35 |
36 | host:
37 | description: Host on which the system is installed
38 | name:
39 | description: Name of the host
40 | required: true
41 | value: '{{ nws4_host_name }}'
42 |
43 | ocp:
44 | description: OpenShift Container Platform (OCP) cluster
45 | project:
46 | description: Project under which the generated images
47 | are stored and the containers are started
48 | required: true
49 | value: '{{ ocp_project_name }}'
50 |
51 | domain:
52 | description: Cluster domain name (used for 'oc' operations)
53 | required: true
54 | value: '{{ ocp_cluster_domain }}'
55 |
56 | helper:
57 | description: Cluster helper node
58 | host:
59 | description: Host on which the helper node is installed
60 | name:
61 | description: Name of the host as seen in the intranet
62 | (*not* in the cluster network)
63 | required: true
64 | value: '{{ ocp_helper_node }}'
65 |
66 | containers:
67 | description: Container instances
68 | di:
69 | description: SAP dialog instance
70 | secret:
71 | description: Name of the OCP secret in which credentials
72 | of the SAP HANA database user (see creds.yaml)
73 | are stored for use within the Pod;
74 | *required* if the reference system is not a standard system
75 | required: false
76 | value: '{{ containers_di_secret }}'
77 |
78 | resources:
79 | requests:
80 | memory:
81 | description: Requested memory
82 | required: false
83 | value: '{{ containers_di_requests_memory }}'
84 | limits:
85 | memory:
86 | description: Memory limit; must be >= requested memory
87 | required: false
88 | value: '{{ containers_di_limits_memory }}'
89 |
90 | ascs:
91 | description: SAP ASCS instance
92 | resources:
93 | requests:
94 | memory:
95 | description: Requested memory
96 | required: true
97 | value: '{{ containers_ascs_requests_memory }}'
98 | limits:
99 | memory:
100 | description: Memory limit; must be >= requested memory
101 | required: true
102 | value: '{{ containers_ascs_limits_memory }}'
103 |
104 | hdb:
105 | description: SAP HANA instance
106 | resources:
107 | requests:
108 | memory:
109 | description: Requested memory; will be derived from the
110 | original database size if not supplied
111 | required: false
112 | value: '{{ containers_hdb_requests_memory }}'
113 | limits:
114 | memory:
115 | description: Memory limit; must be >= requested memory;
116 | will be derived from the original database
117 | size if not supplied
118 | required: false
119 | value: '{{ containers_hdb_limits_memory }}'
120 |
121 | nfs:
122 | description: NFS server
123 | host:
124 | description: Host on which the NFS server is running
125 | name:
126 | description: Name of host; if not specified
127 | ocp.helper.host.name is used
128 | required: false
129 | value: '{{ nfs_host_name }}'
130 |
131 | bases:
132 | description: Base directories
133 | copy:
134 | description: Path where directories {data,log} of the original
135 | SAP HANA system are copied to
136 | required: true
137 | value: '{{ nfs_path_to_hdb_copy }}'
138 |
139 | overlay:
140 | description: Path under which overlay file systems for container
141 | instances are created
142 | required: true
143 | value: '{{ nfs_path_to_overlay }}'
144 |
--------------------------------------------------------------------------------
/ansible/creds.j2.template:
--------------------------------------------------------------------------------
1 | # ------------------------------------------------------------------------
2 | # Copyright 2021, 2022 IBM Corp. All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | # ------------------------------------------------------------------------
16 |
17 | build:
18 | description: Build machine
19 | user:
20 | description: User on the build machine which is used for
21 | executing build, deploy and maintenance operations
22 | sshid:
23 | description: Absolute path to the private SSH ID file which is
24 | used for SSH connect operations from the build machine
25 | to remote systems
26 | required: false
27 | value: '{{ build_user_sshid }}'
28 |
29 | refsys:
30 | description: Reference SAP NetWeaver or SAP S/4HANA system
31 | nws4:
32 | description: ASCS and Dialog instance
33 | sidadm:
34 | description: adm-user
35 | name:
36 | description: Name
37 | required: true
38 | value: '{{ nws4_sidadm_name }}'
39 |
40 | password:
41 | description: Password
42 | required: false
43 | value: '{{ nws4_sidadm_password }}'
44 |
45 | hdbconnect:
46 | description: SAP HANA database user which is used by the
47 | Dialog instance to connect to the database;
48 | *required* if the reference system is not a
49 | standard system
50 | name:
51 | description: Name
52 | required: false
53 | value: '{{ nws4_hdbconnect_name }}'
54 |
55 | password:
56 | description: Password
57 | required: false
58 | value: '{{ nws4_hdbconnect_password }}'
59 |
60 | hdb:
61 | description: SAP HANA database instance
62 | sidadm:
63 | description: adm-user
64 | name:
65 | description: Name
66 | required: true
67 | value: '{{ hdb_sidadm_name }}'
68 |
69 | password:
70 | description: Password
71 | required: false
72 | value: '{{ hdb_sidadm_password }}'
73 |
74 | nfs:
75 | description: NFS server
76 | user:
77 | description: User on the NFS server which is used for accessing
78 | the NFS host via SSH (needs root permissions)
79 | name:
80 | description: Name
81 | required: true
82 | value: '{{ nfs_user_name }}'
83 |
84 | password:
85 | description: Password
86 | required: false
87 | value: '{{ nfs_user_password }}'
88 |
89 | ocp:
90 | description: OpenShift Container Platform (OCP) cluster
91 | user:
92 | description: OCP cluster user which is used for non-admin
93 | 'oc' operations
94 | name:
95 | description: Name
96 | required: true
97 | value: '{{ ocp_user_name }}'
98 |
99 | password:
100 | description: Password
101 | required: true
102 | value: '{{ ocp_user_password }}'
103 |
104 | admin:
105 | description: OCP cluster user which is used for admin
106 | 'oc' operations
107 | name:
108 | description: Name
109 | required: true
110 | value: '{{ ocp_admin_name }}'
111 |
112 | password:
113 | description: Password
114 | required: true
115 | value: '{{ ocp_admin_password }}'
116 |
117 | helper:
118 | description: Cluster helper node
119 | user:
120 | description: User on the OCP helper host which is used for accessing
121 | the helper host via SSH (needs root permissions)
122 |
123 | name:
124 | description: Name
125 | required: true
126 | value: '{{ ocp_helper_node_user_name }}'
127 |
128 | password:
129 | description: Password
130 | required: false
131 | value: '{{ ocp_helper_node_user_password }}'
132 |
133 | sshid:
134 | description: Absolute path to the private SSH ID file which is
135 | used for SSH connect operations from the OCP helper
136 | node to the OCP worker nodes
137 | required: false
138 | value: '{{ ocp_helper_node_user_sshid }}'
139 |
--------------------------------------------------------------------------------
/ansible/ocp-deployment-ansible-tower.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # ------------------------------------------------------------------------
3 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 | # ------------------------------------------------------------------------
17 | - hosts: all
18 | pre_tasks:
19 | - import_tasks: tasks/copy-git-repo.yml
20 | roles:
21 | - os-prerequisites
22 | - ocp-prerequisites
23 | - copy-hdb-nfs
24 | - build-images
25 | - push-images
26 | - create-overlay-share
27 | - deploy-images
28 |
29 |
--------------------------------------------------------------------------------
/ansible/ocp-deployment.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # ------------------------------------------------------------------------
3 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 | # ------------------------------------------------------------------------
17 | - hosts: all
18 | roles:
19 | - os-prerequisites
20 | - ocp-prerequisites
21 | - copy-hdb-nfs
22 | - build-images
23 | - push-images
24 | - create-overlay-share
25 | - deploy-images
26 |
--------------------------------------------------------------------------------
/ansible/roles/build-images/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # ------------------------------------------------------------------------
3 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 | # ------------------------------------------------------------------------
17 | - name: building INIT container image
18 | shell: "source {{path_to_ocp_tool}}/venv/bin/activate && cd {{path_to_ocp_tool}}/ansible && {{path_to_ocp_tool}}/tools/image-build -c {{path_to_ocp_tool}}/config.yaml -q {{path_to_ocp_tool}}/creds.yaml -f init -v {{ debug_level_ocp_tool }}"
19 | register: outmsg
20 | ignore_errors: true
21 | - name: cat result after building INIT container image
22 | shell: "cat {{path_to_ocp_tool}}/ansible/log/*"
23 | register: outmsg_init
24 | ignore_errors: true
25 | - name: show result after building INIT container image
26 | debug:
27 | var: outmsg_init.stdout_lines
28 | ignore_errors: true
29 | - name: show stderr when rc!=0 after building INIT container image
30 | fail:
31 | msg: "Building INIT container image failed"
32 | when: outmsg.rc != 0
33 | - name: delete old logs
34 | file:
35 | path: "{{ path_to_ocp_tool }}/ansible/log"
36 | state: absent
37 |
38 | - name: building NWS4 container image
39 | shell: "source {{path_to_ocp_tool}}/venv/bin/activate && cd {{path_to_ocp_tool}}/ansible && {{path_to_ocp_tool}}/tools/image-build -c {{path_to_ocp_tool}}/config.yaml -q {{path_to_ocp_tool}}/creds.yaml -f nws4 -v {{ debug_level_ocp_tool }}"
40 | register: outmsg
41 | ignore_errors: true
42 | - name: cat result after building NWS4 container image
43 | shell: "cat {{path_to_ocp_tool}}/ansible/log/*"
44 | register: outmsg_nws4
45 | ignore_errors: true
46 | - name: show result after building NWS4 container image
47 | debug:
48 | var: outmsg_nws4.stdout_lines
49 | ignore_errors: true
50 | - name: show stderr when rc!=0 after building NWS4 container image
51 | fail:
52 | msg: "Building NWS4 container image failed"
53 | when: outmsg.rc != 0
54 | - name: delete old logs
55 | file:
56 | path: "{{ path_to_ocp_tool }}/ansible/log"
57 | state: absent
58 |
59 | - name: building SAP HANA container image
60 | shell: "source {{path_to_ocp_tool}}/venv/bin/activate && cd {{path_to_ocp_tool}}/ansible && {{path_to_ocp_tool}}/tools/image-build -c {{path_to_ocp_tool}}/config.yaml -q {{path_to_ocp_tool}}/creds.yaml -f hdb -v {{ debug_level_ocp_tool }}"
61 | register: outmsg
62 | - name: cat result after building SAP HANA container image
63 | shell: "cat {{path_to_ocp_tool}}/ansible/log/*"
64 | register: outmsg_hdb
65 | ignore_errors: true
66 | - name: show result after building SAP HANA container image
67 | debug:
68 | var: outmsg_hdb.stdout_lines
69 | ignore_errors: true
70 | - name: show stderr when rc!=0 after building SAP HANA container image
71 | fail:
72 | msg: "Building SAP HANA container image failed"
73 | when: outmsg.rc != 0
74 | - name: delete old logs
75 | file:
76 | path: "{{ path_to_ocp_tool }}/ansible/log"
77 | state: absent
78 |
79 | - name: verify the images
80 | shell: "podman images soos"
81 | register: out_img
82 | - name: show image building result
83 | debug:
84 | var: out_img.stdout_lines
85 |
--------------------------------------------------------------------------------
/ansible/roles/copy-hdb-nfs/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # ------------------------------------------------------------------------
3 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 | # ------------------------------------------------------------------------
17 | - name: create a snapshot copy of the SAP HANA on the NFS server
18 | shell: "cd {{path_to_ocp_tool}} && source ./venv/bin/activate && ./tools/nfs-hdb-copy -c ./config.yaml -q ./creds.yaml -w"
19 | register: outmsg
20 | - name: show status of copy hdb
21 | debug: var=outmsg.stdout
22 |
--------------------------------------------------------------------------------
/ansible/roles/create-overlay-share/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # ------------------------------------------------------------------------
3 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 | # ------------------------------------------------------------------------
17 | - name: creating HANA DB overlay share on the NFS server
18 | shell: "cd {{path_to_ocp_tool}} && source ./venv/bin/activate && ./tools/nfs-overlay-setup -c ./config.yaml -q ./creds.yaml"
19 | register: uuid_status
20 | - debug: var=uuid_status.stdout
21 | - name: store uuid for the deployment file
22 | set_fact:
23 | overlay_share_name: "{{ uuid_status.stdout }}"
24 | uuid_value: "{{ uuid_status.stdout.split('-') | last }}"
25 |
--------------------------------------------------------------------------------
/ansible/roles/deploy-images/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # ------------------------------------------------------------------------
3 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 | # ------------------------------------------------------------------------
17 | - name: generating the deployment file using {{ overlay_share_name }}
18 | shell: "cd {{path_to_ocp_tool}} && source ./venv/bin/activate && ./tools/ocp-deployment --gen-yaml -c ./config.yaml -q ./creds.yaml -u {{ overlay_share_name }}"
19 | register: outmsg
20 | - debug: var=outmsg.stdout
21 | - set_fact:
22 | deployment_file: "soos-{{ nws4_sid | lower}}-{{ uuid_value }}-deployment.yaml"
23 | # start deployment
24 | - name: apply the deployment file {{ deployment_file }}
25 | shell: "cd {{path_to_ocp_tool}} && source ./venv/bin/activate && ./tools/ocp-deployment --start -f ./{{ deployment_file }} -c ./config.yaml -q ./creds.yaml "
26 | - import_tasks: ../../../tasks/wait_for_pod_running.yml
27 | - name: show pod mem info
28 | shell: "cd {{path_to_ocp_tool}} && source ./venv/bin/activate && ./tools/ocp-pod-meminfo -c ./config.yaml -q ./creds.yaml"
29 | register: out_msg
30 | - debug: var=out_msg
31 | - import_tasks: ../../../tasks/wait_for_system_running.yml
32 | - name: show SAP system status
33 | shell: "cd {{path_to_ocp_tool}} && source ./venv/bin/activate && ./tools/sap-system-status -c ./config.yaml -q ./creds.yaml -w"
34 | register: outmsg
35 | - debug: var=outmsg.stdout
36 |
--------------------------------------------------------------------------------
/ansible/roles/ocp-prerequisites/tasks/generate_ocp_secret.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # ------------------------------------------------------------------------
3 | # Copyright 2021, 2022 IBM Corp. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 | # ------------------------------------------------------------------------
17 |
18 | # generate ocp secret
19 | - name: show status of the secret name
20 | fail:
21 | msg: "secret name in the variable `containers_di_secret` must be defined"
22 | when: distributed_sap_system == 'yes' and containers_di_secret == ''
23 |
24 | - name: show status of the hdbconnect password
25 | fail:
26 | msg: "password in the variable `nws4_hdbconnect_password` must be defined"
27 | when: distributed_sap_system == 'yes' and nws4_hdbconnect_password == ''
28 |
29 | - name: show status of the hdbconnect name
30 | fail:
31 | msg: "password in the variable `nws4_hdbconnect_password` must be defined"
32 | when: distributed_sap_system == 'yes' and nws4_hdbconnect_name == ''
33 |
34 | - name: generate ocp secret if SAP HANA and SAP S/4HANA are distributed
35 | shell: "cd {{path_to_ocp_tool}} && source ./venv/bin/activate && ./tools/ocp-hdb-secret-gen -c ./config.yaml -q ./creds.yaml -w"
36 | register: outmsg
37 | when: distributed_sap_system == 'yes'
38 |
39 | - debug: var=outmsg
40 |
41 |
--------------------------------------------------------------------------------
/ansible/roles/ocp-prerequisites/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # ------------------------------------------------------------------------
3 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 | # ------------------------------------------------------------------------
17 |
18 | - import_tasks: ../../../tasks/oc-user-login.yml
19 |
20 | - name: "set oc_project: {{ ocp_project_name }}"
21 | set_fact:
22 | oc_project: "{{ ocp_project_name }}"
23 | - name: check if the project "{{ ocp_project_name }}" is already existing
24 | shell: "oc get projects"
25 | register: oc_all_projects
26 |
27 | - name: create a new project if "{{ ocp_project_name }}" does not exist
28 | shell: "oc new-project {{ocp_project_name}}"
29 | register: outmsg
30 | when: oc_project not in oc_all_projects.stdout
31 | - name: show new-project
32 | debug: var=outmsg
33 |
34 | - name: choose your project
35 | shell: "oc project {{ocp_project_name}}"
36 | - name: get service account
37 | shell: "oc get serviceaccount"
38 | register: outmsg
39 | - debug: var=outmsg.stdout
40 | when: outmsg.rc==0
41 | - debug:
42 | msg: "outmsg.stderr"
43 | failed_when: outmsg.rc != 0
44 |
45 | - import_tasks: ../../../tasks/oc-admin-login.yml
46 |
47 | - name: enable the Image Registry default route, patch the Image Registry Operator
48 | shell: "oc patch configs.imageregistry.operator.openshift.io/cluster --type merge -p '{\"spec\":{\"defaultRoute\":true}}'"
49 | register: r_msg
50 | - name: show Image Registry default route
51 | debug: var=r_msg
52 |
53 | - name: add permission
54 | shell: "oc adm policy add-scc-to-group anyuid 'system:serviceaccounts:{{ocp_project_name}}'"
55 | register: out_p
56 | - name: show permission settings
57 | debug: var=out_p.stdout
58 |
59 | - name: generate ocp service-account
60 | shell: "cd {{path_to_ocp_tool}} && source ./venv/bin/activate && ./tools/ocp-service-account-gen -c ./config.yaml -q ./creds.yaml -o {{path_to_ocp_tool}}/{{ocp_project_name}}-service-account.yaml -w"
61 | register: out_b
62 | - name: show output after generating oc service account
63 | debug: var=out_b.stdout
64 |
65 | - import_tasks: ../../../tasks/oc-admin-login.yml
66 |
67 | - name: add the required security context constraints to the service account
68 | shell: "oc adm policy add-scc-to-user hostmount-anyuid system:serviceaccount:{{ocp_project_name}}:{{ocp_project_name}}-sa"
69 | register: out_msg
70 | - name: show result after add-scc-to-user
71 | debug: var=out_msg
72 |
73 | # generate secret for Distributed Reference System after OCP project is checked, created
74 | - import_tasks: generate_ocp_secret.yml
75 |
76 | - name: verify configuration settings of config.yaml and creds.yaml
77 | shell: "source {{path_to_ocp_tool}}/venv/bin/activate && {{ path_to_ocp_tool }}/tools/verify-config -c {{ path_to_ocp_tool }}/config.yaml -q {{ path_to_ocp_tool }}/creds.yaml -w"
78 | register: result_msg
79 | ignore_errors: true
80 | - debug: var=result_msg.stdout_lines
81 | - name: check missing verify configuration parameters
82 | debug: var=result_msg.stderr_lines
83 | failed_when: result_msg.rc != 0
84 | when: result_msg.rc != 0
85 |
86 | # Checking security context constraints, checking worker nodes
87 | - name: verify ocp settings
88 | shell: "cd {{path_to_ocp_tool}} && source ./venv/bin/activate && ./tools/verify-ocp-settings -c ./config.yaml -q ./creds.yaml -w"
89 | register: outmsg
90 | ignore_errors: true
91 | - debug: var=outmsg.stdout_lines
92 | - name: check missing verify ocp settings
93 | debug: var=outmsg.stderr_lines
94 | failed_when: outmsg.rc != 0
95 | when: outmsg.rc != 0
96 |
--------------------------------------------------------------------------------
/ansible/roles/os-prerequisites/tasks/check_connection_to_ocp4_cluster.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # ------------------------------------------------------------------------
3 | # Copyright 2021, 2022 IBM Corp. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 | # ------------------------------------------------------------------------
17 |
18 | # check connection to OCP4 cluster
19 | - name: check connection to api.{{ ocp_cluster_domain }} hostname
20 | shell: "ssh -o StrictHostKeyChecking=no root@api.{{ ocp_cluster_domain }} ls"
21 | register: outmsg_api
22 | ignore_errors: true
23 | - name: check connection to oauth-openshift.apps.{{ ocp_cluster_domain }} hostname
24 | shell: "ssh -o StrictHostKeyChecking=no root@oauth-openshift.apps.{{ ocp_cluster_domain }} ls"
25 | register: outmsg_oauth
26 | ignore_errors: true
27 | - name: check connection to default-route-openshift-image-registry.apps.{{ ocp_cluster_domain }} hostname
28 | shell: "ssh -o StrictHostKeyChecking=no root@default-route-openshift-image-registry.apps.{{ ocp_cluster_domain }} ls"
29 | register: outmsg_route
30 | ignore_errors: true
31 | - name: show status of checking connection to OCP4 cluster
32 | fail:
33 | msg: "Insert the ` api. oauth-openshift.apps. default-route-openshift-image-registry.apps.` into the /etc/hosts file on your build LPAR. Check that password-less access is possible for user root to these hosts."
34 | when: outmsg_api.rc != 0 or outmsg_oauth.rc != 0 or outmsg_route.rc != 0
35 |
36 |
--------------------------------------------------------------------------------
/ansible/roles/os-prerequisites/tasks/check_oc_tool.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # ------------------------------------------------------------------------
3 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 | # ------------------------------------------------------------------------
17 |
18 | # check if oc tool is installed and copy it from helper node if not installed
19 | - name: verify local oc tool
20 | command: which oc
21 | ignore_errors: true
22 | register: outmsg
23 | - name: verify oc tool on the OCP4 helper node "{{ ocp_cluster_domain }}"
24 | command: ssh -o StrictHostKeyChecking=no root@api.{{ ocp_cluster_domain }} "which oc"
25 | register: outmsg_helper
26 | ignore_errors: true
27 | when: outmsg.rc !=0
28 | - name: copy oc tool from OCP4 helper node to build LPAR
29 | command: scp -o StrictHostKeyChecking=no root@api.{{ ocp_cluster_domain }}:{{ outmsg_helper.stdout }} {{ outmsg_helper.stdout }}
30 | register: outmsg_scp
31 | when: outmsg.rc != 0 and outmsg_helper is defined and outmsg_helper.rc == 0
32 | - name: check if oc tool is installed
33 | debug: msg="{{ outmsg_scp.stderr }}"
34 | failed_when: outmsg_scp.rc != 0
35 | when: outmsg_scp.stderr is defined and outmsg_scp.rc != 0
36 |
37 |
--------------------------------------------------------------------------------
/ansible/roles/os-prerequisites/tasks/gen-config-creds.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # ------------------------------------------------------------------------
3 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 | # ------------------------------------------------------------------------
17 | - name: generate config.yaml
18 | template:
19 | #source directory of config.j2.template
20 | src: "{{ template_config_file }}"
21 | dest: "{{ path_to_ocp_tool }}/config.yaml"
22 | register: out_msg
23 | - name: show result
24 | debug: var=out_msg
25 |
26 | - name: generate creds.yaml
27 | template:
28 | #source directory of creds.j2.template
29 | src: "{{ template_creds_file }}"
30 | dest: "{{ path_to_ocp_tool }}/creds.yaml"
31 | register: out_msg
32 | - name: show result
33 | debug: var=out_msg
34 |
--------------------------------------------------------------------------------
/ansible/roles/os-prerequisites/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # ------------------------------------------------------------------------
3 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 | # ------------------------------------------------------------------------
17 |
18 | # check if oc tool is installed and copy it from helper node if not installed
19 | - import_tasks: check_oc_tool.yml
20 |
21 | # check temp directory for image builds
22 | - name: create temp directory for image builds
23 | file:
24 | path: "{{ tmp_root }}"
25 | state: directory
26 |
27 | # verify connection to NFS server and create directories for HDB copy
28 | - import_tasks: verify_nfs_server.yml
29 |
30 | # verify NFS directories on NFS server for HDB copy and overlay share
31 | - import_tasks: verify_nfs_hdb_directories.yml
32 |
33 | # install all required libraries
34 | - name: install podman
35 | package:
36 | name: podman
37 | state: "{{ package_state }}"
38 | - name: install a "{{ package_state }}" version of git
39 | package:
40 | name: git
41 | state: "{{ package_state }}"
42 | - name: install {{ python3x_version }}
43 | package:
44 | name: "{{ python3x_version }}"
45 | state: "{{ package_state }}"
46 | - name: install "{{ python3x_version }}-devel"
47 | package:
48 | name: "{{ python3x_version }}-devel"
49 | state: "{{ package_state }}"
50 | - name: install "{{ python3x_version }}-pip"
51 | package:
52 | name: "{{ python3x_version }}-pip"
53 | state: "{{ package_state }}"
54 |
55 | - name: set up a Python virtual environment with all Python modules
56 | shell: "cd {{ path_to_ocp_tool }} && ./tools/venv-setup "
57 | register: outmsg
58 | ignore_errors: true
59 | - debug: var=outmsg.stdout_lines
60 | - name: show debug message if the venv setup doesn't work
61 | debug: var=outmsg.stderr_lines
62 | failed_when: outmsg.rc != 0
63 | when: outmsg.rc != 0
64 |
65 | - name: activate virtual environment
66 | shell: "source {{ path_to_ocp_tool }}/venv/bin/activate"
67 | register: outmsg
68 | - debug: var=outmsg
69 |
70 | # generate config.yml and verify its parameters
71 | - import_tasks: gen-config-creds.yml
72 |
73 | - name: add cluster ip to /etc/hosts
74 | shell: "cd {{path_to_ocp_tool}} && source ./venv/bin/activate && ./tools/ocp-etc-hosts -c ./config.yaml -q ./creds.yaml -w"
75 | register: outmsg
76 | - debug: var=outmsg
77 |
78 | # check connection to OCP4 cluster
79 | - import_tasks: check_connection_to_ocp4_cluster.yml
80 |
--------------------------------------------------------------------------------
/ansible/roles/os-prerequisites/tasks/verify_nfs_hdb_directories.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # ------------------------------------------------------------------------
3 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 | # ------------------------------------------------------------------------
17 |
18 | # verify NFS directories on NFS server for HDB copy and overlay share
19 | - name: create NFS hdb directory on NFS server if NFS host name is defined
20 | command: ssh -o StrictHostKeyChecking=no {{ nfs_user_name }}@{{ nfs_host_name }} "mkdir -p {{ nfs_path_to_hdb_copy }}"
21 | when: nfs_host_name|length > 0
22 |
23 | - name: create NFS hdb directory on helper node if NFS host name isn't defined
24 | command: ssh -o StrictHostKeyChecking=no {{ ocp_helper_node_user_name }}@{{ ocp_helper_node }} "mkdir -p {{ nfs_path_to_hdb_copy }}"
25 | when: nfs_host_name == ''
26 |
27 | - name: create NFS overlay directory on NFS server if NFS host name is defined
28 | command: ssh -o StrictHostKeyChecking=no {{ nfs_user_name }}@{{ nfs_host_name }} "mkdir -p {{ nfs_path_to_overlay }}"
29 | when: nfs_host_name|length > 0
30 |
31 | - name: create NFS overlay directory on helper node if NFS host name isn't defined
32 | command: ssh -o StrictHostKeyChecking=no {{ ocp_helper_node_user_name }}@{{ ocp_helper_node }} "mkdir -p {{ nfs_path_to_overlay }}"
33 | when: nfs_host_name == ''
34 |
35 |
--------------------------------------------------------------------------------
/ansible/roles/os-prerequisites/tasks/verify_nfs_server.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # ------------------------------------------------------------------------
3 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 | # ------------------------------------------------------------------------
17 |
18 | # check NFS server connections
19 | - name: show status of NFS user name and OCP helper node
20 | fail:
21 | msg: "NFS user name and OCP helper node must be defined"
22 | when: ocp_helper_node == '' and nfs_user_name == ''
23 |
24 | - name: check ssh connection to NFS server {{ nfs_user_name }}@{{ nfs_host_name }}
25 | shell: "ssh -o StrictHostKeyChecking=no {{ nfs_user_name }}@{{ nfs_host_name }} ls"
26 | when: nfs_host_name !=''
27 |
28 | - name: check ssh connection to NFS server on a helper node {{ nfs_user_name }}@{{ ocp_helper_node }}
29 | shell: "ssh -o StrictHostKeyChecking=no {{ ocp_helper_node_user_name }}@{{ ocp_helper_node }} ls"
30 | when: nfs_host_name == ''
31 |
--------------------------------------------------------------------------------
/ansible/roles/push-images/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # ------------------------------------------------------------------------
3 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 | # ------------------------------------------------------------------------
17 | - name: push INIT image into ocp cluster
18 | shell: "cd {{path_to_ocp_tool}} && source ./venv/bin/activate && ./tools/image-push -c ./config.yaml -q ./creds.yaml -f init -w"
19 | register: outmsg_init
20 | - name: show result after pushing INIT image
21 | debug:
22 | var: outmsg_init.stdout
23 | - name: push NWS4 image into ocp cluster
24 | shell: "cd {{path_to_ocp_tool}} && source ./venv/bin/activate && ./tools/image-push -c ./config.yaml -q ./creds.yaml -f nws4 -w"
25 | register: outmsg_nws4
26 | - name: show result after pushing NWS4 image
27 | debug:
28 | var: outmsg_nws4.stdout
29 | - name: push SAP HANA container image
30 | shell: "cd {{path_to_ocp_tool}} && source ./venv/bin/activate && ./tools/image-push -c ./config.yaml -q ./creds.yaml -f hdb -w"
31 | register: outmsg_hdb
32 | - name: show result after pushing SAP HANA container
33 | debug:
34 | var: outmsg_hdb.stdout
35 | - import_tasks: ../../../tasks/oc-user-login.yml
36 | - name: verify whether the images are available in the local registry of the OpenShift cluster
37 | command: oc get imagestream
38 | register: out_image_stream
39 | - debug: var=out_image_stream.stdout_lines
40 |
--------------------------------------------------------------------------------
/ansible/tasks/copy-git-repo.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # ------------------------------------------------------------------------
3 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 | # ------------------------------------------------------------------------
17 | - name: install a "{{ package_state }}" version of git
18 | package:
19 | name: git
20 | state: "{{ package_state }}"
21 | - name: Download the tool containerization-for-sap-s4hana from the GitHub repository
22 | git: repo="{{ github_repo_url }}" dest="{{ path_to_ocp_tool }}" accept_hostkey=yes key_file="{{ github_key_file }}"
23 | when: github_key_file is defined
24 | - name: Download the tool containerization-for-sap-s4hana from the GitHub repository
25 | git: repo="{{ github_repo_url }}" dest="{{ path_to_ocp_tool }}" accept_hostkey=yes
26 | when: github_key_file is not defined
27 |
--------------------------------------------------------------------------------
/ansible/tasks/oc-admin-login.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # ------------------------------------------------------------------------
3 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 | # ------------------------------------------------------------------------
17 | #oc login -u -p
18 | - name: Login as admin to OCP cluster
19 | shell: "cd {{path_to_ocp_tool}} && source ./venv/bin/activate && ./tools/ocp-login -c ./config.yaml -q ./creds.yaml -a -w"
20 | register: login_adm
21 | - name: show login result info
22 | debug: var=login_adm.stdout
23 |
--------------------------------------------------------------------------------
/ansible/tasks/oc-user-login.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # ------------------------------------------------------------------------
3 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 | # ------------------------------------------------------------------------
17 | - name: Login as user "{{ ocp_user_name }}" to OCP cluster
18 | shell: "cd {{path_to_ocp_tool}} && source ./venv/bin/activate && ./tools/ocp-login -c ./config.yaml -q ./creds.yaml -u --project-ignore -w"
19 | register: login_ocp_msg
20 | - debug: var=login_ocp_msg.stdout
21 |
--------------------------------------------------------------------------------
/ansible/tasks/rhel8.x-prerequisites.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # ------------------------------------------------------------------------
3 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 | # ------------------------------------------------------------------------
17 | - name: install libffi
18 | package:
19 | name: libffi
20 | state: "{{package_state}}"
21 | - name: install libffi-devel
22 | package:
23 | name: libffi-devel
24 | state: "{{package_state}}"
25 | - name: install gcc
26 | package:
27 | name: gcc
28 | state: "{{package_state}}"
29 | - name: install openssl-devel
30 | package:
31 | name: openssl-devel
32 | state: "{{package_state}}"
33 | - name: install make utility
34 | package:
35 | name: make
36 | state: "{{package_state}}"
37 |
38 |
--------------------------------------------------------------------------------
/ansible/tasks/stop-deployment.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # ------------------------------------------------------------------------
3 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 | # ------------------------------------------------------------------------
17 | - import_tasks: oc-user-login.yml
18 | - name: Stopping deployment on the OCP cluster
19 | command: "oc delete -f {{path_to_ocp_tool}}/soos-{{ nws4_sid | lower}}-{{ uuid_value }}-deployment.yaml"
20 | register: stop_status
21 | - debug: var=stop_status
22 |
23 |
--------------------------------------------------------------------------------
/ansible/tasks/wait_for_n_min.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # ------------------------------------------------------------------------
3 | # Copyright 2021, 2022 IBM Corp. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 | # ------------------------------------------------------------------------
17 | #pause for 2 minutes
18 | - name: wait for 2 minutes
19 | pause:
20 | minutes: 2
21 |
--------------------------------------------------------------------------------
/ansible/tasks/wait_for_pod_running.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # ------------------------------------------------------------------------
3 | # Copyright 2021, 2022 IBM Corp. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 | # ------------------------------------------------------------------------
17 | - name: verify pod status every 30 seconds and maximum 30 minutes or until stdout contains string "Running"
18 | shell: "cd {{path_to_ocp_tool}} && source {{path_to_ocp_tool}}/venv/bin/activate && {{path_to_ocp_tool}}/tools/ocp-pod-status -c {{path_to_ocp_tool}}/config.yaml -q {{path_to_ocp_tool}}/creds.yaml"
19 | register: outmsg
20 | ignore_errors: yes
21 | until: outmsg.stdout.find("Running") != -1
22 | retries: 60
23 | delay: 30
24 |
--------------------------------------------------------------------------------
/ansible/tasks/wait_for_system_running.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # ------------------------------------------------------------------------
3 | # Copyright 2021, 2022 IBM Corp. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 | # ------------------------------------------------------------------------
17 | - name: verify system status every 30 seconds and maximum 30 minutes or until stdout contains string "running"
18 | shell: "cd {{path_to_ocp_tool}} && source {{path_to_ocp_tool}}/venv/bin/activate && {{path_to_ocp_tool}}/tools/sap-system-status -c {{path_to_ocp_tool}}/config.yaml -q {{path_to_ocp_tool}}/creds.yaml"
19 | register: outmsg
20 | ignore_errors: yes
21 | until: (outmsg.stdout | regex_findall(' running') | length) == 3
22 | retries: 60
23 | delay: 30
24 |
--------------------------------------------------------------------------------
/config.yaml.template:
--------------------------------------------------------------------------------
1 | # ------------------------------------------------------------------------
2 | # Copyright 2020, 2021 IBM Corp. All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | # ------------------------------------------------------------------------
16 |
17 | build:
18 | description: Build machine
19 | repo:
20 | description: Github repository 'https://github.com/IBM/containerization-for-sap-s4hana'
21 | root:
22 | description: Path to the root directory of the repository clone
23 | on the build machine
24 | required: true
25 | value: ''
26 |
27 | refsys:
28 | description: Reference SAP NetWeaver or SAP S/4HANA system
29 | nws4:
30 | description: ASCS and Dialog instance
31 | sid:
32 | description: SAP system ID
33 | required: true
34 | value: ''
35 |
36 | host:
37 | description: Host on which the system is installed
38 | name:
39 | description: Name of the host
40 | required: true
41 | value: ''
42 |
43 | ocp:
44 | description: OpenShift Container Platform (OCP) cluster
45 | project:
46 | description: Project under which the generated images
47 | are stored and the containers are started
48 | required: true
49 | value: ''
50 |
51 | domain:
52 | description: Cluster domain name (used for 'oc' operations)
53 | required: true
54 | value: ''
55 |
56 | helper:
57 | description: Cluster helper node
58 | host:
59 | description: Host on which the helper node is installed
60 | name:
61 | description: Name of the host as seen in the intranet
62 | (*not* in the cluster network)
63 | required: true
64 | value: ''
65 |
66 | containers:
67 | description: Container instances
68 | di:
69 | description: SAP dialog instance
70 | secret:
71 | description: Name of the OCP secret in which credentials
72 | of the SAP HANA database user (see creds.yaml)
73 | are stored for use within the Pod;
74 | *required* if the reference system is not a
75 | standard system
76 | required: false
77 | value: ''
78 |
79 | resources:
80 | requests:
81 | memory:
82 | description: Requested memory
83 | required: false
84 | value: ''
85 | limits:
86 | memory:
87 | description: Memory limit; must be >= requested memory
88 | required: false
89 | value: ''
90 |
91 | ascs:
92 | description: SAP ASCS instance
93 | resources:
94 | requests:
95 | memory:
96 | description: Requested memory
97 | required: true
98 | value: 10Gi
99 | limits:
100 | memory:
101 | description: Memory limit; must be >= requested memory
102 | required: true
103 | value: 10Gi
104 |
105 | hdb:
106 | description: SAP HANA instance
107 | resources:
108 | requests:
109 | memory:
110 | description: Requested memory; will be derived from the
111 | original database size if not supplied
112 | required: false
113 | value: ''
114 | limits:
115 | memory:
116 | description: Memory limit; must be >= requested memory;
117 | will be derived from the original database
118 | size if not supplied
119 | required: false
120 | value: ''
121 |
122 | nfs:
123 | description: NFS server
124 | host:
125 | description: Host on which the NFS server is running
126 | name:
127 | description: Name of host; if not specified
128 | ocp.helper.host.name is used
129 | required: false
130 | value: ''
131 |
132 | bases:
133 | description: Base directories
134 | copy:
135 | description: Path where directories {data,log} of the original
136 | SAP HANA system are copied to
137 | required: true
138 | value: ''
139 |
140 | overlay:
141 | description: Path under which overlay file systems for container
142 | instances are created
143 | required: true
144 | value: ''
145 |
--------------------------------------------------------------------------------
/creds.yaml.template:
--------------------------------------------------------------------------------
1 | # ------------------------------------------------------------------------
2 | # Copyright 2021 IBM Corp. All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | # ------------------------------------------------------------------------
16 |
17 | build:
18 | description: Build machine
19 | user:
20 | description: User on the build machine which is used for
21 | executing build, deploy and maintenance operations
22 | sshid:
23 | description: Absolute path to the private SSH ID file which is
24 | used for SSH connect operations from the build machine
25 | to remote systems
26 | required: false
27 | value: ''
28 |
29 | refsys:
30 | description: Reference SAP NetWeaver or SAP S/4HANA system
31 | nws4:
32 | description: ASCS and Dialog instance
33 | sidadm:
34 | description: adm-user
35 | name:
36 | description: Name
37 | required: true
38 | value: ''
39 |
40 | password:
41 | description: Password
42 | required: false
43 | value: ''
44 |
45 | hdbconnect:
46 | description: SAP HANA database user which is used by the
47 | Dialog instance to connect to the database;
48 | *required* if the reference system is not a
49 | standard system
50 | name:
51 | description: Name
52 | required: false
53 | value: SAPHANADB
54 |
55 | password:
56 | description: Password
57 | required: false
58 | value: ''
59 |
60 | hdb:
61 | description: SAP HANA database instance
62 | sidadm:
63 | description: adm-user
64 | name:
65 | description: Name
66 | required: true
67 | value: ''
68 |
69 | password:
70 | description: Password
71 | required: false
72 | value: ''
73 |
74 | nfs:
75 | description: NFS server
76 | user:
77 | description: User on the NFS server which is used for accessing
78 | the NFS host via SSH (needs root permissions)
79 | name:
80 | description: Name
81 | required: true
82 | value: root
83 |
84 | password:
85 | description: Password
86 | required: false
87 | value: ''
88 |
89 | ocp:
90 | description: OpenShift Container Platform (OCP) cluster
91 | user:
92 | description: OCP cluster user which is used for non-admin
93 | 'oc' operations
94 | name:
95 | description: Name
96 | required: true
97 | value: ''
98 |
99 | password:
100 | description: Password
101 | required: true
102 | value: ''
103 |
104 | admin:
105 | description: OCP cluster user which is used for admin
106 | 'oc' operations
107 | name:
108 | description: Name
109 | required: true
110 | value: kubeadmin
111 |
112 | password:
113 | description: Password
114 | required: true
115 | value: ''
116 |
117 | helper:
118 | description: Cluster helper node
119 | user:
120 | description: User on the OCP helper host which is used for accessing
121 | the helper host via SSH (needs root permissions)
122 |
123 | name:
124 | description: Name
125 | required: true
126 | value: root
127 |
128 | password:
129 | description: Password
130 | required: false
131 | value: ''
132 |
133 | sshid:
134 | description: Absolute path to the private SSH ID file which is
135 | used for SSH connect operations from the OCP helper
136 | node to the OCP worker nodes
137 | required: false
138 | value: ''
139 |
--------------------------------------------------------------------------------
/docs/ANSIBLE-TOWER.md:
--------------------------------------------------------------------------------
1 |
17 |
18 | # Building Images and Starting Deployments with Red Hat® Ansible Tower®
19 |
20 | In the following we describe how to build the images and deploy
21 | containers based on the images for running an SAP® system in a Red
22 | Hat® OpenShift® Container Platform using Red Hat Ansible Tower.
23 |
24 |
25 |
26 | ## Contents
27 |
28 |
29 | Table of Contents
30 |
31 | - [Getting Started with Red Hat Ansible Tower](#getting-started-with-red-hat-ansible-tower)
32 | - [Performing Manual Tasks](#performing-manual-tasks)
33 | - [Creating a New Red Hat Ansible Tower Project](#creating-a-new-red-hat-ansible-tower-project)
34 | - [Creating the Inventory](#creating-the-inventory)
35 | - [Creating the Job Template](#creating-the-job-template)
36 | - [Building the Images and Starting the SAP System](#building-the-images-and-starting-the-sap-system)
37 | - [Connecting to the Deployed SAP System](#connecting-to-the-deployed-sap-system)
38 |
39 |
40 |
41 |
42 |
43 | ## Getting Started with Red Hat Ansible Tower
44 |
45 |
46 | In the following we assume that you have installed and configured Red
47 | Hat Ansible Tower on your build LPAR.
48 |
49 | The basic installation of Ansible Tower is described in the [Ansible
50 | Automation Platform Quick Installation
51 | Guide](https://docs.ansible.com/ansible-tower/latest/html/quickinstall/index.html).
52 |
53 | More detailed information is available in the [Ansible Automation
54 | Platform Installation and Reference
55 | Guide](https://docs.ansible.com/ansible-tower/3.8.0/html/installandreference/index.html#ir-start).
56 |
57 | ## Performing Manual Tasks
58 |
59 | The tasks that need to be performed manually are described in section
60 | [*Performing manual tasks before running the
61 | playbook*](ANSIBLE.md#performing-manual-tasks-before-running-the-playbook).
62 |
63 | ## Creating a New Red Hat Ansible Tower Project
64 |
65 | You need to set up a project that will be used in a job template for
66 | building and deploying images.
67 |
68 | To define a new project, log into the Red Hat Ansible Tower web
69 | interface using *admin-level* credentials. Select *Projects* in the left
70 | navigation bar and click a green plus-button in the right top
71 | corner. You will get a new project view in which you need to fill in
72 | all required fields:
73 |
74 | + Define a project name.
75 | + Add a description.
76 | + Select organization - as an example `Default` can be used.
77 | + Select `Git` as __SCM TYPE__.
78 | + Specify __SCM BRANCH/TAG/COMMIT__ to checkout source code, as example `main` can be defined.
79 | + Select __SCM UPDATE OPTIONS__ check boxes such as `clean`, `delete on update` and `update revision on launch`.
80 |
81 | You do not need credentials to access our GitHub repository since the
82 | provided URL is public - just copy it into the field __SCM URL__ of the
83 | *Projects* template as shown:
84 |
85 | __SCM URL__: `https://github.com/IBM/containerization-for-sap-s4hana.git`
86 |
87 | 
88 |
89 | ## Creating the Inventory
90 |
91 | Before creating a job template you need to set up your inventory
92 | defining the build host and credentials. Refer to chapter
93 | [Inventories](https://docs.ansible.com/ansible-tower/latest/html/userguide/inventories.html)
94 | of the *Ansible Tower User Guide* for detailed instructions.
95 |
96 | ## Creating the Job Template
97 |
98 | Next, select *Templates* on the left side of the navigation panel. You
99 | will see a list of job templates, if there are any. To define a new
100 | job template click the green plus on the top right corner as shown:
101 |
102 | 
103 |
104 | Fill in all required fields and the desired optional fields. Detailed
105 | explanations about job templates are described in chapter [Job
106 | Templates](https://docs.ansible.com/ansible-tower/latest/html/userguide/job_templates.html)
107 | of the *Ansible Tower User Guide*.
108 |
109 | Add your variables as specified in file `vars/ocp-extra-vars.yml` to
110 | field __Extra Variables__. See section [*Specifying your
111 | settings*](ANSIBLE.md#specifying-your-settings) for all required variables.
112 |
113 | Select playbook `ansible/ocp-deployment-ansible-tower.yml` in field __Playbook__.
114 |
115 | Finally save the job template.
116 |
117 | ## Building the Images and Starting the SAP System
118 |
119 | Launch the job. A green status of the job run indicates that the three
120 | images were successfully built and the deployment of the SAP system
121 | was successfully started.
122 |
123 | Verify whether your SAP system was correctly started by performing the
124 | steps described in section [*Verifying
125 | Deployments*](VERIFYING-MANAGING.md#verifying-deployments).
126 |
127 | ## Connecting to the Deployed SAP System
128 |
129 | To connect to the deployed SAP system refer to section [*Managing
130 | Deployments*](VERIFYING-MANAGING.md#managing-deployments).
131 |
--------------------------------------------------------------------------------
/docs/ARCHITECTURE.md:
--------------------------------------------------------------------------------
1 |
17 |
18 | # Architecture
19 |
20 | The following describes the general architecture of how to build
21 | container images from existing reference SAP® systems and deploying
22 | containers in a Red Hat® OpenShift® Container Platform.
23 |
24 |
25 |
26 | ## Contents
27 |
28 |
29 | Table of Contents
30 |
31 | - [General Architecture and Workflow](#general-architecture-and-workflow)
32 |
33 |
34 |
35 |
36 |
37 | ## General Architecture and Workflow
38 |
39 | The following picture describes the steps that are executed during
40 | image build and container deployment:
41 |
42 |
43 |
45 |
46 | During the build phase three different images are created:
47 |
48 | - *Init* image: This image is independent from the reference SAP system
49 | and is used during the initialization of the deployment in the
50 | cluster.
51 |
52 | - *SAP AppServer* image: This image contains all relevant components
53 | of the reference SAP system that are needed to start both the *ABAP SAP Central Services* (ASCS)
54 | and the *Dialog instance* (DI) containers.
55 |
56 | - *SAP HANA* image: This image contains the SAP HANA® instance
57 | directories. It does not contain the `data/` and the `log/`
58 | directory trees of the database. A snapshot of these two directory
59 | trees is copied to the NFS file server during the build phase. At
60 | deployment time an overlay file system is created on top of the
61 | snapshot and mounted into the SAP HANA container.
62 |
63 | The images are pushed into the internal cluster registry. At
64 | deployment time the images are copied to the cluster helper node on
65 | which the deployment is started. At deployment start the *init*
66 | container sets up the environments for the application containers
67 | (ASCS, DI and SAP HANA containers). These are started after the *init*
68 | container has terminated. During start up of the SAP HANA container the
69 | overlay file system is mounted into the container.
70 |
71 |
--------------------------------------------------------------------------------
/docs/SCENARIOS.md:
--------------------------------------------------------------------------------
1 |
17 |
18 | # Customer Scenarios
19 |
20 | This document describes the scenarios for which containerization of
21 | reference SAP® systems was developed and tested.
22 |
23 |
24 |
25 | ## Contents
26 |
27 |
28 | Table of Contents
29 |
30 | - [Supported Reference SAP Systems for Containerization](#supported-reference-sap-systems-for-containerization)
31 | - [Supported OS Distributions](#supported-os-distributions)
32 | - [What is an SAP Instance?](#what-is-an-sap-instance)
33 | - [What is a Reference SAP System?](#what-is-a-reference-sap-system)
34 |
35 |
36 |
37 |
38 |
39 | ## Supported Reference SAP Systems for Containerization
40 |
41 | Containerization of the [reference SAP
42 | system](#what-is-a-reference-sap-system) was developed and tested
43 | with the following scope of scenarios:
44 |
45 | * Standard system (former "Central System")
46 |
47 | In a standard SAP system, all main [SAP
48 | instances](#what-is-an-sap-instance) run on a single host. All the
49 | SAP system instances from the *Primary Application Server* and *ABAP Central
50 | Services* reside on the same host as the SAP HANA® database.
51 |
52 | * Distributed System
53 |
54 | In a distributed system, the SAP instances can run on multiple
55 | hosts:
56 |
57 | * one host running the *ABAP Central Services* instance (ASCS) and the
58 | *Primary Application Server* instance (PAS),
59 |
60 | * one host running the *SAP HANA® DB* instance
61 |
62 | - SAP system installed with virtual hostnames
63 |
64 | The SAP instance installation is not bound to the physical hostname
65 | of the host, but references to an additional IP label (virtual
66 | hostname). The virtual hostname either has an own unique IP address,
67 | or is realized as IP alias (DNS CNAME). All virtual hostnames need
68 | to be resolvable on all hosts attempting to communicate with them -
69 | either via DNS entries, or via local resolution.
70 |
71 | The containerization was tested for a SAP system installed with
72 | virtual hostnames using
73 |
74 | * one IP alias name for the SAP HANA database,
75 | * one IP alias name for both *ASCS* instance and *PAS* instance.
76 |
77 | ## Supported OS Distributions
78 |
79 | Reference SAP systems installed on
80 |
81 | * RHEL 8.2 (or higher)
82 | * SLES 12 SP4 (or higher), and SLES15 SP1 (or higher)
83 |
84 | can be used for containerization.
85 |
86 | ## What is an SAP Instance?
87 |
88 | An SAP instance is a group of processes that are started and stopped
89 | at the same time. Those instances can be deployed with certain
90 | variants.
91 |
92 | ## What is a Reference SAP System?
93 |
94 | The reference SAP system is the source system for containerization. It
95 | consists out of the following main SAP instances:
96 |
97 | * *ABAP Central Services* instance (ASCS instance)
98 | * *Primary Application Server* instance (DI instance aka PAS instance)
99 | * *SAP HANA Database* instance (HDB instance)
100 |
--------------------------------------------------------------------------------
/docs/images/ArchitecturalOverview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/containerization-for-sap-s4hana/f11085ddc10f468d14e9a83ed9623cd803b8dafe/docs/images/ArchitecturalOverview.png
--------------------------------------------------------------------------------
/docs/images/BuildingImages.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/containerization-for-sap-s4hana/f11085ddc10f468d14e9a83ed9623cd803b8dafe/docs/images/BuildingImages.png
--------------------------------------------------------------------------------
/docs/images/PowerSystemsVirtualServers_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/containerization-for-sap-s4hana/f11085ddc10f468d14e9a83ed9623cd803b8dafe/docs/images/PowerSystemsVirtualServers_1.png
--------------------------------------------------------------------------------
/docs/images/PowerSystemsVirtualServers_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/containerization-for-sap-s4hana/f11085ddc10f468d14e9a83ed9623cd803b8dafe/docs/images/PowerSystemsVirtualServers_2.png
--------------------------------------------------------------------------------
/docs/images/PowerSystemsVirtualServers_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/containerization-for-sap-s4hana/f11085ddc10f468d14e9a83ed9623cd803b8dafe/docs/images/PowerSystemsVirtualServers_3.png
--------------------------------------------------------------------------------
/docs/images/PowerSystemsVirtualServers_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/containerization-for-sap-s4hana/f11085ddc10f468d14e9a83ed9623cd803b8dafe/docs/images/PowerSystemsVirtualServers_4.png
--------------------------------------------------------------------------------
/docs/images/PowerSystemsVirtualServers_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/containerization-for-sap-s4hana/f11085ddc10f468d14e9a83ed9623cd803b8dafe/docs/images/PowerSystemsVirtualServers_5.png
--------------------------------------------------------------------------------
/docs/images/ansible_tower_add_new_job_template.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/containerization-for-sap-s4hana/f11085ddc10f468d14e9a83ed9623cd803b8dafe/docs/images/ansible_tower_add_new_job_template.png
--------------------------------------------------------------------------------
/docs/images/ansible_tower_projects_view.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/containerization-for-sap-s4hana/f11085ddc10f468d14e9a83ed9623cd803b8dafe/docs/images/ansible_tower_projects_view.png
--------------------------------------------------------------------------------
/docs/images/howto/hana_studio_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/containerization-for-sap-s4hana/f11085ddc10f468d14e9a83ed9623cd803b8dafe/docs/images/howto/hana_studio_1.png
--------------------------------------------------------------------------------
/docs/images/howto/hana_studio_10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/containerization-for-sap-s4hana/f11085ddc10f468d14e9a83ed9623cd803b8dafe/docs/images/howto/hana_studio_10.png
--------------------------------------------------------------------------------
/docs/images/howto/hana_studio_11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/containerization-for-sap-s4hana/f11085ddc10f468d14e9a83ed9623cd803b8dafe/docs/images/howto/hana_studio_11.png
--------------------------------------------------------------------------------
/docs/images/howto/hana_studio_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/containerization-for-sap-s4hana/f11085ddc10f468d14e9a83ed9623cd803b8dafe/docs/images/howto/hana_studio_2.png
--------------------------------------------------------------------------------
/docs/images/howto/hana_studio_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/containerization-for-sap-s4hana/f11085ddc10f468d14e9a83ed9623cd803b8dafe/docs/images/howto/hana_studio_3.png
--------------------------------------------------------------------------------
/docs/images/howto/hana_studio_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/containerization-for-sap-s4hana/f11085ddc10f468d14e9a83ed9623cd803b8dafe/docs/images/howto/hana_studio_4.png
--------------------------------------------------------------------------------
/docs/images/howto/hana_studio_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/containerization-for-sap-s4hana/f11085ddc10f468d14e9a83ed9623cd803b8dafe/docs/images/howto/hana_studio_5.png
--------------------------------------------------------------------------------
/docs/images/howto/hana_studio_6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/containerization-for-sap-s4hana/f11085ddc10f468d14e9a83ed9623cd803b8dafe/docs/images/howto/hana_studio_6.png
--------------------------------------------------------------------------------
/docs/images/howto/hana_studio_7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/containerization-for-sap-s4hana/f11085ddc10f468d14e9a83ed9623cd803b8dafe/docs/images/howto/hana_studio_7.png
--------------------------------------------------------------------------------
/docs/images/howto/hana_studio_8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/containerization-for-sap-s4hana/f11085ddc10f468d14e9a83ed9623cd803b8dafe/docs/images/howto/hana_studio_8.png
--------------------------------------------------------------------------------
/docs/images/howto/hana_studio_9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/containerization-for-sap-s4hana/f11085ddc10f468d14e9a83ed9623cd803b8dafe/docs/images/howto/hana_studio_9.png
--------------------------------------------------------------------------------
/docs/images/ocp-haproxy-cleanup.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/containerization-for-sap-s4hana/f11085ddc10f468d14e9a83ed9623cd803b8dafe/docs/images/ocp-haproxy-cleanup.png
--------------------------------------------------------------------------------
/docs/images/ocp-haproxy-forwarding.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/containerization-for-sap-s4hana/f11085ddc10f468d14e9a83ed9623cd803b8dafe/docs/images/ocp-haproxy-forwarding.png
--------------------------------------------------------------------------------
/docs/images/ocp-port-forwarding.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/containerization-for-sap-s4hana/f11085ddc10f468d14e9a83ed9623cd803b8dafe/docs/images/ocp-port-forwarding.png
--------------------------------------------------------------------------------
/docs/images/sshkeyscopy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IBM/containerization-for-sap-s4hana/f11085ddc10f468d14e9a83ed9623cd803b8dafe/docs/images/sshkeyscopy.png
--------------------------------------------------------------------------------
/openshift/images/hdb/containerfile.template:
--------------------------------------------------------------------------------
1 | # ------------------------------------------------------------------------
2 | # Copyright 2020, 2021 IBM Corp. All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | # ------------------------------------------------------------------------
16 |
17 | FROM registry.access.redhat.com/ubi8/ubi-init:latest
18 |
19 | # label
20 |
21 | LABEL soos.containerfile.description="{{IMAGE_DESCRIPTION}}" \
22 | soos.containerfile.date="{{IMAGE_DATE}}" \
23 | soos.containerfile.version="{{IMAGE_VERSION}}" \
24 | soos.containerfile.commit="{{IMAGE_COMMIT}}" \
25 | soos.containerfile.branch="{{IMAGE_BRANCH}}"
26 |
27 | #RUN dnf -y makecache
28 |
29 | RUN \
30 | # Install packages needed for image build
31 | dnf -y install --setopt=install_weak_deps=False util-linux-user && \
32 | # Install packages needed for container operation
33 | dnf -y install --setopt=install_weak_deps=False csh hostname && \
34 | # Install prerequisite packages for running SAP products (SAP Note #2772999)
35 | dnf -y install --setopt=install_weak_deps=False uuidd libnsl tcsh psmisc nfs-utils bind-utils && \
36 | # Need to be installed for SAP HANA
37 | dnf -y install --setopt=install_weak_deps=False expect graphviz iptraf-ng krb5-workstation libatomic libcanberra-gtk2 libibverbs libicu libpng12 libssh2 lm_sensors ncurses numactl PackageKit-gtk3-module xorg-x11-xauth && \
38 | # Need to be installed for the "Server" environment group
39 | dnf -y install --setopt=install_weak_deps=False cairo libaio krb5-libs net-tools openssl rsyslog sudo xfsprogs && \
40 | # Need to be installed for mounting NFS shares for HANA
41 | dnf -y install --setopt=install_weak_deps=False nfs-utils
42 |
43 | # Install optional packages
44 |
45 | {{INSTALL_OPT_PACKAGES}}
46 |
47 | {{COPY_OPT_PACKAGE_FILES}}
48 | {{INSTALL_OPT_PACKAGE_FILES}}
49 |
50 | RUN dnf -y clean all
51 |
52 | # Create needed users and groups
53 |
54 | RUN groupadd --gid {{SAPSYS_GID}} sapsys && \
55 | useradd --no-create-home --uid {{SAPADM_UID}} --gid {{SAPSYS_GID}} --comment "{{SAPADM_COMMENT}}" --home-dir {{SAPADM_HOME}} --shell {{SAPADM_SHELL}} sapadm && \
56 | useradd --no-create-home --uid {{SIDADM_UID}} --gid {{SAPSYS_GID}} --comment "{{SIDADM_COMMENT}}" --home-dir {{SIDADM_HOME}} --shell {{SIDADM_SHELL}} {{sid}}adm
57 |
58 | # Copy HANA system related files
59 |
60 | COPY ./etc_services_sap ./etc_security_limits.conf /
61 | COPY ./etc/pam.d/sapstartsrv /etc/pam.d/sapstartsrv
62 | COPY ./etc/security/limits.d/99-sapsys.conf /etc/security/limits.d/99-sapsys.conf
63 | COPY --chown={{SIDADM_UID}}:{{SAPSYS_GID}} .{{USR_SAP_REAL}} {{USR_SAP_REAL}}/
64 | COPY --chown={{SIDADM_UID}}:{{SAPSYS_GID}} .{{HANA_SHARED_SID}} {{HANA_SHARED_SID}}/
65 |
66 | # Copy systemd and HANA license manager related files
67 |
68 | COPY ./soos.service /etc/systemd/system/
69 | COPY ./soos-start.sh ./soos-stop.sh ./soos-hdblcm.tmp /root/
70 |
71 |
72 | # Setup HANA system and and enable required systemd services
73 |
74 | RUN {{USR_SAP_LINK_CMD}} && \
75 | cat /etc_services_sap >> /etc/services && rm /etc_services_sap && \
76 | cat /etc_security_limits.conf >> /etc/security/limits.conf && rm /etc_security_limits.conf && \
77 | chown root:{{SAPSYS_GID}} /usr/sap {{USR_SAP_REAL}} {{USR_SAP_REAL}}/sapservices && \
78 | mkdir -p {{VAR_LIB_HDB_SID}} && chown {{SIDADM_UID}}:{{SAPSYS_GID}} {{VAR_LIB_HDB_SID}} && \
79 | chgrp -R {{SAPSYS_GID}} {{USR_SAP_REAL}}/sapservices && \
80 | chmod +x /root/soos-start.sh && \
81 | chmod +x /root/soos-stop.sh && \
82 | systemctl enable soos && \
83 | systemctl enable uuidd && \
84 | systemctl unmask systemd-logind
85 |
86 | # Cleanup
87 |
88 | # XXX TBD
89 |
90 | # Container startup
91 |
92 | # In ubi-init images CMD is /sbin/init by default
93 | # In ubi images we need to specify a CMD
94 | #CMD /root/soos-start.sh && tail -f /dev/null
95 |
--------------------------------------------------------------------------------
/openshift/images/hdb/image-content/hdblcm-config.template:
--------------------------------------------------------------------------------
1 | # ------------------------------------------------------------------------
2 | # Copyright 2020, 2021 IBM Corp. All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | # ------------------------------------------------------------------------
16 |
17 | [Action]
18 |
19 | # Execution scenario
20 | action=register_rename_system
21 |
22 | [Rename]
23 |
24 | # Skip all SAP Host Agent calls
25 | skip_hostagent_calls=n
26 |
27 | # Execute checks, do not rename SAP HANA System
28 | check_only=n
29 |
30 | # Clean up system replication configuration on the target system
31 | sr_cleanup=n
32 |
33 | # Remote Execution
34 | remote_execution=ssh
35 |
36 | # Enable the installation or upgrade of the SAP Host Agent
37 | install_hostagent=n
38 |
39 | # Use Existing System Administrator ()
40 | init_user=n
41 |
42 | # Do not start SAP HANA Database System but start service (sapstartsrv) instead
43 | nostart={{SOOS_HDB_RENAME}}
44 |
45 | # Installation Path
46 | sapmnt={{SOOS_HDB_BASE_DIR}}/shared
47 |
48 | # Source System ID
49 | source_sid={{SID}}
50 |
51 | # Host Name
52 | hostmap={{SRC_HOST}}={{SOOS_HDB_HOST}}
53 |
54 | # System Usage
55 | system_usage=development
56 |
57 | # Execution Scope
58 | scope=system
59 |
60 | # SAP HANA System is already offline
61 | system_is_offline=n
62 |
63 | # Certificate Host Names
64 | # certificates_hostmap={{SRC_HOST}}={{SOOS_HDB_HOST}}
65 | certificates_hostmap={{SOOS_HDB_HOST}}={{SOOS_HDB_HOST}}
66 |
67 | # Target System ID
68 | target_sid={{SID}}
69 |
70 | # Target Instance Number
71 | number={{INST_NO}}
72 |
73 | # Location of Data Volumes
74 | datapath={{SOOS_HDB_BASE_DATA_DIR}}/data/{{SID}}
75 |
76 | # Location of Log Volumes
77 | logpath={{SOOS_HDB_BASE_LOG_DIR}}/log/{{SID}}
78 |
79 | # Location of Data Backups
80 | databackuppath={{SOOS_HDB_BASE_DIR}}/shared/{{SID}}/HDB{{INST_NO}}/backup/data
81 |
82 | # Location of Log Backups
83 | logbackuppath={{SOOS_HDB_BASE_DIR}}/shared/{{SID}}/HDB{{INST_NO}}/backup/log
84 |
85 | # Location of Catalog Backups
86 | catalogbackuppath={{SOOS_HDB_BASE_DIR}}/shared/{{SID}}/HDB{{INST_NO}}/backup/log
87 |
88 | # Init Existing Home Directory of System Administrator ()
89 | init_user_home_dir=n
90 |
91 | # System Administrator Home Directory
92 | home={{SIDADM_HOME}}
93 |
94 | # System Administrator Login Shell
95 | shell={{SIDADM_SHELL}}
96 |
97 | # System Administrator User ID
98 | userid={{SIDADM_UID}}
99 |
100 | # ID of User Group (sapsys)
101 | groupid={{SAPSYS_GID}}
102 |
103 | # Do not Modify '/etc/sudoers' File
104 | skip_modify_sudoers=n
105 |
106 | # Do not Remove XS Advanced OS Users
107 | keep_xs_os_users=n
108 |
109 | # Change the password of the System Database user
110 | change_system_user_password=n
111 |
112 | # Restart system after machine reboot?
113 | autostart=n
114 |
--------------------------------------------------------------------------------
/openshift/images/hdb/image-content/soos-stop.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # ------------------------------------------------------------------------
4 | # Copyright 2020, 2021 IBM Corp. All Rights Reserved.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | # ------------------------------------------------------------------------
18 |
19 | # Stop Instances
20 | #su - ${SOOS_HDB_SID,,}adm -c "HDB stop"
21 |
--------------------------------------------------------------------------------
/openshift/images/hdb/image-content/soos.service:
--------------------------------------------------------------------------------
1 | # ------------------------------------------------------------------------
2 | # Copyright 2020, 2021 IBM Corp. All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | # ------------------------------------------------------------------------
16 |
17 | [Unit]
18 | Description=Startup service for SAP HANA
19 | Wants=network.target network-online.target
20 | After=network.target network-online.target
21 |
22 | [Service]
23 | Type=oneshot
24 | EnvironmentFile=/etc/sysconfig/soos/soos-env
25 | ExecStart=/root/soos-start.sh
26 | RemainAfterExit=true
27 | ExecStop=/root/soos-stop.sh
28 | TimeoutSec=6000
29 | Restart=no
30 |
31 | [Install]
32 | WantedBy=multi-user.target
33 |
--------------------------------------------------------------------------------
/openshift/images/init/containerfile:
--------------------------------------------------------------------------------
1 | # ------------------------------------------------------------------------
2 | # Copyright 2020, 2021 IBM Corp. All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | # ------------------------------------------------------------------------
16 |
17 | FROM registry.access.redhat.com/ubi8/ubi-init:latest
18 |
19 | # Install packages needed for image build
20 |
21 | RUN dnf -y install --setopt=install_weak_deps=False util-linux-user
22 |
23 | # Install packages needed for container operation
24 |
25 | RUN dnf -y install --setopt=install_weak_deps=False csh hostname
26 |
27 | # Copy and enable shell script
28 |
29 | COPY ./soos-create-envdir.sh /root/
30 |
31 | RUN chmod +x /root/soos-create-envdir.sh
32 |
33 | CMD /root/soos-create-envdir.sh
34 |
--------------------------------------------------------------------------------
/openshift/images/init/image-content/soos-create-envdir.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # ------------------------------------------------------------------------
4 | # Copyright 2020, 2021 IBM Corp. All Rights Reserved.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | # ------------------------------------------------------------------------
18 |
19 | # Write env-file with variables for all instances
20 | env | grep SOOS_GLOBAL | sort > /root/global-env
21 |
22 | # Write env-file for both ASCS and DI instance
23 | env | grep SOOS_NWS4 | sort > /root/nws4-env
24 |
25 | # Write env-file for ASCS instance
26 | env | grep SOOS_ASCS | sort > /root/ascs-env
27 |
28 | sed -e "s/SOOS_ASCS_PROFILE/SOOS_NWS4_PROFILE/g" \
29 | -e "s/SOOS_ASCS_INSTNO/SOOS_NWS4_INSTNO/g" \
30 | -e "1iSOOS_NWS4_INSTTYPE=ASCS" \
31 | /root/ascs-env > /root/ascs-env-mod
32 |
33 | cat /root/global-env /root/nws4-env /root/ascs-env-mod > /envdir-ascs/soos-env
34 |
35 | # Write env-file for DI instance
36 | env | grep SOOS_DI | sort > /root/di-env
37 |
38 | sed -e "s/SOOS_DI_PROFILE/SOOS_NWS4_PROFILE/g" \
39 | -e "s/SOOS_DI_INSTNO/SOOS_NWS4_INSTNO/g" \
40 | -e "1iSOOS_NWS4_INSTTYPE=DI" \
41 | /root/di-env > /root/di-env-mod
42 |
43 | cat /root/global-env /root/nws4-env /root/di-env-mod > /envdir-di/soos-env
44 |
45 | # Write env-file for HDB instance
46 | env | grep SOOS_HDB | sort > /root/hdb-env
47 | cat /root/global-env /root/hdb-env > /envdir-hdb/soos-env
48 |
--------------------------------------------------------------------------------
/openshift/images/nws4/containerfile.template:
--------------------------------------------------------------------------------
1 | # ------------------------------------------------------------------------
2 | # Copyright 2020, 2021 IBM Corp. All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | # ------------------------------------------------------------------------
16 |
17 | FROM registry.access.redhat.com/ubi8/ubi-init:latest
18 |
19 | # label
20 |
21 | LABEL soos.containerfile.description="{{IMAGE_DESCRIPTION}}" \
22 | soos.containerfile.date="{{IMAGE_DATE}}" \
23 | soos.containerfile.version="{{IMAGE_VERSION}}" \
24 | soos.containerfile.commit="{{IMAGE_COMMIT}}" \
25 | soos.containerfile.branch="{{IMAGE_BRANCH}}"
26 |
27 | #RUN dnf -y makecache
28 |
29 | RUN \
30 | # Install packages needed for image build
31 | dnf -y install --setopt=install_weak_deps=False util-linux-user && \
32 | # Install packages needed for container operation
33 | dnf -y install --setopt=install_weak_deps=False csh hostname && \
34 | # Install prerequisite packages for running SAP products (SAP Note #2772999)
35 | dnf -y install --setopt=install_weak_deps=False uuidd libnsl tcsh psmisc nfs-utils bind-utils && \
36 | # Need to be installed for SAP HANA
37 | dnf -y install --setopt=install_weak_deps=False expect graphviz iptraf-ng krb5-workstation libatomic libcanberra-gtk2 libibverbs libicu libpng12 libssh2 lm_sensors numactl PackageKit-gtk3-module xorg-x11-xauth && \
38 | # Need to be installed for the "Server" environment group
39 | dnf -y install --setopt=install_weak_deps=False cairo libaio krb5-libs net-tools openssl rsyslog sudo xfsprogs && \
40 | dnf -y clean all
41 |
42 | # Create needed users and groups
43 |
44 | RUN groupadd --gid {{SAPSYS_GID}} sapsys && \
45 | useradd --no-create-home --uid {{SAPADM_UID}} --gid {{SAPSYS_GID}} --comment "{{SAPADM_COMMENT}}" --home-dir {{SAPADM_HOME}} --shell {{SAPADM_SHELL}} sapadm && \
46 | useradd --no-create-home --uid {{SIDADM_UID}} --gid {{SAPSYS_GID}} --comment "{{SIDADM_COMMENT}}" --home-dir {{SIDADM_HOME}} --shell {{SIDADM_SHELL}} {{sid}}adm
47 |
48 | # Copy SAP system related files
49 |
50 | COPY ./etc_services_sap ./etc_security_limits.conf /
51 | COPY --chown={{SIDADM_UID}}:{{SAPSYS_GID}} .{{USR_SAP_REAL}} {{USR_SAP_REAL}}/
52 | COPY --chown={{SIDADM_UID}}:{{SAPSYS_GID}} .{{SAPMNT}} {{SAPMNT}}/
53 | # COPY --chown={{SAPADM_UID}}:{{SAPSYS_GID}} .{{SAPADM_HOME}} {{SAPADM_HOME}}/
54 | COPY --chown={{SIDADM_UID}}:{{SAPSYS_GID}} .{{SIDADM_HOME}} {{SIDADM_HOME}}/
55 |
56 | # Copy systemd related files
57 |
58 | COPY ./soos.service /etc/systemd/system/
59 | COPY ./soos-start.sh ./soos-stop.sh /root/
60 |
61 | # Setup SAP system and and enable required systemd services
62 |
63 | RUN {{USR_SAP_LINK_CMD}} && \
64 | cat /etc_services_sap >> /etc/services && rm /etc_services_sap && \
65 | cat /etc_security_limits.conf >> /etc/security/limits.conf && rm /etc_security_limits.conf && \
66 | mv {{USR_SAP_REAL}}/sapservices {{USR_SAP_REAL}}/sapservices.orig && \
67 | chown root:{{SAPSYS_GID}} /usr/sap {{USR_SAP_REAL}} {{USR_SAP_REAL}}/sapservices.orig {{SAPMNT}} && \
68 | chown -R root:{{SAPSYS_GID}} {{USR_SAP_REAL}}/trans && \
69 | # SJ 20 Aug: remove hostagent
70 | # chown -R {{SAPADM_UID}}:{{SAPSYS_GID}} {{USR_SAP_REAL}}/hostctrl && \
71 | #chgrp -R {{SAPSYS_GID}} {{USR_SAP_REAL}}/trans && \
72 | chmod +x /root/soos-start.sh && \
73 | chmod +x /root/soos-stop.sh && \
74 | systemctl enable soos && \
75 | systemctl enable uuidd && \
76 | systemctl unmask systemd-logind
77 |
78 | # Cleanup
79 |
80 | # XXX TBD
81 |
82 | # Container startup
83 |
84 | # In ubi-init images CMD is /sbin/init by default
85 | # In ubi images we need to specify a CMD
86 | #CMD /root/soos-start.sh && tail -f /dev/null
87 |
--------------------------------------------------------------------------------
/openshift/images/nws4/image-content/soos-stop.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # ------------------------------------------------------------------------
4 | # Copyright 2020, 2021 IBM Corp. All Rights Reserved.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | # ------------------------------------------------------------------------
18 |
19 | # Stop Instances
20 |
21 | # for i in $(/usr/sap/hostctrl/exe/saphostctrl -function ListInstances | cut -d- -f2); do
22 | echo "Stopping instance $i"
23 | # /usr/sap/hostctrl/exe/sapcontrol -nr "$i" -function Stop
24 | su - ${SOOS_NWS4_SID,,}adm -c "/usr/sap/$SOOS_NWS4_SID/SYS/exe/run/sapcontrol -nr "${SOOS_NWS4_INSTNO}" -function Stop"
25 | # done
26 |
--------------------------------------------------------------------------------
/openshift/images/nws4/image-content/soos.service:
--------------------------------------------------------------------------------
1 | # ------------------------------------------------------------------------
2 | # Copyright 2020, 2021 IBM Corp. All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | # ------------------------------------------------------------------------
16 |
17 | [Unit]
18 | Description=Startup service for SAP S/4HANA
19 | Wants=network.target network-online.target
20 | After=network.target network-online.target
21 |
22 | [Service]
23 | Type=oneshot
24 | EnvironmentFile=/etc/sysconfig/soos/soos-env
25 | ExecStart=/root/soos-start.sh
26 | RemainAfterExit=true
27 | ExecStop=/root/soos-stop.sh
28 | TimeoutSec=900
29 |
30 | [Install]
31 | WantedBy=multi-user.target
32 |
--------------------------------------------------------------------------------
/openshift/secret.yaml.template:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Secret
3 | metadata:
4 | name: {{secret-name}}
5 | namespace: {{project}}
6 | type: Opaque
7 | stringData:
8 | HDB_DBUSER: {{User}}
9 | HDB_DBUSERPWD: {{Password}}
10 |
--------------------------------------------------------------------------------
/openshift/service-nodeport.yaml.template:
--------------------------------------------------------------------------------
1 | # ------------------------------------------------------------------------
2 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | # ------------------------------------------------------------------------
16 |
17 | apiVersion: v1
18 | kind: Service
19 | metadata:
20 | namespace: {{PROJECT}}
21 | name: {{DEPLOYMENT_NAME}}-np
22 | spec:
23 | type: NodePort
24 | ports:
25 | - name: di-32xx
26 | port: 32{{NWS4_DI_INSTNO}}
27 | targetPort: 32{{NWS4_DI_INSTNO}}
28 | protocol: TCP
29 | - name: hdb-3xx13
30 | port: 3{{HDB_INSTNO}}13
31 | targetPort: 3{{HDB_INSTNO}}13
32 | protocol: TCP
33 | - name: hdb-3xx15
34 | port: 3{{HDB_INSTNO}}15
35 | targetPort: 3{{HDB_INSTNO}}15
36 | protocol: TCP
37 | selector:
38 | app: {{DEPLOYMENT_NAME}}
39 |
--------------------------------------------------------------------------------
/tools/config:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # ------------------------------------------------------------------------
4 | # Copyright 2021, 2022 IBM Corp. All Rights Reserved.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | # ------------------------------------------------------------------------
18 |
19 | """ Configuration management """
20 |
21 |
22 | try:
23 | # Global modules
24 |
25 | import yaml
26 |
27 | # Local modules
28 |
29 | from modules.args import getCommonArgsParser
30 | from modules.config import Config
31 | from modules.context import getContext
32 | from modules.nestedns import nestedNsToObj
33 | from modules.startup import startup
34 |
35 | except ModuleNotFoundError as mnfex:
36 | from modules.exceptions import setExceptHook
37 | setExceptHook()
38 | raise mnfex
39 |
40 |
41 | # Functions
42 |
43 | def _getArgs():
44 | """ Get command line arguments """
45 | parser = getCommonArgsParser(
46 | 'Configuration management'
47 | )
48 |
49 | parser.add_argument(
50 | '-n',
51 | '--new',
52 | required = False,
53 | action = 'store_true',
54 | help = "Create a new configuration file"
55 | )
56 |
57 | parser.add_argument(
58 | '-e',
59 | '--edit',
60 | required = False,
61 | action = 'store_true',
62 | help = "Change configuration in an existing configuration file"
63 | )
64 |
65 | parser.add_argument(
66 | '-d',
67 | '--dump',
68 | required = False,
69 | action = 'store_true',
70 | help = "Dump configuration to stdout"
71 | )
72 |
73 | parser.add_argument(
74 | '--non-interactive',
75 | required = False,
76 | action = 'store_true',
77 | help = "Perform '-n' and '-e' non-interactively"
78 | ' (reading values from environment)'
79 | )
80 |
81 | parser.add_argument(
82 | '-s',
83 | '--suppress-descriptions',
84 | required = False,
85 | action = 'store_true',
86 | help = "Don't show detailed descriptions during edit"
87 | )
88 |
89 | return parser.parse_args()
90 |
91 |
92 | # ----------------------------------------------------------------------
93 |
94 | def _main():
95 |
96 | ctx = getContext(_getArgs(), withCreds=True, withConfig=False)
97 |
98 | if ctx.ar.new:
99 | config = Config(ctx, create=True, failOnDiscoveryError=False)
100 | else:
101 | config = Config(ctx, create=False, failOnDiscoveryError=False)
102 |
103 | if ctx.ar.new:
104 | config.create(ctx.ar.suppress_descriptions)
105 |
106 | elif ctx.ar.edit:
107 | config.edit(ctx.ar.suppress_descriptions)
108 |
109 | elif ctx.ar.dump:
110 | print(yaml.dump(nestedNsToObj(config.get())))
111 |
112 | else:
113 | print('\nUse option\n\n'
114 | " '-n' to create a new configuration file\n"
115 | " '-e' to edit an existing configuration file\n"
116 | " '-d' to dump an existing configuration file\n"
117 | " '-h' to get more help\n\n"
118 | "NEVER CHANGE FILE 'config.yaml.template'"
119 | " - OTHERWISE THIS TOOL WON'T WORK AS EXPECTED\n")
120 |
121 |
122 | # ----------------------------------------------------------------------
123 |
124 | if __name__ == '__main__':
125 | startup(_main)
126 |
--------------------------------------------------------------------------------
/tools/creds:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # ------------------------------------------------------------------------
4 | # Copyright 2021, 2022 IBM Corp. All Rights Reserved.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | # ------------------------------------------------------------------------
18 |
19 | """ Credentials management """
20 |
21 |
22 | try:
23 | # Global modules
24 |
25 | import yaml
26 |
27 | # Local modules
28 |
29 | from modules.args import getCommonArgsParser
30 | from modules.context import getContext
31 | from modules.creds import Creds
32 | from modules.nestedns import nestedNsToObj
33 | from modules.startup import startup
34 |
35 | except ModuleNotFoundError as mnfex:
36 | from modules.exceptions import setExceptHook
37 | setExceptHook()
38 | raise mnfex
39 |
40 |
41 | # Functions
42 |
43 | def _getArgs():
44 | """ Get command line arguments """
45 | parser = getCommonArgsParser(
46 | 'Credentials management'
47 | )
48 |
49 | parser.add_argument(
50 | '-n',
51 | '--new',
52 | required = False,
53 | action = 'store_true',
54 | help = "Create a new credentials file"
55 | )
56 |
57 | parser.add_argument(
58 | '-e',
59 | '--edit',
60 | required = False,
61 | action = 'store_true',
62 | help = "Change credentials in an existing credentials file"
63 | )
64 |
65 | parser.add_argument(
66 | '-d',
67 | '--dump',
68 | required = False,
69 | action = 'store_true',
70 | help = "Dump credentials to stdout (DISPLAYS SECRETS IN CLEAR TEXT)"
71 | )
72 |
73 | parser.add_argument(
74 | '--non-interactive',
75 | required = False,
76 | action = 'store_true',
77 | help = "Perform '-n' and '-e' non-interactively"
78 | ' (reading values from environment)'
79 | )
80 |
81 | parser.add_argument(
82 | '-s',
83 | '--suppress-descriptions',
84 | required = False,
85 | action = 'store_true',
86 | help = "Don't show detailed descriptions during edit"
87 | )
88 |
89 | parser.add_argument(
90 | '-u',
91 | '--unencrypted',
92 | required = False,
93 | default = False,
94 | action = 'store_true',
95 | help = "If '-n' is specified: Don't encrypt a newly"
96 | ' created credentials file'
97 | )
98 |
99 | parser.add_argument(
100 | '-r',
101 | '--recipient',
102 | metavar = '',
103 | required = False,
104 | default = None,
105 | help = "If '-n' is specified and '-u' is not specified:"
106 | ' Owner e-mail address or key fingerprint of GPG key'
107 | ' which will be used for encrypting a newly created'
108 | ' credentials file. If not specified, symmetric AES256'
109 | ' encryption is used.'
110 | )
111 |
112 | return parser.parse_args()
113 |
114 |
115 | # ----------------------------------------------------------------------
116 |
117 | def _main():
118 |
119 | ctx = getContext(_getArgs(), withCreds=False, withConfig=False)
120 |
121 | if ctx.ar.new:
122 | creds = Creds(ctx, create=True)
123 | else:
124 | creds = Creds(ctx, create=False)
125 |
126 | if ctx.ar.new:
127 | creds.create(ctx.ar.suppress_descriptions)
128 |
129 | elif ctx.ar.edit:
130 | creds.edit(ctx.ar.suppress_descriptions)
131 |
132 | elif ctx.ar.dump:
133 | print(yaml.dump(nestedNsToObj(creds.get(), hideSecrets=False)))
134 |
135 | else:
136 | print('\nUse option\n\n'
137 | " '-n' to create a new credentials file\n"
138 | " '-e' to edit an existing credentials file\n"
139 | " '-d' to dump an existing credentials file (DISPLAYS SECRETS IN CLEAR TEXT)\n"
140 | " '-h' to get more help\n\n"
141 | "NEVER CHANGE FILE 'creds.yaml.template'"
142 | " - OTHERWISE THIS TOOL WON'T WORK AS EXPECTED\n")
143 |
144 |
145 | # ----------------------------------------------------------------------
146 |
147 | if __name__ == '__main__':
148 | startup(_main)
149 |
--------------------------------------------------------------------------------
/tools/gpg-key-gen:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # ------------------------------------------------------------------------
4 | # Copyright 2021, 2022 IBM Corp. All Rights Reserved.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | # ------------------------------------------------------------------------
18 |
19 | """ Generate a GPG private / public key pair """
20 |
21 |
22 | try:
23 | # Global modules
24 |
25 | import getpass
26 | import os
27 | import pwd
28 | import socket
29 | import sys
30 |
31 | import gnupg
32 |
33 | # Local modules
34 |
35 | from modules.args import getCommonArgs
36 | from modules.context import getContext
37 | from modules.logger import logging
38 | from modules.startup import startup
39 |
40 | except ModuleNotFoundError as mnfex:
41 | from modules.exceptions import setExceptHook
42 | setExceptHook()
43 | raise mnfex
44 |
45 |
46 | # Functions
47 |
48 |
49 | # ----------------------------------------------------------------------
50 |
51 | def _main():
52 |
53 | getContext(getCommonArgs(
54 | 'Generate a GPG private / public key pair'
55 | ), withCreds=False, withConfig=False)
56 |
57 | user = getpass.getuser()
58 | host = socket.gethostname()
59 | gecos = pwd.getpwnam(user).pw_gecos
60 |
61 | recipient = f'{user}@{host}'
62 |
63 | gpg = gnupg.GPG()
64 |
65 | logging.getLogger("gnupg").setLevel(logging.ERROR)
66 |
67 | # Set gpg tty to make console pinentry reliably working
68 |
69 | try:
70 | # os.ttyname() fails when we are not running interactivly
71 | os.environ['GPG_TTY'] = os.ttyname(sys.stdin.fileno())
72 | except OSError:
73 | logging.info('Not setting GPG_TTY environment variable')
74 |
75 | # Generate the key
76 |
77 | key = gpg.gen_key(gpg.gen_key_input(
78 | key_type = 'RSA',
79 | key_length = 3072,
80 | name_real = gecos,
81 | name_comment = 'GPG key for SAP on OCP',
82 | name_email = recipient
83 | ))
84 |
85 | print(f"\nGenerated GPG private / public key pair for recipient '{recipient}'\n\n"
86 | f"Run\n\n"
87 | f" gpg --list-keys\n\n"
88 | f"to list your GPG keys.\n\n"
89 | f"Run\n\n"
90 | f" KEY={key}\n"
91 | f" gpg --delete-secret-key ${{KEY}} && gpg --delete-key ${{KEY}}\n\n"
92 | f"to remove the secret and public key from your keyring\n")
93 |
94 |
95 | # ----------------------------------------------------------------------
96 |
97 | if __name__ == '__main__':
98 | startup(_main)
99 |
--------------------------------------------------------------------------------
/tools/image-build:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # ------------------------------------------------------------------------
4 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | # ------------------------------------------------------------------------
18 |
19 | """ Build a container image of a given flavor """
20 |
21 |
22 | try:
23 | # Global modules
24 |
25 | # None
26 |
27 | # Local modules
28 |
29 | from modules.args import (
30 | addArgImageFlavor,
31 | getCommonArgsParser
32 | )
33 | from modules.command import CmdShell
34 | from modules.context import getContext
35 | from modules.imagebuilder import getBuilder
36 | from modules.startup import startup
37 | from modules.tools import pushd
38 |
39 | except ModuleNotFoundError as mnfex:
40 | from modules.exceptions import setExceptHook
41 | setExceptHook()
42 | raise mnfex
43 |
44 |
45 | # Functions
46 |
47 | def _getArgs():
48 | """ Get command line arguments """
49 | parser = getCommonArgsParser(
50 | 'Build a container image of a given flavor'
51 | )
52 |
53 | addArgImageFlavor(parser)
54 |
55 | parser.add_argument(
56 | '-t',
57 | '--temp-root',
58 | metavar = '',
59 | required = False,
60 | default = '/data/tmp',
61 | help = "Use as root for temporary files generated during build")
62 |
63 | parser.add_argument(
64 | '-d',
65 | '--build-directory',
66 | metavar = '',
67 | required = False,
68 | help = "Use as build directory; "
69 | "if not specified, a new build directory is created under ''")
70 |
71 | parser.add_argument(
72 | '-k',
73 | '--keep-files',
74 | required = False,
75 | action = 'store_true',
76 | help = "Keep existing files in which were copied from in a "
77 | "previous run; has no effect if '-d' is not specified"
78 | )
79 |
80 | return parser.parse_args()
81 |
82 |
83 | # ----------------------------------------------------------------------
84 |
85 | def _main():
86 |
87 | ctx = getContext(_getArgs())
88 |
89 | if ctx.ar.image_flavor == 'init':
90 | with pushd(f'{ctx.cf.build.repo.root}/openshift/images/init'):
91 | imageName = ctx.cf.images.init.names.local
92 | CmdShell().run(f'podman build -t {imageName} -f ./containerfile ./image-content')
93 | else:
94 | sidU = getattr(ctx.cf.refsys, ctx.ar.image_flavor).sidU
95 | host = getattr(ctx.cf.refsys, ctx.ar.image_flavor).host.name
96 | user = getattr(ctx.cr.refsys, ctx.ar.image_flavor).sidadm
97 |
98 | getBuilder(ctx).buildImage(sidU, host, user)
99 |
100 |
101 | # ----------------------------------------------------------------------
102 |
103 | if __name__ == '__main__':
104 | startup(_main)
105 |
--------------------------------------------------------------------------------
/tools/image-push:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # ------------------------------------------------------------------------
4 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | # ------------------------------------------------------------------------
18 |
19 | """ Push a container image of a given flavor to the internal cluster registry """
20 |
21 |
22 | try:
23 | # Global modules
24 |
25 | # None
26 |
27 | # Local modules
28 |
29 | from modules.args import (
30 | addArgImageFlavor,
31 | getCommonArgsParser
32 | )
33 | from modules.command import CmdShell
34 | from modules.context import getContext
35 | from modules.ocp import Ocp
36 | from modules.startup import startup
37 |
38 | except ModuleNotFoundError as mnfex:
39 | from modules.exceptions import setExceptHook
40 | setExceptHook()
41 | raise mnfex
42 |
43 |
44 | # Functions
45 |
46 | def _getArgs():
47 | """ Get command line arguments """
48 | parser = getCommonArgsParser(
49 | 'Push a container image of a given flavor to the internal cluster registry'
50 | )
51 |
52 | addArgImageFlavor(parser)
53 |
54 | return parser.parse_args()
55 |
56 |
57 | def _tagImage(ctx, flavor):
58 | names = getattr(ctx.cf.images, flavor).names
59 | CmdShell().run(f'podman tag {names.local} {names.ocp}')
60 |
61 |
62 | def _pushImage(ctx, flavor):
63 | names = getattr(ctx.cf.images, flavor).names
64 | cmd = 'podman push'
65 | cmd += ' --tls-verify=false'
66 | cmd += f' {names.ocp}'
67 | CmdShell().run(cmd)
68 |
69 |
70 | # ----------------------------------------------------------------------
71 |
72 | def _main():
73 |
74 | ctx = getContext(_getArgs())
75 |
76 | ocp = Ocp(ctx)
77 |
78 | ocp.podmanOcpRegistryLogin()
79 |
80 | _tagImage(ctx, ctx.ar.image_flavor)
81 |
82 | _pushImage(ctx, ctx.ar.image_flavor)
83 |
84 | del ocp
85 |
86 |
87 | # ----------------------------------------------------------------------
88 |
89 | if __name__ == '__main__':
90 | startup(_main)
91 |
--------------------------------------------------------------------------------
/tools/modules/__init__.py:
--------------------------------------------------------------------------------
1 | # ------------------------------------------------------------------------
2 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | # ------------------------------------------------------------------------
16 |
17 | """ Init file for package 'modules' """
18 |
19 | # DO NOT ERASE THIS FILE
20 |
--------------------------------------------------------------------------------
/tools/modules/argsdoc.py:
--------------------------------------------------------------------------------
1 | # ------------------------------------------------------------------------
2 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | # ------------------------------------------------------------------------
16 |
17 | """ Generate documentation from CLI command definitions """
18 |
19 |
20 | # Global modules
21 |
22 | import argparse
23 | import html
24 | import sys
25 |
26 |
27 | # Classes
28 |
29 | # The follwowing classes partly rely on internal
30 | # implementation details of the Python argparse module
31 | #
32 | # See https://github.com/python/cpython/blob/main/Lib/argparse.py
33 |
34 | # The following classes were inspired by the GitHub Gist
35 | #
36 | # https://gist.githubusercontent.com/parajain/772e138f7604c0ecb7e57898e45a903a/raw/e7e8e4d5544e337cbfa1ec527d093e287da23045/generate_doc.py
37 | #
38 | # This Gist contains the following note:
39 | #
40 | # > MARKDOWN boilerplate
41 | # >
42 | # > Copyright 2016 The Chromium Authors. All rights reserved.
43 | # > Use of this source code is governed by a BSD-style license that can be
44 | # > found in the LICENSE file.
45 | #
46 | # XXX TO BE SOLVED BEFORE PUBLICATION ON github.com:
47 | # - DO WE HAVE TO MENTION THE GIST SINCE THE CODE WAS CONSIDERABLY CHANGED?
48 | # - IF YES, WHAT DO WE HAVE TO DO IN DETAIL TO FULFILL THE ABOVE COPYRIGHT STATEMENT
49 |
50 |
51 | class ArgsDocsGfmAction(argparse.Action):
52 | """ Python argparse action for generating a
53 | GitHub Flavored Markdown (GFM) document snippet """
54 |
55 | def __call__(self, parser, namespace, values, option_string=None):
56 |
57 | parser.formatter_class = _ArgsDocsGfmFormatter
58 |
59 | # Format the GFM snippet from the argparse definitions
60 |
61 | gfm = parser.format_help()
62 |
63 | # Remove trailing ':' at end of table definition line
64 | # emitted by argparse._Section().format_help()
65 | # There seems to be no other was of getting rid of the ':'
66 |
67 | gfm = gfm.replace(':--------|:\n', ':--------|\n')
68 |
69 | print(gfm)
70 |
71 | sys.exit(0)
72 |
73 |
74 | class _ArgsDocsGfmFormatter(argparse.HelpFormatter):
75 | """ Python argparse help formatter for generating a
76 | GitHub Flavored Markdown (GFM) document snippet """
77 |
78 | def format_help(self):
79 | # Generate GFM snippet by means of parent class formatter
80 | # Prepend GFM heading
81 |
82 | return f'## Tool `{self._prog}`\n\n{super().format_help()}'
83 |
84 | def _format_usage(self, usage, actions, groups, prefix):
85 | # Generate GFM for usage section by means of parent class formatter
86 |
87 | usage = super()._format_usage(usage, actions, groups, prefix='')
88 |
89 | # Trim the received string by removing all unwanted whitespaces
90 |
91 | usage = ' '.join(s.strip() for s in usage.split())
92 |
93 | # Prepend the heading for the 'Usage' section
94 | # Also append the heading for the 'Purpose' section since there
95 | # seems to be no other way to get it into the final GFM snippet
96 |
97 | usage = f'### Usage\n\n`{usage}`\n\n### Purpose\n\n'
98 |
99 | return usage
100 |
101 | def start_section(self, heading):
102 | # Formatter for head of each section
103 | # 'heading': 'positional arguments', 'optional arguments', ...
104 |
105 | # Capitalize the first character of each word in heading
106 | # and HTML escape the heading
107 |
108 | heading = ' '.join(s.capitalize() for s in heading.split())
109 | heading = html.escape(heading)
110 |
111 | # Start the section by means of the parent class formatter
112 | # Pass the table head in addition to the heading
113 |
114 | super().start_section(
115 | f'### {heading}\n'
116 | f'\n'
117 | f'| Argument | Description | Default |\n'
118 | f'|:---------|:------------|:--------|'
119 | )
120 |
121 | def _format_action(self, action):
122 | # Formatter for a single CLI argument
123 |
124 | argument = f'`{super()._format_action_invocation(action)}`'
125 | description = html.escape(self._expand_help(action))
126 | default = f'`{action.default}`' if action.default != argparse.SUPPRESS else ''
127 |
128 | return f'| {argument} | {description} | {default} |\n'
129 |
--------------------------------------------------------------------------------
/tools/modules/constants.py:
--------------------------------------------------------------------------------
1 | # ------------------------------------------------------------------------
2 | # Copyright 2021, 2022 IBM Corp. All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | # ------------------------------------------------------------------------
16 |
17 | """ Constants """
18 |
19 |
20 | # Global modules
21 |
22 | import types
23 |
24 |
25 | # Functions
26 |
27 | def getConstants():
28 | """ Get constants """
29 | const = types.SimpleNamespace()
30 |
31 | # Constants for config.yaml file handling
32 | const.configCacheTimeout = 600 # seconds
33 |
34 | # optional packages to be installed depending on the SPS Level of the HANA DB
35 |
36 | compatSapPkg9 = types.SimpleNamespace()
37 |
38 | compatSapPkg9.minSpsLevel = 50
39 | compatSapPkg9.maxSpsLevel = 59
40 | # packageName is part of the package metadata, it is not the rpm filename
41 | compatSapPkg9.packageName = "compat-sap-c++-9"
42 | compatSapPkg9.dependencies = ["libgomp"]
43 | compatSapPkg9.distribution = "rhel"
44 | compatSapPkg9.repository = "rhel-8-for-ppc64le-sap-netweaver-rpms"
45 |
46 | compatSapPkg10 = types.SimpleNamespace()
47 |
48 | compatSapPkg10.minSpsLevel = 60
49 | compatSapPkg10.maxSpsLevel = 69
50 | # packageName is part of the package metadata, it is not the rpm filename
51 | compatSapPkg10.packageName = "compat-sap-c++-10"
52 | compatSapPkg10.dependencies = ["libgomp"]
53 | compatSapPkg10.distribution = "rhel"
54 | compatSapPkg10.repository = "rhel-8-for-ppc64le-sap-netweaver-rpms"
55 |
56 | const.optionalHdbPkgs = [compatSapPkg9, compatSapPkg10]
57 |
58 | # default location for packages to be downloaded
59 | const.defaultPackagesDir = "/tmp/soos/rpm-packages"
60 |
61 | # additional free space to be added for HANA DB
62 | const.additionalFreeSpaceHdbGiB = 5
63 | # minimum memory size of Dialog Instance Container
64 | const.minMemSizeDIGiB = 32
65 |
66 | # length of the uuid
67 | # uuid is used for overlay fs name, deployment file name and deployment app name
68 | const.uuidLen = 10
69 |
70 | # HA Proxy configuration file
71 | const.haproxyCfg = '/etc/haproxy/haproxy.cfg'
72 |
73 | # Constants for argument names
74 | const.argAdd = 'add'
75 | const.argAppName = 'app-name'
76 | const.argConfigFile = 'config-file'
77 | const.argContainerFlavor = 'container-flavor'
78 | const.argCredsFile = 'creds-file'
79 | const.argDeploymentFile = 'deployment-file'
80 | const.argDumpContext = 'dump-context'
81 | const.argGenDocGfm = 'gen-doc-gfm'
82 | const.argGenYaml = 'gen-yaml'
83 | const.argImageFlavor = 'image-flavor'
84 | const.argList = 'list'
85 | const.argLogFileDir = 'logfile-dir'
86 | const.argLogLevel = 'loglevel'
87 | const.argLogToTerminal = 'log-to-terminal'
88 | const.argLoop = 'loop'
89 | const.argNumber = 'number'
90 | const.argOutputFile = 'output-file'
91 | const.argOverlayUuid = 'overlay-uuid'
92 | const.argRemove = 'remove'
93 | const.argSleepTime = 'sleep-time'
94 | const.argStart = 'start'
95 | const.argStop = 'stop'
96 |
97 | # Constants for different deployment types
98 | const.deployAll = 'all'
99 | const.deployRunning = 'running'
100 | const.deployDeployed = 'deployed'
101 | const.deployNotDeployed = 'not deployed'
102 |
103 | return const
104 |
--------------------------------------------------------------------------------
/tools/modules/context.py:
--------------------------------------------------------------------------------
1 | # ------------------------------------------------------------------------
2 | # Copyright 2021, 2022 IBM Corp. All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | # ------------------------------------------------------------------------
16 |
17 | """ Context """
18 |
19 |
20 | # Global modules
21 |
22 | import sys
23 | import types
24 | import yaml
25 |
26 |
27 | # Local modules
28 |
29 | from modules.config import Config
30 | from modules.creds import Creds
31 | from modules.constants import getConstants
32 | from modules.fail import fail
33 | from modules.logger import setupLogging
34 | from modules.nestedns import nestedNsToObj
35 |
36 |
37 | # Functions
38 |
39 | def _printHeader(msg):
40 | sep = '-' * len(msg)
41 | print(f'# {sep}\n# {msg}\n# {sep}\n')
42 |
43 |
44 | def getContext(args, withCreds=True, withConfig=True, failOnDiscoveryError=True):
45 | """ Get context """
46 |
47 | setupLogging(args)
48 |
49 | ctx = types.SimpleNamespace()
50 |
51 | ctx.ar = args
52 | ctx.cr = None
53 | ctx.cf = None
54 | ctx.cs = getConstants()
55 |
56 | if withCreds:
57 | ctx.creds = Creds(ctx)
58 | ctx.cr = ctx.creds.get()
59 | if withConfig:
60 | ctx.config = Config(ctx, failOnDiscoveryError=failOnDiscoveryError)
61 | ctx.cf = ctx.config.getFull()
62 | elif withConfig:
63 | fail("Can't get configuration without credentials")
64 |
65 | if args.dump_context:
66 | _printHeader('COMMAND LINE ARGUMENTS')
67 | print(yaml.dump({'ar': nestedNsToObj(ctx.ar)}))
68 | _printHeader('CREDENTIALS')
69 | print(yaml.dump({'cr': nestedNsToObj(ctx.cr)}))
70 | _printHeader('CONFIGURATION')
71 | print(yaml.dump({'cf': nestedNsToObj(ctx.cf)}))
72 | sys.exit(0)
73 |
74 | return ctx
75 |
--------------------------------------------------------------------------------
/tools/modules/exceptions.py:
--------------------------------------------------------------------------------
1 | # ------------------------------------------------------------------------
2 | # Copyright 2021, 2022 IBM Corp. All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | # ------------------------------------------------------------------------
16 |
17 | """ Exceptions """
18 |
19 |
20 | # Global modules
21 |
22 | import sys
23 |
24 |
25 | # Local modules
26 |
27 | from modules.messages import getMessage
28 | from modules.times import (
29 | saveCurrentTime,
30 | printTimes
31 | )
32 |
33 |
34 | # Classes
35 |
36 | class RpmFileNotFoundException(Exception):
37 | """ Raises if RPM File for specific package could not be found """
38 |
39 | def __init__(self, path, packageName, err):
40 | super().__init__()
41 | self.errorText = getMessage("msgE001", path, packageName, err)
42 |
43 |
44 | # Functions
45 |
46 | def setExceptHook():
47 | """ Set the global exception hook """
48 |
49 | sys.excepthook = _exceptHook
50 |
51 |
52 | def _exceptHook(extype, exinstance, traceback):
53 | """ Handle an exception depending on the type of the exception """
54 |
55 | # Print times recorded during program execution
56 |
57 | saveCurrentTime('Exception', traceback)
58 | printTimes(traceback)
59 |
60 | # Handle exception
61 |
62 | if extype == KeyboardInterrupt:
63 | _exceptHookKeyboardInterrupt(extype, exinstance, traceback)
64 |
65 | elif extype == ModuleNotFoundError:
66 | _exceptHookModuleNotFoundError(extype, exinstance, traceback)
67 |
68 | else:
69 | sys.__excepthook__(extype, exinstance, traceback)
70 |
71 |
72 | def _exceptHookKeyboardInterrupt(extype, exinstance, traceback):
73 | # pylint: disable=unused-argument
74 | print()
75 |
76 |
77 | def _exceptHookModuleNotFoundError(extype, exinstance, traceback):
78 | # pylint: disable=unused-argument
79 | hrule = '\n' + '='*50 + '\n'
80 | print(f'{hrule}\n',
81 | f' GOT THE FOLLOWING EXCEPTION:\n\n'
82 | f' {exinstance}\n',
83 | sep = '',
84 | file=sys.stderr
85 | )
86 |
87 | if sys.prefix != sys.base_prefix:
88 | # Running in a virtual environment
89 | print(' YOUR VIRTUAL PYTHON ENVIRONMENT SEEMS NOT TO BE\n'
90 | ' SET UP AS EXPECTED.\n\n'
91 | ' LEAVE YOUR VIRTUAL ENVIRONMENT BY EXECUTING\n\n'
92 | ' deactivate\n\n'
93 | ' AND REMOVE IT BY EXECUTING\n\n'
94 | ' rm -rf ./venv/\n\n'
95 | ' RECREATE THE VIRTUAL ENVIRONMENT BY RUNNING\n\n'
96 | ' tools/venv-setup\n\n'
97 | ' AND ACTIVATE IT BY EXECUTING\n\n'
98 | ' source ./venv/bin/activate',
99 | file=sys.stderr
100 | )
101 |
102 | else:
103 | # Not running in a virtual environment
104 | print(' NOT RUNNING IN A VIRTUAL PYTHON ENVIRONMENT.\n\n'
105 | ' CREATE A VIRTUAL PYTHON ENVIRONMENT BY RUNNING\n\n'
106 | ' tools/venv-setup\n\n'
107 | ' AND ACTIVATE IT BY EXECUTING\n\n'
108 | ' source ./venv/bin/activate\n\n'
109 | ' OR MAKE SURE THAT YOUR CURRENT PYTHON RUNTIME\n'
110 | ' ENVIRONMENT PROVIDES ALL REQUIRED PYTHON MODULES\n'
111 | " (SEE ERROR MESSAGE ABOVE).",
112 | file=sys.stderr
113 | )
114 |
115 | print(hrule, file=sys.stderr)
116 |
--------------------------------------------------------------------------------
/tools/modules/fail.py:
--------------------------------------------------------------------------------
1 | # ------------------------------------------------------------------------
2 | # Copyright 2021, 2022 IBM Corp. All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | # ------------------------------------------------------------------------
16 |
17 | """ Helper tools """
18 |
19 |
20 | # Global modules
21 |
22 | import logging
23 | import sys
24 |
25 |
26 | # Local modules
27 |
28 | from modules.times import (
29 | saveCurrentTime,
30 | printTimes
31 | )
32 |
33 |
34 | # Functions
35 |
36 | def fail(msg, exitCode=1):
37 | """ Print error message and recorded times and exit """
38 | logging.error(msg)
39 | print(msg, file=sys.stderr)
40 |
41 | saveCurrentTime('Failure')
42 | printTimes()
43 |
44 | sys.exit(exitCode)
45 |
46 |
47 | def warn(msg):
48 | """ Print warning message but don't exit """
49 | logging.warning(msg)
50 | print(msg, file=sys.stderr)
51 |
--------------------------------------------------------------------------------
/tools/modules/logger.py:
--------------------------------------------------------------------------------
1 | # ------------------------------------------------------------------------
2 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | # ------------------------------------------------------------------------
16 |
17 | """ Logging setup """
18 |
19 |
20 | # Global modules
21 |
22 | import logging
23 | import os
24 | import sys
25 | import time
26 |
27 |
28 | # Functions
29 |
30 | def _getScriptName():
31 | scriptName = os.path.basename(sys.argv[0])
32 | if scriptName.endswith('.py'):
33 | scriptName = scriptName[:-3]
34 | return scriptName
35 |
36 |
37 | def _getLogFilePath(logfileDir, infix=''):
38 | prefix = _getScriptName()
39 | if len(infix) > 0:
40 | prefix += '-'+infix
41 | return f'{logfileDir}/{prefix}-{str(time.time()).replace(".","")}.log'
42 |
43 |
44 | def setupLogging(args, infix=''):
45 | """ Set up logging """
46 |
47 | # Delete existing root handlers
48 |
49 | for handler in logging.root.handlers[:]:
50 | logging.root.removeHandler(handler)
51 |
52 | # Custom formatting
53 |
54 | class _LogRecordFactory(logging.LogRecord):
55 | # pylint: disable=too-few-public-methods
56 | def __init__(self, *args, **kwargs):
57 | super().__init__(*args, **kwargs)
58 | self.origin = f"{self.filename}:{self.funcName}()"
59 | logging.setLogRecordFactory(_LogRecordFactory)
60 |
61 | logFormat = '[{origin:25}] {message}'
62 |
63 | # Configure logging
64 |
65 | loglevel = getattr(logging, args.loglevel.upper())
66 |
67 | if args.log_to_terminal:
68 | logging.basicConfig(format=logFormat, style='{', level=loglevel)
69 | else:
70 | if not os.path.exists(args.logfile_dir):
71 | os.makedirs(args.logfile_dir)
72 | logFilePath = _getLogFilePath(args.logfile_dir, infix=infix)
73 | logging.basicConfig(format=logFormat, style='{', level=loglevel,
74 | filename=logFilePath, filemode='w')
75 | print(f"Logging to '{logFilePath}'", file=sys.stderr)
76 |
--------------------------------------------------------------------------------
/tools/modules/messages.py:
--------------------------------------------------------------------------------
1 | # ------------------------------------------------------------------------
2 | # Copyright 2021, 2022 IBM Corp. All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | # ------------------------------------------------------------------------
16 |
17 | """ Helper tools for message formatting """
18 |
19 |
20 | # Global modules
21 |
22 | import textwrap
23 |
24 |
25 | # Functions
26 |
27 | def formatMessageParagraphs(paragraphs, width, prefix, indentLevel):
28 | """ Format a list of paragraphs """
29 | return _formatMessage(paragraphs, width, prefix*indentLevel, prefix*indentLevel)
30 |
31 |
32 | def formatMessageList(listItems, width, prefix, indentLevel):
33 | """ Format a list of list items """
34 | return _formatMessage(listItems, width, prefix*indentLevel+'- ', prefix*indentLevel+' ')
35 |
36 |
37 | def getMessage(*parmList):
38 | """ returns the message text for given message number """
39 | msgNo = parmList[0]
40 | # First entry in parmList is the msgNo, ignore it!
41 | nmbrOfParmsPassed = len(parmList) - 1
42 | messageText = ""
43 | msgObj = msgList[msgNo]
44 |
45 | if msgObj["noOfParms"] != nmbrOfParmsPassed:
46 | # Throw exception?
47 | return messageText
48 | # Replacing placeholders
49 | for element in msgObj["msg"]:
50 | messageText += _formatMessageElement(element, parmList)
51 | return messageText
52 |
53 |
54 | def _formatMessage(paragraphs, width, initialPrefix, subsequentPrefix):
55 | msg = ''
56 | first = True
57 | for paragraph in paragraphs:
58 | if first:
59 | first = False
60 | else:
61 | msg += '\n'
62 | msg += '\n'.join(textwrap.wrap(paragraph,
63 | width=width,
64 | initial_indent=initialPrefix,
65 | subsequent_indent=subsequentPrefix
66 | )
67 | )
68 | return msg
69 |
70 |
71 | def _formatMessageElement(element, parmList):
72 | if "index" in element.keys():
73 | return element["msg"].format(parmList[element["index"]])
74 | return element["msg"]
75 |
76 |
77 | def _setNumberOfParms(msgObj):
78 | highestNo = 0
79 | for element in msgObj:
80 | if "index" in element.keys():
81 | if element["index"] > highestNo:
82 | highestNo = element["index"]
83 | return highestNo
84 |
85 |
86 | # Message definitions
87 |
88 | # Messages printed by logging
89 |
90 | # parmList:
91 | # 1: type of the resource (limits/requests)
92 | # 2: containerType
93 | # 3: memory size
94 | msgL001 = [{"msg": "Caution: You did not specify a value for the {} ",
95 | "index": 1},
96 | {"msg": "memory size for the "},
97 | {"msg": "{} container.\n",
98 | "index": 2},
99 | {"msg": "The memory size is set to its default value {}.\n",
100 | "index": 3},
101 | {"msg": "If the 'limits' memory size is smaller than the value "},
102 | {"msg": "of the 'requested' memory size, \n"},
103 | {"msg": "the generation of the deployment will fail "},
104 | {"msg": "and the process is stopped. \n"},
105 | {"msg": "Use the 'verify-config' tool to make sure "},
106 | {"msg": "that your memory settings are valid.\n"}]
107 |
108 | # Messages printed by Exceptions
109 |
110 | # parmList:
111 | # 1: path to rpm file
112 | # 2: packageName
113 | # 3: additional error text
114 | msgE001 = [{"msg": "The default package file path '{}' ",
115 | "index": 1},
116 | {"msg": "{} \n",
117 | "index": 3},
118 | {"msg": "Provide the rpm package file for package '{}' ",
119 | "index": 2},
120 | {"msg": "at the local directory {}. \n",
121 | "index": 1},
122 | {"msg": "For more information about additionally required RPM packages "},
123 | {"msg": "see the documentation."}]
124 |
125 | # parmList:
126 | # 1: limits memory size
127 | # 2: containerType
128 | # 3: requests memory size
129 | msgE002 = [{"msg": "The specified 'limits' memory value {} ",
130 | "index": 1},
131 | {"msg": "for the {} container \n",
132 | "index": 2},
133 | {"msg": "is less than the specified 'requests' memory value {}.\n",
134 | "index": 3},
135 | {"msg": "The Container cannot be started."}]
136 |
137 | msgList = {"msgE001": {"msg": msgE001, "noOfParms": _setNumberOfParms(msgE001)},
138 | "msgE002": {"msg": msgE002, "noOfParms": _setNumberOfParms(msgE002)},
139 | "msgL001": {"msg": msgL001, "noOfParms": _setNumberOfParms(msgL001)}
140 | }
141 |
--------------------------------------------------------------------------------
/tools/modules/nestedns.py:
--------------------------------------------------------------------------------
1 | # ------------------------------------------------------------------------
2 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | # ------------------------------------------------------------------------
16 |
17 | """ Implementation of nested namespaces based on types.SimpleNamespace """
18 |
19 |
20 | # Global modules
21 |
22 | import argparse
23 | import types
24 |
25 |
26 | # Local modules
27 |
28 | # None
29 |
30 |
31 | # Functions
32 |
33 | def objToNestedNs(obj):
34 | """ Convert an object into a (potentially) nested namespaces """
35 |
36 | if isinstance(obj, dict):
37 | nnObj = {}
38 | for k, v in obj.items(): # pylint: disable=invalid-name
39 | nnObj[k] = objToNestedNs(v)
40 | nestedNs = types.SimpleNamespace(**nnObj)
41 |
42 | elif isinstance(obj, list):
43 | nestedNs = []
44 | for i in obj:
45 | nestedNs.append(objToNestedNs(i))
46 |
47 | else:
48 | nestedNs = obj
49 |
50 | return nestedNs
51 |
52 |
53 | def nestedNsToObj(nestedNs, hideSecrets=True):
54 | """ Convert a (potentially) nested namespaces into an object """
55 |
56 | if isinstance(nestedNs, (types.SimpleNamespace, argparse.Namespace)):
57 | hideList = []
58 | if hideSecrets:
59 | hideList += ['password']
60 | obj = {}
61 | for k in vars(nestedNs).keys():
62 | if k in hideList:
63 | obj[k] = ''
64 | else:
65 | obj[k] = nestedNsToObj(getattr(nestedNs, k), hideSecrets)
66 |
67 | elif isinstance(nestedNs, list):
68 | obj = []
69 | for child in nestedNs:
70 | obj.append(nestedNsToObj(child, hideSecrets))
71 |
72 | else:
73 | obj = nestedNs
74 |
75 | return obj
76 |
--------------------------------------------------------------------------------
/tools/modules/nfs-ping-test:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # ------------------------------------------------------------------------
4 | # Copyright 2021, 2022 IBM Corp. All Rights Reserved.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | # ------------------------------------------------------------------------
18 |
19 | """ Ping test from worker node: Get 1st reachable ip address out of a list """
20 |
21 | import sys
22 | import subprocess
23 |
24 | rtc = 'None'
25 |
26 | if len(sys.argv) > 2:
27 | worker = sys.argv[1]
28 |
29 | for ip in sys.argv[2:]:
30 |
31 | sshcmd = f'ping -c 1 {ip} 2>&1 >/dev/null && echo True || echo False'
32 | cmd = f'ssh core@{worker} {sshcmd}'
33 |
34 | output = subprocess.check_output(f'{cmd}', shell=True).decode("utf-8").split()[0]
35 | if output == 'True':
36 | rtc = ip
37 | break
38 |
39 | print(rtc)
40 |
--------------------------------------------------------------------------------
/tools/modules/quantity.py:
--------------------------------------------------------------------------------
1 | # ------------------------------------------------------------------------
2 | # Copyright 2021, 2022 IBM Corp. All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | # ------------------------------------------------------------------------
16 |
17 | """ OCP quantities """
18 |
19 | # pylint: disable=line-too-long
20 | # See https://docs.openshift.com/container-platform/4.7/rest_api/objects/index.html#quantity-api-resource
21 |
22 | # Global modules
23 |
24 | import logging
25 | import re
26 |
27 |
28 | # Local modules
29 |
30 | from modules.fail import fail
31 |
32 |
33 | # Constants
34 |
35 | _scale = {
36 | '': 1,
37 |
38 | 'K': 1000**1,
39 | 'M': 1000**2,
40 | 'G': 1000**3,
41 | 'T': 1000**4,
42 | 'P': 1000**5,
43 | 'E': 1000**6,
44 |
45 | 'Ki': 1024**1,
46 | 'Mi': 1024**2,
47 | 'Gi': 1024**3,
48 | 'Ti': 1024**4,
49 | 'Pi': 1024**5,
50 | 'Ei': 1024**6,
51 | }
52 |
53 |
54 | # Classes
55 |
56 | class Quantity():
57 | """ OCP quantities """
58 |
59 | def __init__(self, quantityStr):
60 |
61 | self._quantityStr = quantityStr if quantityStr else '0'
62 |
63 | # Extract value and scale
64 |
65 | match = re.match(r'\s*(\d+)\s*(\S*)\s*', self._quantityStr)
66 | if not match:
67 | fail(f"Quantity '{self._quantityStr}' format is invalid")
68 |
69 | self._valueInt = int(match.groups()[0])
70 | self._scale = match.groups()[1]
71 | self._checkScale()
72 |
73 | self._valueIntNormalized = self._valueInt * _scale[self._scale]
74 |
75 | logging.debug(f'({self._quantityStr}, {self._valueInt},'
76 | f' {self._scale}, {self._valueIntNormalized})')
77 |
78 | def __str__(self):
79 | return self._quantityStr
80 |
81 | def __ge__(self, other):
82 | return self._valueIntNormalized >= other._valueIntNormalized
83 |
84 | def __lt__(self, other):
85 | return self._valueIntNormalized < other._valueIntNormalized
86 |
87 | def _checkScale(self):
88 | if self._scale not in _scale.keys():
89 | fail(f"Unknown scale '{self._scale}' in '{self._quantityStr}'")
90 |
91 | def valueIntScaled(self, scale):
92 | """ returns int value scaled to unit """
93 | if scale not in _scale.keys():
94 | fail(f"Unknown scale '{scale}' specified. Cannot continue.")
95 | return self._valueIntNormalized / _scale[scale]
96 |
97 | def valueIntNormalized(self):
98 | """ returns the value normed to bytes """
99 | return self._valueIntNormalized
100 |
--------------------------------------------------------------------------------
/tools/modules/startup.py:
--------------------------------------------------------------------------------
1 | # ------------------------------------------------------------------------
2 | # Copyright 2021, 2022 IBM Corp. All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | # ------------------------------------------------------------------------
16 |
17 | """ Common startup sequence for all tools """
18 |
19 |
20 | # Global Modules
21 |
22 | import sys
23 |
24 |
25 | # Local Modules
26 |
27 | from modules.exceptions import setExceptHook
28 | from modules.times import (
29 | printTimes,
30 | saveEndTime,
31 | saveStartTime
32 | )
33 |
34 |
35 | # Functions
36 |
37 | def startup(mainFunc):
38 | """ Execute common startup sequence and start main function """
39 |
40 | # Handle specifc uncaught exceptions in a particular way
41 | # and print all saved times in case of an uncaught exception
42 |
43 | setExceptHook()
44 |
45 | # Save the program start time
46 |
47 | saveStartTime()
48 |
49 | # Run the program
50 |
51 | retCode = mainFunc()
52 |
53 | # Save the program termination time
54 |
55 | saveEndTime()
56 |
57 | # Print all saved times
58 |
59 | printTimes()
60 |
61 | exitCode = 0 if not retCode else retCode
62 |
63 | sys.exit(exitCode)
64 |
--------------------------------------------------------------------------------
/tools/modules/times.py:
--------------------------------------------------------------------------------
1 | # ------------------------------------------------------------------------
2 | # Copyright 2021, 2022 IBM Corp. All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | # ------------------------------------------------------------------------
16 |
17 | """ Record time stamps during program execution and print them at program termination """
18 |
19 |
20 | # Global Modules
21 |
22 | import datetime
23 | import inspect
24 | import logging
25 | import types
26 |
27 |
28 | # Local Modules
29 |
30 | from modules.table import Table
31 |
32 |
33 | # Functions
34 |
35 | def saveStartTime():
36 | """ Save program start time """
37 | saveCurrentTime('Program Start')
38 |
39 |
40 | def saveEndTime():
41 | """ Save program termination time """
42 | saveCurrentTime('Program End')
43 |
44 |
45 | def saveCurrentTime(label, traceback=None):
46 | """ Save current time together with a descriptive label """
47 |
48 | time = types.SimpleNamespace()
49 | time.label = label
50 | time.time = datetime.datetime.now()
51 |
52 | _getTimes(traceback).append(time)
53 |
54 |
55 | def printTimes(traceback=None):
56 | """ Print all saved times """
57 |
58 | times = _getTimes(traceback)
59 |
60 | if len(times) > 0:
61 | table = Table(title = 'Elapsed Times',
62 | headings = ['Step', 'Date', 'Time', 'Δt Prev. Step'],
63 | )
64 |
65 | startTime = times[0].time
66 | prevTime = startTime
67 |
68 | for time in times:
69 |
70 | curTime = time.time
71 | delta = curTime-prevTime if curTime != prevTime else ''
72 |
73 | table.appendRow([time.label, curTime.date(), curTime.time(), delta])
74 |
75 | prevTime = curTime
76 |
77 | logging.critical(f'\n{table.render()}\n') # Always log times
78 |
79 |
80 | def _getTimes(traceback):
81 |
82 | # We store the times in the local variables section of the main module
83 | # For accessing them we first need to get the frame for the main module
84 |
85 | frame = _getModuleFrame(traceback)
86 |
87 | # Now we can retrieve the times from the local variable section of the main module
88 |
89 | if not frame:
90 | logging.debug("Could not find frame for ''")
91 | times = []
92 |
93 | else:
94 | timesKey = '_soos_times'
95 |
96 | if timesKey not in frame.f_locals.keys():
97 |
98 | # This is the first time _getTimes() is called.
99 | # Add an empty times array to the local
100 | # variable section of the main module.
101 |
102 | frame.f_locals[timesKey] = []
103 |
104 | times = frame.f_locals[timesKey]
105 |
106 | return times
107 |
108 |
109 | def _getModuleFrame(traceback):
110 |
111 | # Get the start frame for searching the main module frame
112 | # See https://docs.python.org/3/library/inspect.html
113 |
114 | if not traceback:
115 | # Retrieve the start frame via inspect()
116 | frame = inspect.currentframe()
117 |
118 | else:
119 | # Retrieve the start frame from the traceback
120 | # See https://www.oreilly.com/library/view/python-cookbook/0596001673/ch14s05.html
121 |
122 | while traceback.tb_next:
123 | traceback = traceback.tb_next
124 | frame = traceback.tb_frame
125 |
126 | # Search the main module frame starting from the start frame
127 |
128 | while frame and frame.f_code.co_name != '':
129 | frame = frame.f_back
130 |
131 | return frame
132 |
--------------------------------------------------------------------------------
/tools/nfs-hdb-copy:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # ------------------------------------------------------------------------
4 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | # ------------------------------------------------------------------------
18 |
19 | """ Copy an SAP HANA DB snapshot to the NFS server """
20 |
21 |
22 | try:
23 | # Global modules
24 |
25 | import logging
26 | from pathlib import Path
27 |
28 | # Local modules
29 |
30 | from modules.args import getCommonArgs
31 | from modules.command import (
32 | CmdSsh,
33 | CmdShell
34 | )
35 | from modules.context import getContext
36 | from modules.fail import fail
37 | from modules.nfstools import (
38 | getHdbCopyBase,
39 | getHdbSubDirs
40 | )
41 | from modules.startup import startup
42 | from modules.tools import getNumRunningSapProcs
43 |
44 | except ModuleNotFoundError as mnfex:
45 | from modules.exceptions import setExceptHook
46 | setExceptHook()
47 | raise mnfex
48 |
49 |
50 | # Functions
51 |
52 | def _getCopyCmd(cmdSshDb, cmdSshNfs, sourceDir, targetDir):
53 | # Copy using tar shell command running on SAPDBHOST,
54 | # redirecting the output to
55 | # and piping it then to the tar command running on the
56 | # NFS server.
57 |
58 | # ssh command Build Server -> SAPDBHOST
59 | sshDb = cmdSshDb.getSshCmdAndSecrets()[0]
60 | # ssh command Build Server -> NFS Server
61 | sshNfs = cmdSshNfs.getSshCmdAndSecrets()[0]
62 |
63 | tarCmd = f"tar cf - {sourceDir}"
64 |
65 | # --strip-components= is an argument used during extracting the tar file
66 | # Its value is set to the number of existing subdirs of the source to
67 | # strip the number of leading components from the extracted file name
68 | noOfSubdirs = _getNoOfSubdirs(sourceDir)
69 |
70 | untarCmd = f"tar xf - -C {targetDir} --strip-components={noOfSubdirs} --same-owner"
71 | return f"{sshDb} {tarCmd} | {sshNfs} {untarCmd}"
72 |
73 |
74 | def _getNoOfSubdirs(directory):
75 | parentDir = Path(directory)
76 | count = 0
77 | rootDir = parentDir.anchor
78 | while str(parentDir) != str(rootDir):
79 | parentDir = parentDir.parent
80 | count = count+1
81 | return count
82 |
83 |
84 | def _getFileSizeSet(cmdSsh, directory):
85 | cmd = f'cd {directory}; find . -type f -printf "%s %p$"'
86 | result = cmdSsh.run(cmd)
87 | if result.rc != 0:
88 | fail("Error: could not get file list")
89 |
90 | sizeList = result.out.split("$")
91 | sizeSet = set()
92 | for element in sizeList:
93 | sizeSet.add(tuple(element.split(" ")))
94 | return sizeSet
95 |
96 |
97 | def _checkCopyStep(cmdSshDb, cmdSshNfs, sourceDir, targetDir):
98 | sourceSizes = _getFileSizeSet(cmdSshDb, sourceDir)
99 | targetSizes = _getFileSizeSet(cmdSshNfs, targetDir)
100 |
101 | # get differences:
102 | diffs = sourceSizes - targetSizes
103 |
104 | # if the set of diffs is not empty, there is a mismatch between source and target
105 | if len(diffs) > 0:
106 | for obj in diffs:
107 | # obj looks like: [, ]
108 | print(f"Missing file or file with wrong size: {obj[1]} on {targetDir}")
109 | return False
110 | return True
111 |
112 | # ----------------------------------------------------------------------
113 |
114 |
115 | def _main():
116 |
117 | ctx = getContext(getCommonArgs(
118 | 'Copy an SAP HANA DB snapshot the NFS server'
119 | ))
120 |
121 | hdbSid = ctx.cf.refsys.hdb.sidU
122 | hdbHost = ctx.cf.refsys.hdb.host
123 | hdbUser = ctx.cr.refsys.hdb.sidadm
124 |
125 | nfsHost = ctx.cf.nfs.host
126 | nfsUser = ctx.cr.nfs.user
127 | cmdSshNfs = CmdSsh(ctx, nfsHost.name, nfsUser)
128 | cmdSshDb = CmdSsh(ctx, hdbHost.name, hdbUser)
129 |
130 | logging.debug('Checking if HDB is stopped')
131 |
132 | # Check if HDB is stopped
133 |
134 | if getNumRunningSapProcs(ctx, 'hdb') != '0':
135 | fail(f"Error: HANA Database '{hdbSid}' is running on host {hdbHost.name}.\n"
136 | f"Stop the database then restart the nfs-hdb-copy step.")
137 |
138 | # Copy HDB content
139 |
140 | for obj in getHdbSubDirs(ctx):
141 |
142 | subDir = obj.path
143 | base = obj.base
144 | sourceDir = f"{base}/{subDir}/{hdbSid}"
145 | targetDir = f"{getHdbCopyBase(ctx)}/{subDir}/{hdbSid}"
146 |
147 | cmdSshNfs.run(f'mkdir -p "{targetDir}"')
148 |
149 | copyCmd = _getCopyCmd(cmdSshDb, cmdSshNfs, sourceDir, targetDir)
150 |
151 | print(f"Copying '{sourceDir}' to '{targetDir}' on host '{ctx.cf.nfs.host.name}'")
152 | CmdShell().run(copyCmd)
153 |
154 | if not _checkCopyStep(cmdSshDb, cmdSshNfs, sourceDir, targetDir):
155 | print(f"Copying '{sourceDir}' to '{targetDir}' was not successful.")
156 |
157 |
158 | # ----------------------------------------------------------------------
159 |
160 | if __name__ == '__main__':
161 | startup(_main)
162 |
--------------------------------------------------------------------------------
/tools/nfs-overlay-list:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # ------------------------------------------------------------------------
4 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | # ------------------------------------------------------------------------
18 |
19 | """ List availabe overlay shares on NFS server """
20 |
21 |
22 | try:
23 | # Global modules
24 |
25 | # None
26 |
27 | # Local modules
28 |
29 | from modules.args import getCommonArgs
30 | from modules.context import getContext
31 | from modules.nfstools import Overlays
32 | from modules.startup import startup
33 |
34 | except ModuleNotFoundError as mnfex:
35 | from modules.exceptions import setExceptHook
36 | setExceptHook()
37 | raise mnfex
38 |
39 |
40 | # Functions
41 |
42 |
43 | # ----------------------------------------------------------------------
44 |
45 | def _main():
46 |
47 | ctx = getContext(getCommonArgs(
48 | 'List availabe overlay shares on NFS server'
49 | ))
50 |
51 | print("Overlay Share" + " "*32 + "Added at")
52 | print("-"*63)
53 | for overlay in Overlays(ctx).get():
54 | print(overlay)
55 |
56 |
57 | # ----------------------------------------------------------------------
58 |
59 | if __name__ == '__main__':
60 | startup(_main)
61 |
--------------------------------------------------------------------------------
/tools/nfs-overlay-setup:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # ------------------------------------------------------------------------
4 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | # ------------------------------------------------------------------------
18 |
19 | """ Setup overlay file system on NFS server """
20 |
21 |
22 | try:
23 | # Global modules
24 |
25 | # None
26 |
27 | # Local modules
28 |
29 | from modules.args import (
30 | getCommonArgsParser,
31 | addArgOverlayUuid
32 | )
33 | from modules.context import getContext
34 | from modules.nfstools import Overlay
35 | from modules.startup import startup
36 | from modules.deployment import Deployment
37 |
38 | except ModuleNotFoundError as mnfex:
39 | from modules.exceptions import setExceptHook
40 | setExceptHook()
41 | raise mnfex
42 |
43 |
44 | # Functions
45 | def _getArgs():
46 | """ Get command line arguments """
47 | parser = getCommonArgsParser(
48 | 'Setup overlay file system on NFS server'
49 | )
50 | addArgOverlayUuid(parser, required = False)
51 | return parser.parse_args()
52 |
53 |
54 | # ----------------------------------------------------------------------
55 |
56 | def _main():
57 |
58 | ctx = getContext(_getArgs())
59 |
60 | overlayUuid = ctx.ar.overlay_uuid
61 |
62 | if not ctx.ar.overlay_uuid:
63 | overlayUuid = Deployment(ctx).get().overlayUuid
64 |
65 | print(f'{Overlay.create(ctx, overlayUuid).uuid}')
66 |
67 |
68 | # ----------------------------------------------------------------------
69 |
70 | if __name__ == '__main__':
71 | startup(_main)
72 |
--------------------------------------------------------------------------------
/tools/nfs-overlay-teardown:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # ------------------------------------------------------------------------
4 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | # ------------------------------------------------------------------------
18 |
19 | """ Tear down overlay file system on NFS server """
20 |
21 |
22 | try:
23 | # Global modules
24 |
25 | # None
26 |
27 | # Local modules
28 |
29 | from modules.args import (
30 | addArgOverlayUuid,
31 | getCommonArgsParser
32 | )
33 | from modules.context import getContext
34 | from modules.nfstools import Overlays
35 | from modules.startup import startup
36 |
37 | except ModuleNotFoundError as mnfex:
38 | from modules.exceptions import setExceptHook
39 | setExceptHook()
40 | raise mnfex
41 |
42 |
43 | # Functions
44 |
45 | def _getArgs():
46 | """ Get command line arguments """
47 | parser = getCommonArgsParser(
48 | 'Tear down overlay file system on NFS server'
49 | )
50 |
51 | addArgOverlayUuid(parser)
52 |
53 | return parser.parse_args()
54 |
55 |
56 | # ----------------------------------------------------------------------
57 |
58 | def _main():
59 |
60 | ctx = getContext(_getArgs())
61 |
62 | overlay = Overlays(ctx).find(ctx.ar.overlay_uuid)
63 |
64 | print(f"Deleting overlay share '{overlay}'")
65 |
66 | overlay.delete()
67 |
68 |
69 | # ----------------------------------------------------------------------
70 |
71 | if __name__ == '__main__':
72 | startup(_main)
73 |
--------------------------------------------------------------------------------
/tools/ocp-container-login:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # ------------------------------------------------------------------------
4 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | # ------------------------------------------------------------------------
18 |
19 | """ Interactively log into a container running in an OpenShift cluster """
20 |
21 |
22 | try:
23 | # Global modules
24 |
25 | # none
26 |
27 | # Local modules
28 |
29 | from modules.args import (
30 | addArgContainerFlavor,
31 | getCommonArgsParser,
32 | addArgAppName
33 | )
34 | from modules.context import getContext
35 | from modules.ocp import Ocp
36 | from modules.deployment import Deployments
37 | from modules.startup import startup
38 |
39 | except ModuleNotFoundError as mnfex:
40 | from modules.exceptions import setExceptHook
41 | setExceptHook()
42 | raise mnfex
43 |
44 |
45 | # Functions
46 |
47 | def _getArgs():
48 | """ Get command line arguments """
49 | parser = getCommonArgsParser(
50 | 'Interactively log into a container running in an OpenShift cluster'
51 | )
52 |
53 | addArgContainerFlavor(parser, ('di', 'ascs', 'hdb'), False)
54 | addArgAppName(parser)
55 |
56 | return parser.parse_args()
57 |
58 |
59 | # ----------------------------------------------------------------------
60 |
61 | def _main():
62 |
63 | ctx = getContext(_getArgs())
64 | ocp = Ocp(ctx)
65 | deployments = Deployments(ctx, ocp, deploymentType = ctx.cs.deployRunning)
66 | ocp.setAppName(deployments.getValidAppName())
67 |
68 | ocp.containerLogin()
69 |
70 |
71 | # ----------------------------------------------------------------------
72 |
73 | if __name__ == '__main__':
74 | startup(_main)
75 |
--------------------------------------------------------------------------------
/tools/ocp-container-run:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # ------------------------------------------------------------------------
4 | # Copyright 2021, 2022 IBM Corp. All Rights Reserved.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | # ------------------------------------------------------------------------
18 |
19 | """ Run a command in a container running in an OpenShift cluster """
20 |
21 |
22 | try:
23 | # Global modules
24 |
25 | import sys
26 |
27 | # Local modules
28 |
29 | from modules.args import (
30 | addArgContainerFlavor,
31 | getCommonArgsParser,
32 | addArgAppName
33 | )
34 | from modules.context import getContext
35 | from modules.ocp import Ocp
36 | from modules.startup import startup
37 | from modules.deployment import Deployments
38 | from modules.times import (
39 | printTimes,
40 | saveEndTime
41 | )
42 |
43 | except ModuleNotFoundError as mnfex:
44 | from modules.exceptions import setExceptHook
45 | setExceptHook()
46 | raise mnfex
47 |
48 |
49 | # Functions
50 |
51 | def _getArgs():
52 | """ Get command line arguments """
53 | parser = getCommonArgsParser(
54 | 'Log into a container running in an OpenShift cluster'
55 | )
56 |
57 | addArgContainerFlavor(parser, ('di', 'ascs', 'hdb'), False)
58 | addArgAppName(parser)
59 |
60 | parser.add_argument('command',
61 | help='Command to be executed inside the container'
62 | )
63 |
64 | return parser.parse_args()
65 |
66 |
67 | # ----------------------------------------------------------------------
68 |
69 | def _main():
70 |
71 | ctx = getContext(_getArgs())
72 |
73 | ocp = Ocp(ctx)
74 | deployments = Deployments(ctx, ocp, deploymentType = ctx.cs.deployRunning)
75 | ocp.setAppName(deployments.getValidAppName())
76 | containerName = ocp.getContainerName(ctx.ar.container_flavor)
77 | podName = ocp.getPodName()
78 | command = ctx.ar.command
79 |
80 | print(f"Executing command '{command}' in container '{containerName}' of pod '{podName}'",
81 | file=sys.stderr)
82 |
83 | res = ocp.containerRun(containerName, command)
84 |
85 | print(res.out, file=sys.stdout)
86 | print(res.err, file=sys.stderr)
87 |
88 | del ocp
89 |
90 | saveEndTime()
91 | printTimes()
92 |
93 | return res.rc
94 |
95 |
96 | # ----------------------------------------------------------------------
97 |
98 | if __name__ == '__main__':
99 | startup(_main)
100 |
--------------------------------------------------------------------------------
/tools/ocp-etc-hosts:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # ------------------------------------------------------------------------
4 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | # ------------------------------------------------------------------------
18 |
19 | """ Add OpenShift cluster domain entries to '/etc/hosts' """
20 |
21 |
22 | try:
23 | # Global modules
24 |
25 | import shutil
26 |
27 | # Local modules
28 |
29 | from modules.args import getCommonArgs
30 | from modules.context import getContext
31 | from modules.startup import startup
32 | from modules.fail import fail
33 |
34 | except ModuleNotFoundError as mnfex:
35 | from modules.exceptions import setExceptHook
36 | setExceptHook()
37 | raise mnfex
38 |
39 |
40 | # Functions
41 |
42 |
43 | # ----------------------------------------------------------------------
44 |
45 | def _main():
46 |
47 | ctx = getContext(getCommonArgs(
48 | "Add OpenShift cluster domain entries to '/etc/hosts'"
49 | ))
50 |
51 | ocpDomain = ctx.cf.ocp.domain
52 | helperIp = ctx.cf.ocp.helper.host.ip
53 |
54 | fqdns = (
55 | f'api.{ocpDomain}',
56 | f'oauth-openshift.apps.{ocpDomain}',
57 | f'default-route-openshift-image-registry.apps.{ocpDomain}',
58 | f'console-openshift-console.apps.{ocpDomain}',
59 | f'downloads-openshift-console.apps.{ocpDomain}'
60 | )
61 |
62 | etcHosts = '/etc/hosts'
63 | hostEntry = f'{helperIp}\t'+' '.join(fqdns)
64 |
65 | found = []
66 | try:
67 | # pylint: disable=invalid-name, unspecified-encoding
68 | with(open(etcHosts, 'r')) as fh:
69 | for line in fh.readlines():
70 | if line.strip().startswith('#'):
71 | continue
72 | if ocpDomain in line:
73 | found.append(line)
74 | except IOError:
75 | fail(f"Error reading from file {etcHosts}")
76 |
77 | if found:
78 | print(f"\nThe following line(s) in '{etcHosts}' already"
79 | f" contain(s) entries for domain '{ocpDomain}':\n")
80 | for line in found:
81 | print(f"{line}")
82 | print("Please check whether the following FQDN's are active and add all missing FQDN's:\n")
83 | for fqdn in fqdns:
84 | print(f" '{fqdn}'")
85 | print()
86 | else:
87 | backup = f'{etcHosts}.orig'
88 | shutil.copy2(etcHosts, backup)
89 | try:
90 | # pylint: disable=invalid-name, unspecified-encoding
91 | with open(etcHosts, 'a') as fh:
92 | print(f'\n# Added by ocp-etc-hosts:\n{hostEntry}', file=fh)
93 | except IOError:
94 | fail(f"Error writing to file {etcHosts}")
95 | print(f"\nAdded the following line to file '{etcHosts}'\n\n{hostEntry}\n")
96 | print(f"Stored backup of original '{etcHosts}' in '{backup}'\n")
97 |
98 |
99 | # ----------------------------------------------------------------------
100 |
101 | if __name__ == '__main__':
102 | startup(_main)
103 |
--------------------------------------------------------------------------------
/tools/ocp-hdb-secret-gen:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # ------------------------------------------------------------------------
4 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | # ------------------------------------------------------------------------
18 |
19 | """ Generate OpenShift HANA secret YAML file """
20 |
21 |
22 | try:
23 | # Global modules
24 |
25 | # None
26 |
27 | # Local modules
28 |
29 | from modules.args import getCommonArgs
30 | from modules.command import CmdShell
31 | from modules.context import getContext
32 | from modules.fail import fail
33 | from modules.ocp import Ocp
34 | from modules.startup import startup
35 | from modules.tools import genFileFromTemplate
36 |
37 | except ModuleNotFoundError as mnfex:
38 | from modules.exceptions import setExceptHook
39 | setExceptHook()
40 | raise mnfex
41 |
42 |
43 | # Functions
44 |
45 |
46 | # ----------------------------------------------------------------------
47 |
48 | def _main():
49 |
50 | ctx = getContext(getCommonArgs(
51 | 'Generate OpenShift HANA secret YAML file'
52 | ))
53 |
54 | secretName = ctx.cf.ocp.containers.di.secret
55 |
56 | if not secretName:
57 | fail(f"Secret name is not specified in file '{ctx.ar.config_file}'"
58 | f" - not generating secret")
59 |
60 | templateDir = f'{ctx.cf.build.repo.root}/openshift'
61 | templateFile = f'{templateDir}/secret.yaml.template'
62 | secretFile = f'{templateDir}/{secretName}.yaml'
63 |
64 | params = {
65 | 'secret-name': secretName,
66 | 'project': ctx.cf.ocp.project,
67 | 'User': ctx.cr.refsys.nws4.hdbconnect.name,
68 | 'Password': ctx.cr.refsys.nws4.hdbconnect.password
69 | }
70 |
71 | genFileFromTemplate(templateFile, secretFile, params)
72 |
73 | ocp = Ocp(ctx)
74 | result = ocp.ocApply(secretFile)
75 |
76 | if result.rc > 0:
77 | fail(result.err)
78 | CmdShell().run(f'rm -f {secretFile}')
79 | print(f'Secret {secretName} created for project {ctx.cf.ocp.project}')
80 |
81 | del ocp
82 |
83 |
84 | # ----------------------------------------------------------------------
85 |
86 | if __name__ == '__main__':
87 | startup(_main)
88 |
--------------------------------------------------------------------------------
/tools/ocp-login:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # ------------------------------------------------------------------------
4 | # Copyright 2021, 2022 IBM Corp. All Rights Reserved.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | # ------------------------------------------------------------------------
18 |
19 | """ Log into an OpenShift cluster as regular user or as admin user """
20 |
21 |
22 | try:
23 | # Global modules
24 |
25 | # None
26 |
27 | # Local modules
28 |
29 | from modules.args import getCommonArgsParser
30 | from modules.command import CmdShell
31 | from modules.context import getContext
32 | from modules.fail import fail
33 | from modules.ocp import Ocp
34 | from modules.startup import startup
35 |
36 | except ModuleNotFoundError as mnfex:
37 | from modules.exceptions import setExceptHook
38 | setExceptHook()
39 | raise mnfex
40 |
41 |
42 | # Functions
43 |
44 | def _getArgs():
45 | """ Get command line arguments """
46 | parser = getCommonArgsParser(
47 | 'Log into OCP'
48 | )
49 |
50 | parser.add_argument(
51 | '-u',
52 | '--user',
53 | required = False,
54 | action ='store_true',
55 | help = "Log into OCP as regular user"
56 | )
57 |
58 | parser.add_argument(
59 | '-a',
60 | '--admin',
61 | required = False,
62 | action ='store_true',
63 | help = "Log into OCP as admin user"
64 | )
65 |
66 | parser.add_argument(
67 | '--project-ignore',
68 | required = False,
69 | action ='store_true',
70 | help = "Errors during setProject are ignored if set to False"
71 | )
72 |
73 | return parser.parse_args()
74 |
75 |
76 | # ----------------------------------------------------------------------
77 |
78 | def _main():
79 |
80 | ctx = getContext(_getArgs())
81 |
82 | msg = "Specify excactly one of '-u' or '-a' ('-h' for help)"
83 |
84 | setProject = True
85 |
86 | if ctx.ar.project_ignore:
87 | setProject = False
88 |
89 | if ctx.ar.user:
90 | if not ctx.ar.admin:
91 | ocp = Ocp(ctx, login="user", logout=False, setProject = setProject)
92 | result = ocp.ocLogin()
93 | del ocp
94 | print(result.out)
95 | else:
96 | fail(msg)
97 |
98 | elif ctx.ar.admin:
99 | if not ctx.ar.user:
100 | ocp = Ocp(ctx, login="admin", logout=False, setProject = setProject)
101 | result = ocp.ocLogin()
102 | del ocp
103 | print(result.out)
104 | else:
105 | fail(msg)
106 |
107 | else:
108 | fail(msg)
109 |
110 | print(f'\nActive user: {CmdShell().run("oc whoami").out}\n')
111 |
112 |
113 | # ----------------------------------------------------------------------
114 |
115 | if __name__ == '__main__':
116 | startup(_main)
117 |
--------------------------------------------------------------------------------
/tools/ocp-pod-meminfo:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # ------------------------------------------------------------------------
4 | # Copyright 2021, 2022 IBM Corp. All Rights Reserved.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | # ------------------------------------------------------------------------
18 |
19 | """ Get SAP system memory consumption information """
20 |
21 |
22 | try:
23 | # Global modules
24 |
25 | import logging
26 | import math
27 | import time
28 |
29 | # Local modules
30 |
31 | from modules.args import (
32 | addCommonArgsString,
33 | getCommonArgsParser,
34 | addArgAppName,
35 | addArgLoop,
36 | addArgSleepTime
37 | )
38 | from modules.context import getContext
39 | from modules.ocp import Ocp
40 | from modules.deployment import Deployments
41 | from modules.quantity import Quantity
42 | from modules.startup import startup
43 | from modules.tools import getTimestamp
44 | from modules.fail import fail
45 |
46 | except ModuleNotFoundError as mnfex:
47 | from modules.exceptions import setExceptHook
48 | setExceptHook()
49 | raise mnfex
50 |
51 |
52 | # Functions
53 |
54 | def _getArgs():
55 | """ Get command line arguments """
56 | parser = getCommonArgsParser(
57 | 'Get SAP system memory consumption information'
58 | )
59 |
60 | addArgAppName(parser)
61 | addArgLoop(parser)
62 | addArgSleepTime(parser)
63 |
64 | return parser.parse_args()
65 |
66 |
67 | def _getMeminfoGiB(ocp, instance):
68 | # Returns a float, may return math.nan
69 |
70 | containerName = ocp.getContainerName(instance)
71 | meminfoCmd = "cat /sys/fs/cgroup/memory/memory.usage_in_bytes"
72 |
73 | res = ocp.containerRun(containerName, meminfoCmd)
74 |
75 | if res.rc != 0:
76 | logging.debug(f"Execution of command '{meminfoCmd}' in container '{containerName}'"
77 | f" returned rc {res.rc} (reason: {res.err})")
78 |
79 | try:
80 | memUsage = float(res.out.strip())/(1024**3)
81 | except ValueError:
82 | memUsage = math.nan
83 |
84 | return memUsage
85 |
86 |
87 | def _getLimitGiB(ctx, instance):
88 | # Returns an int
89 |
90 | limit = getattr(ctx.cf.ocp.containers, instance).resources.limits.memory
91 |
92 | # Scale the limit value to GiB
93 |
94 | return Quantity(limit).valueIntScaled("Gi")
95 |
96 |
97 | def _printResult(instance, memUsage, limit, percentage):
98 | # memUsage and percentage might be math.nan, if a problem occurred
99 | # during containerRun() in function _getMeminfoGiB()
100 |
101 | limitStr = f'{limit:4.1f}'
102 | memUsageStr = f'{memUsage:6.3f}' if not math.isnan(memUsage) else ' ?'
103 | percentageStr = f'{percentage:4.2f}' if not math.isnan(percentage) else ' ?'
104 | print(f'{instance.upper():10} {memUsageStr:7} {limitStr:5} {percentageStr}')
105 |
106 |
107 | # ----------------------------------------------------------------------
108 |
109 | def _main():
110 |
111 | ctx = getContext(_getArgs())
112 |
113 | addCommonArgsString(ctx)
114 |
115 | instances = ctx.config.getContainerFlavors()
116 | instances.remove('init')
117 |
118 | ocp = Ocp(ctx)
119 |
120 | deployments = Deployments(ctx, ocp, deploymentType = ctx.cs.deployRunning)
121 |
122 | appNames = None
123 | if not ctx.ar.app_name:
124 | appNames = deployments.getAppNames()
125 | else:
126 | appName = deployments.getValidAppName()
127 | appNames = [appName]
128 |
129 | if len(appNames) == 0:
130 | fail("No running deployments found.")
131 |
132 | while True:
133 | if ctx.ar.loop:
134 | print(getTimestamp(withDecorator=True))
135 |
136 | print(' Used Limit Used')
137 | print('Instance GiB GiB %')
138 | print('='*30)
139 |
140 | first = True
141 |
142 | for appName in appNames:
143 | ocp.setAppName(appName)
144 |
145 | if not first:
146 | print('-'*len('Deployment ' + appName))
147 | first = False
148 | print(f'App-Name {appName}')
149 | print('-'*len('Deployment ' + appName))
150 |
151 | for instance in instances:
152 | memUsage = _getMeminfoGiB(ocp, instance)
153 | limit = _getLimitGiB(ctx, instance)
154 | _printResult(instance, memUsage, limit, memUsage * 100 / limit)
155 |
156 | if ctx.ar.loop:
157 | time.sleep(ctx.ar.sleep_time)
158 | else:
159 | break
160 |
161 | del ocp
162 |
163 | # ----------------------------------------------------------------------
164 |
165 |
166 | if __name__ == '__main__':
167 | startup(_main)
168 |
--------------------------------------------------------------------------------
/tools/ocp-pod-status:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # ------------------------------------------------------------------------
4 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | # ------------------------------------------------------------------------
18 |
19 | """ Get the status of a pod """
20 |
21 |
22 | try:
23 | # Global modules
24 |
25 | import time
26 |
27 | # Local modules
28 |
29 | from modules.args import (
30 | getCommonArgsParser,
31 | addArgAppName,
32 | addArgLoop,
33 | addArgSleepTime
34 | )
35 | from modules.context import getContext
36 | from modules.ocp import Ocp
37 | from modules.deployment import Deployments
38 | from modules.startup import startup
39 | from modules.tools import getTimestamp
40 | from modules.fail import fail
41 |
42 | except ModuleNotFoundError as mnfex:
43 | from modules.exceptions import setExceptHook
44 | setExceptHook()
45 | raise mnfex
46 |
47 |
48 | # Functions
49 |
50 | def _getArgs():
51 | """ Get command line arguments """
52 | parser = getCommonArgsParser(
53 | 'Get the status of a pod'
54 | )
55 | addArgAppName(parser)
56 | addArgLoop(parser)
57 | addArgSleepTime(parser)
58 | return parser.parse_args()
59 |
60 |
61 | def _printHeader():
62 | print('Pod' + ' '*40 + 'Status')
63 | print('-'*50)
64 |
65 | # ----------------------------------------------------------------------
66 |
67 |
68 | def _main():
69 |
70 | ctx = getContext(_getArgs())
71 |
72 | ocp = Ocp(ctx)
73 |
74 | deployments = Deployments(ctx, ocp, deploymentType = ctx.cs.deployDeployed)
75 |
76 | appNames = None
77 |
78 | if not ctx.ar.app_name:
79 | appNames = deployments.getAppNames()
80 | else:
81 | appName = deployments.getValidAppName()
82 | appNames = [appName]
83 |
84 | if len(appNames) == 0:
85 | fail("No deployments found.")
86 |
87 | while True:
88 | if ctx.ar.loop:
89 | print(getTimestamp(withDecorator=True))
90 | _printHeader()
91 |
92 | if len(appNames) > 0:
93 | for appName in appNames:
94 | ocp.setAppName(appName)
95 | podName = ocp.getPodName()
96 | podStatus = ocp.getPodStatus()
97 |
98 | if not podName:
99 | print(f"No pod found for {appName}")
100 | else:
101 | print(f'{podName}' + ' '*7 + f'{podStatus}')
102 | else:
103 | print("None")
104 | break
105 | if ctx.ar.loop:
106 | time.sleep(ctx.ar.sleep_time)
107 | else:
108 | break
109 |
110 |
111 | # ----------------------------------------------------------------------
112 |
113 | if __name__ == '__main__':
114 | startup(_main)
115 |
--------------------------------------------------------------------------------
/tools/ocp-service-account-gen:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # ------------------------------------------------------------------------
4 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | # ------------------------------------------------------------------------
18 |
19 | """ Generate YAML file for service account creation """
20 |
21 |
22 | try:
23 | # Global modules
24 |
25 | # None
26 |
27 | # Local modules
28 |
29 | from modules.args import (
30 | addArgOutputFile,
31 | getCommonArgsParser
32 | )
33 | from modules.context import getContext
34 | from modules.fail import fail
35 | from modules.ocp import Ocp
36 | from modules.startup import startup
37 | from modules.command import CmdShell
38 |
39 |
40 | except ModuleNotFoundError as mnfex:
41 | from modules.exceptions import setExceptHook
42 | setExceptHook()
43 | raise mnfex
44 |
45 |
46 | # Functions
47 |
48 | def _getArgs():
49 | """ Get command line arguments """
50 | parser = getCommonArgsParser(
51 | 'Generate YAML file for service account creation'
52 | )
53 |
54 | addArgOutputFile(parser, None)
55 |
56 | return parser.parse_args()
57 |
58 |
59 | # ----------------------------------------------------------------------
60 |
61 | def _main():
62 |
63 | ctx = getContext(_getArgs())
64 |
65 | outputFile = ctx.ar.output_file
66 | if not outputFile:
67 | outputFile = ctx.cf.ocp.sa.file
68 |
69 | try:
70 | # pylint: disable=invalid-name, unspecified-encoding
71 | with open(outputFile, 'w') as fh:
72 | print(f'apiVersion: v1\n'
73 | f'kind: ServiceAccount\n'
74 | f'metadata:\n'
75 | f' name: {ctx.cf.ocp.sa.name}\n'
76 | f' namespace: {ctx.cf.ocp.project}',
77 | file=fh
78 | )
79 | except IOError:
80 | fail(f"Error writing to file {outputFile}")
81 |
82 | ocp = Ocp(ctx)
83 | result = ocp.ocApply(outputFile)
84 | del ocp
85 |
86 | CmdShell().run(f'rm -f {outputFile}')
87 | if result.rc > 0:
88 | fail(result.err)
89 | else:
90 | print(result.out)
91 |
92 |
93 | # ----------------------------------------------------------------------
94 |
95 | if __name__ == '__main__':
96 | startup(_main)
97 |
--------------------------------------------------------------------------------
/tools/ssh-key-gen:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # ------------------------------------------------------------------------
4 | # Copyright 2021, 2022 IBM Corp. All Rights Reserved.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | # ------------------------------------------------------------------------
18 |
19 | """ Generate a passphrase-less SSH private / public key pair """
20 |
21 |
22 | try:
23 | # Global modules
24 |
25 | from pathlib import Path
26 | import getpass
27 | import socket
28 | import subprocess
29 |
30 | # Local modules
31 |
32 | from modules.args import getCommonArgsParser
33 | from modules.context import getContext
34 | from modules.startup import startup
35 | from modules.tools import readInput
36 |
37 | except ModuleNotFoundError as mnfex:
38 | from modules.exceptions import setExceptHook
39 | setExceptHook()
40 | raise mnfex
41 |
42 |
43 | # Functions
44 |
45 | def _getArgs():
46 | """ Get command line arguments """
47 | parser = getCommonArgsParser(
48 | 'Generate a passphrase-less SSH private / public key pair'
49 | )
50 |
51 | parser.add_argument(
52 | '-i',
53 | '--ssh-id',
54 | metavar = '',
55 | required = False,
56 | help = "Path to the SSH ID private key file"
57 | )
58 |
59 | return parser.parse_args()
60 |
61 |
62 | def _getDefaultId(ctx):
63 |
64 | sshId = ctx.ar.ssh_id
65 |
66 | if not sshId:
67 | sshId = ctx.cr.build.user.sshid
68 |
69 | if not sshId:
70 | sshId = f'{Path.home()}/.ssh/id_rsa'
71 |
72 | return sshId
73 |
74 |
75 | def _getDefaultComment():
76 | return f'{getpass.getuser()}@{socket.gethostname()}'
77 |
78 |
79 | # ----------------------------------------------------------------------
80 |
81 | def _main():
82 |
83 | ctx = getContext(_getArgs(), withConfig=False)
84 |
85 | sshId = readInput('Enter file in which to save the key',
86 | _getDefaultId(ctx), False, False, False)
87 |
88 | comment = readInput('Enter comment which is stored with the key',
89 | _getDefaultComment(), False, False, False)
90 |
91 | subprocess.run(['ssh-keygen', '-f', sshId, '-C', comment], check=False)
92 |
93 |
94 | # ----------------------------------------------------------------------
95 |
96 | if __name__ == '__main__':
97 | startup(_main)
98 |
--------------------------------------------------------------------------------
/tools/tool-shortcuts:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # ------------------------------------------------------------------------
4 | # Copyright 2022 IBM Corp. All Rights Reserved.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | # ------------------------------------------------------------------------
18 |
19 | SCRIPT_PATH=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd)
20 | SCRIPT_NAME=$(basename "${BASH_SOURCE[0]}")
21 | export SOOS_TOOLS_PATH=$(dirname $SCRIPT_PATH)
22 |
23 | if [[ $# == 1 && "$1" == "--add" ]]; then
24 | if [[ "$(grep -c $SCRIPT_NAME ~/.bashrc)" == "0" ]]; then
25 | SCRIPT_FQN=$SCRIPT_PATH/$SCRIPT_NAME
26 | printf "\n# Added soos $SCRIPT_NAME ($(date))\nsource $SCRIPT_FQN\n" >> ~/.bashrc
27 | echo "Added command \"source $SCRIPT_NAME\" in ~/.bashrc"
28 | else
29 | echo "Command \"$SCRIPT_NAME\" already found in ~/.bashrc"
30 | fi
31 | fi
32 | if [[ -d $SOOS_TOOLS_PATH/tools ]]; then
33 | SOOS_TOOLS_LIST=$(ls $SOOS_TOOLS_PATH/tools|grep -v -E "modules|venv-setup|codingstyle|$SCRIPT_NAME|^creds|^config")
34 | fi
35 | for TOOL in $SOOS_TOOLS_LIST; do
36 | eval "function soos-$TOOL()
37 | { export ARGS=\$@ && sh -c 'tool-shortcut $TOOL; exit \$?'
38 | }"
39 | export -f soos-$TOOL
40 | done
41 | function tool-shortcut()
42 | {
43 | echo "Using SOOS_TOOLS_PATH=$SOOS_TOOLS_PATH"
44 | if [[ "$1" == "" ]];then
45 | echo "Error: Call tool-shortcut not direct." && return 1
46 | fi
47 | if [[ ! -x $SOOS_TOOLS_PATH/tools/$1 ]]; then
48 | echo "Error: Tool $SOOS_TOOLS_PATH/tools/$1 not found in dir $SOOS_TOOLS_PATH/tools, change environment variable SOOS_TOOLS_PATH." && return 1
49 | fi
50 | if [[ ! -r $SOOS_TOOLS_PATH/venv/bin/activate ]]; then
51 | cd $SOOS_TOOLS_PATH && $SOOS_TOOLS_PATH/tools/venv-setup || return $?
52 | fi
53 | if [[ -r $SOOS_TOOLS_PATH/config.yaml ]]; then
54 | if [[ -r $SOOS_TOOLS_PATH/creds.yaml ]]; then
55 | cd $SOOS_TOOLS_PATH && source $SOOS_TOOLS_PATH/venv/bin/activate && \
56 | $SOOS_TOOLS_PATH/tools/$1 $ARGS -c $SOOS_TOOLS_PATH/config.yaml -q $SOOS_TOOLS_PATH/creds.yaml || return $?
57 | elif [[ -r $SOOS_TOOLS_PATH/creds.yaml.gpg ]]; then
58 | cd $SOOS_TOOLS_PATH && source $SOOS_TOOLS_PATH/venv/bin/activate && \
59 | $SOOS_TOOLS_PATH/tools/$1 $ARGS -c $SOOS_TOOLS_PATH/config.yaml -q $SOOS_TOOLS_PATH/creds.yaml.gpg || return $?
60 | else
61 | echo "Error: Credential file $SOOS_TOOLS_PATH/creds.yaml or $SOOS_TOOLS_PATH/creds.yaml.gpg not found, run tools/creds first." && return 1
62 | fi
63 | else
64 | echo "Error: Config file $SOOS_TOOLS_PATH/config.yaml not found, run tools/config first." && return 1
65 | fi
66 | }
67 | export -f tool-shortcut
68 |
--------------------------------------------------------------------------------
/tools/venv-setup:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # ------------------------------------------------------------------------
4 | # Copyright 2021, 2022 IBM Corp. All Rights Reserved.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | # ------------------------------------------------------------------------
18 |
19 | # Set up a virtual Python environment with all modules
20 | # required to run the tools in directory tools/
21 |
22 | set -euo pipefail
23 |
24 | function gen_doc_gfm() {
25 |
26 | cat <<'EOF'
27 | ## Tool `venv-setup`
28 |
29 | ### Usage
30 |
31 | `venv-setup`
32 |
33 | ### Purpose
34 |
35 | Set up a Python virtual environment with all modules that are required
36 | to run the tools.
37 |
38 | Once the virtual environment is prepared, activate it by executing
39 | `source venv/bin/activate` out of the repository clone root directory
40 | before running any of the other tools.
41 |
42 | EOF
43 | }
44 |
45 | if [ $# -eq 1 ]; then
46 | if [ $1 == '--gen-doc-gfm' ]; then
47 | gen_doc_gfm
48 | exit 0
49 | fi
50 | fi
51 |
52 | if [ $# -ge 1 ]; then
53 | echo
54 | echo "$0:"
55 | echo
56 | echo " Set up a virtual Python environment with all modules"
57 | echo " required to run the tools in directory tools/"
58 | echo
59 | echo "Doesn't require any command line arguments"
60 | echo
61 | exit 1
62 | fi
63 |
64 | # Check OS version
65 |
66 | major () { echo ${1%.*}; }
67 | minor () { echo ${1#*.}; }
68 |
69 | MIN_RHEL="8.2"
70 |
71 | source /etc/os-release # Sets ${ID} and ${VERSION_ID}
72 |
73 | if [ ${ID} == "rhel" ]; then
74 | if [ $(major ${VERSION_ID}) -lt $(major ${MIN_RHEL}) \
75 | -o $(major ${VERSION_ID}) -eq $(major ${MIN_RHEL}) \
76 | -a $(minor ${VERSION_ID}) -lt $(minor ${MIN_RHEL}) ]; then
77 | echo "Minimal required RHEL version to run this script: ${MIN_RHEL}"
78 | exit 1
79 | fi
80 | fi
81 |
82 | # Ensure required RPM packages on OS level are installed
83 |
84 | echo
85 | echo "Checking / installing required RPM packages"
86 | echo
87 |
88 | PKG_REQ=""
89 | PKG_REQ="${PKG_REQ} python38"
90 |
91 | PKG_INST=""
92 |
93 | for PKG in ${PKG_REQ}; do
94 | echo -n "${PKG} - "
95 | if dnf list installed ${PKG} >/dev/null 2>&1; then
96 | echo "installed"
97 | else
98 | echo "missing"
99 | PKG_INST="${PKG_INST} ${PKG}"
100 | fi
101 | done
102 |
103 | if [ -n "${PKG_INST}" ]; then
104 | INSTALL_CMD="dnf install -y ${PKG_INST}"
105 |
106 | if [ $(id -u) != 0 ]; then
107 | echo "Provide root user password for installing package(s)${PKG_INST}"
108 | su root -c "${INSTALL_CMD}"
109 | else
110 | ${INSTALL_CMD}
111 | fi
112 | fi
113 |
114 | # Set up the virtual environment
115 |
116 | echo
117 | echo "Setting up virtual environment"
118 | echo
119 |
120 | PYTHON="/usr/bin/env python3.8"
121 | VENV="$(pwd)/venv"
122 |
123 | ${PYTHON} -m venv "${VENV}"
124 | source ${VENV}/bin/activate
125 |
126 | pip install --upgrade pip
127 |
128 | MODULES=""
129 | MODULES="${MODULES} autopep8" # tools/codingstyle only
130 | MODULES="${MODULES} pyaml"
131 | MODULES="${MODULES} pylint" # tools/codingstyle only
132 | MODULES="${MODULES} python-gnupg"
133 | MODULES="${MODULES} termcolor"
134 |
135 | pip install --no-cache-dir ${MODULES}
136 |
137 | SEP='------------------------------------------------------------------------'
138 |
139 | echo ${SEP}
140 | echo
141 | echo ' Setup of virtual python environment finished.'
142 | echo
143 | echo ' Execute'
144 | echo
145 | echo ' source ./venv/bin/activate'
146 | echo
147 | echo ' to activate the virtual environment'
148 | echo
149 | echo ' Execute'
150 | echo
151 | echo ' deactivate'
152 | echo
153 | echo ' inside the virtual environment to deactivate the environment.'
154 | echo
155 | echo ${SEP}
156 |
--------------------------------------------------------------------------------
/tools/verify-config:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # ------------------------------------------------------------------------
4 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | # ------------------------------------------------------------------------
18 |
19 | """ Verify parameter settings in configuration YAML file """
20 |
21 |
22 | try:
23 | # Global modules
24 |
25 | # None
26 |
27 | # Local modules
28 |
29 | from modules.args import getCommonArgsParser
30 | from modules.context import getContext
31 | from modules.fail import fail
32 | from modules.startup import startup
33 | from modules.verify import Verify
34 |
35 | except ModuleNotFoundError as mnfex:
36 | from modules.exceptions import setExceptHook
37 | setExceptHook()
38 | raise mnfex
39 |
40 |
41 | # Functions
42 |
43 | def _getArgs():
44 | """ Get command line arguments """
45 | parser = getCommonArgsParser(
46 | 'Verify parameter settings in configuration YAML file'
47 | )
48 | parser.add_argument(
49 | '-func',
50 | '--function',
51 | required = False,
52 | help = 'single test mode for function'
53 | )
54 | return parser.parse_args()
55 |
56 |
57 | # ----------------------------------------------------------------------
58 |
59 | def _main():
60 |
61 | ctx = getContext(_getArgs(), failOnDiscoveryError=True)
62 | print('-'*72)
63 | print(f"Verifying configuration parameters in file '{ctx.ar.config_file}'")
64 | print('-'*72)
65 |
66 | if not Verify(ctx).verify():
67 | print('-'*72)
68 | fail('VERIFICATION ERRORS OCCURED - SEE ABOVE MESSAGES FOR MORE DETAILS\n')
69 |
70 | print('-'*72)
71 | print('Verification successful.\n')
72 |
73 |
74 | # ----------------------------------------------------------------------
75 |
76 | if __name__ == '__main__':
77 | startup(_main)
78 |
--------------------------------------------------------------------------------
/tools/verify-ocp-settings:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # ------------------------------------------------------------------------
4 | # Copyright 2020, 2022 IBM Corp. All Rights Reserved.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | # ------------------------------------------------------------------------
18 |
19 | """ Verify OpenShift cluster setup related settings """
20 |
21 |
22 | try:
23 | # Global modules
24 |
25 | # None
26 |
27 | # Local modules
28 |
29 | from modules.args import getCommonArgsParser
30 | from modules.context import getContext
31 | from modules.fail import fail
32 | from modules.startup import startup
33 | from modules.verify import VerifyOcp
34 |
35 | except ModuleNotFoundError as mnfex:
36 | from modules.exceptions import setExceptHook
37 | setExceptHook()
38 | raise mnfex
39 |
40 | # Functions
41 |
42 |
43 | def _getArgs():
44 | """ Get command line arguments """
45 | parser = getCommonArgsParser(
46 | 'Verify OpenShift cluster setup related settings'
47 | )
48 | parser.add_argument(
49 | '-func',
50 | '--function',
51 | required = False,
52 | help = 'single test mode for function'
53 | )
54 | return parser.parse_args()
55 |
56 |
57 | # ----------------------------------------------------------------------
58 |
59 |
60 | def _main():
61 |
62 | ctx = getContext(_getArgs())
63 |
64 | # Check settings for OpenShift project and service account
65 |
66 | print('-'*72)
67 | print('Verifying OpenShift Cluster Setup related settings')
68 | print('-'*72)
69 |
70 | if not VerifyOcp(ctx).verify():
71 | print('-'*72)
72 | fail('VERIFICATION ERRORS OCCURED - SEE ABOVE MESSAGES FOR MORE DETAILS\n')
73 |
74 | print('-'*72)
75 | print('Verification successful.\n')
76 |
77 |
78 | # ----------------------------------------------------------------------
79 |
80 | if __name__ == '__main__':
81 | startup(_main)
82 |
--------------------------------------------------------------------------------