Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
systemsmanagement:Ardana:8:CentOS:7.3
ardana-cobbler
ardana-cobbler-8.0+git.1660773402.d845a45.obscpio
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File ardana-cobbler-8.0+git.1660773402.d845a45.obscpio of Package ardana-cobbler
07070100000000000081A400000000000000000000000162FD641A00000083000000000000000000000000000000000000003500000000ardana-cobbler-8.0+git.1660773402.d845a45/.gitreview[gerrit] host=gerrit.suse.provo.cloud port=29418 project=ardana/cobbler-ansible.git defaultremote=ardana defaultbranch=stable/pike 07070100000001000081A400000000000000000000000162FD641A0000279F000000000000000000000000000000000000003200000000ardana-cobbler-8.0+git.1660773402.d845a45/LICENSE Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. 07070100000002000081A400000000000000000000000162FD641A00000A8D000000000000000000000000000000000000003400000000ardana-cobbler-8.0+git.1660773402.d845a45/README.md(c) Copyright 2015-2017 Hewlett Packard Enterprise Development LP (c) Copyright 2017-2018 SUSE LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. README ====== This repo contains the following roles: - COBBLER: Cobbler server role The verbs: - configure - install - start - populate The operations: - deploy Repo structure: ``` ├── bm-reimage.yml ├── cobbler-bm-verify.yml ├── cobbler-deploy.yml ├── cobbler-power-down.yml ├── cobbler-power-status.yml ├── cobbler-power-up.yml ├── cobbler-provision.yml ├── cobbler-set-diskboot-all.yml ├── cobbler-set-pxeboot-all.yml ├── cobbler-wait-for-shutdown.yml ├── cobbler-wait-for-ssh.yml ├── library │ ├── bmconfig │ └── ipmi ├── README.md └── roles └── cobbler ├── defaults │ └── main.yml ├── files │ ├── cobbler.conf │ ├── configure_network.sh │ ├── fence_ipmitool.template │ └── validate_yaml ├── tasks │ ├── check-ipmi-connectivity.yml │ ├── configure.yml │ ├── get-nodelist.yml │ ├── install.yml │ ├── populate.yml │ ├── power-cycle-all.yml │ ├── power-down-all.yml │ ├── power-up-all.yml │ ├── set-diskboot-all.yml │ ├── set-pxeboot-all.yml │ ├── set-vars.yml │ ├── start.yml │ ├── verify-bm-install.yml │ ├── wait-for-shutdown.yml │ └── wait-for-ssh.yml ├── templates │ ├── cobbler.dhcp.template.j2 │ ├── dhcpd.conf.j2 │ ├── dhcpd-start-limit.conf.j2 │ ├── grub.cfg.j2 │ ├── hlinux-server-vm.preseed.j2 │ ├── isc-dhcp-server.j2 │ ├── rhel73-anaconda-ks.cfg.j2 │ └── settings.j2 └── vars └── main.yml ``` 07070100000003000081ED00000000000000000000000162FD641A00000C95000000000000000000000000000000000000003B00000000ardana-cobbler-8.0+git.1660773402.d845a45/ardanaencrypt.py#!/usr/bin/env python # # A utility to encrypt passwords for auxiliary Ardana OpenStack # systems like IPMI. # # (c) Copyright 2015 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import os from subprocess import PIPE, Popen encryption_env = 'ARDANA_USER_PASSWORD_ENCRYPT_KEY' legacy_encryption_env = 'HOS_USER_PASSWORD_ENCRYPT_KEY' class aes256: prefix = '@ardana_aes256@' legacy_prefix = '@hos_aes256@' def __init__(self, key): pass def encrypt(self, raw): return "" def decrypt(self, cooked): return "" class openssl: prefix = '@ardana@' legacy_prefix = '@hos@' def __init__(self, key=None): pass def _get_env_key_name(self): if encryption_env in os.environ and os.environ[encryption_env]: return encryption_env elif (legacy_encryption_env in os.environ and os.environ[legacy_encryption_env]): return legacy_encryption_env else: return encryption_env def delegate(self, cmd, value): # Note that I'm passing the environment variable's name to the # subprocess, not its value. argv = ('/usr/bin/openssl', 'aes-256-cbc', '-a', cmd, '-pass', 'env:%s' % self._get_env_key_name()) p = Popen(argv, close_fds=True, stdin=PIPE, stdout=PIPE, stderr=PIPE) result = p.communicate(input=value) if p.returncode != 0: errmsg = result[1].strip() if errmsg.startswith('bad decrypt'): errmsg = 'incorrect encryption key' elif (errmsg.startswith('error reading input file') or errmsg.startswith('bad magic number')): errmsg = 'bad input data' raise OSError('openssl: %s' % errmsg) return result[0].strip() def encrypt(self, raw): return self.delegate('-salt', raw) def decrypt(self, cooked): # openssl expects a newline at the end of the string. if cooked[-1] != '\n': cooked += '\n' return self.delegate('-d', cooked) def main(): import getpass import sys obj = openssl() if len(sys.argv) > 1 and sys.argv[1] == '-d': value = getpass.getpass('encrypted value? ') if value.startswith(obj.prefix): value = value[len(obj.prefix):] elif value.startswith(obj.legacy_prefix): value = value[len(obj.legacy_prefix):] x = obj.decrypt(value) print x else: value = getpass.getpass('unencrypted value? ') x = obj.encrypt(value) print obj.prefix + x if __name__ == '__main__': main() 07070100000004000081A400000000000000000000000162FD641A000003AD000000000000000000000000000000000000004500000000ardana-cobbler-8.0+git.1660773402.d845a45/bm-assert-power-is-off.yml# # (c) Copyright 2015 Hewlett Packard Enterprise Development LP # (c) Copyright 2017-2018 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # --- - include: bm-target-all-nodes.yml when: dynamic_targets_created is undefined - hosts: dynamic_targets max_fail_percentage: 100 roles: - cobbler tasks: - include: roles/cobbler/tasks/assert-power-is-off.yml - include: roles/cobbler/tasks/assert-nodes-are-not-pingable.yml 07070100000005000081A400000000000000000000000162FD641A000004D9000000000000000000000000000000000000003A00000000ardana-cobbler-8.0+git.1660773402.d845a45/bm-diskboot.yml# # (c) Copyright 2015 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # --- - include: bm-target-no-default.yml when: dynamic_targets_created is undefined # Tasks that can safely be done in parallel. - hosts: dynamic_targets roles: - cobbler tasks: - include: roles/cobbler/tasks/set-diskboot.yml when: set_bootdev # Tasks that can't. - hosts: dynamic_targets serial: 1 roles: - cobbler tasks: - include: roles/cobbler/tasks/netboot-off.yml when: set_bootdev - include: bm-power-up.yml - hosts: localhost tasks: - name: The nodes have been instructed to boot from disk pause: minutes=1 - include: bm-wait-for-ssh.yml 07070100000006000081A400000000000000000000000162FD641A0000034E000000000000000000000000000000000000003D00000000ardana-cobbler-8.0+git.1660773402.d845a45/bm-power-cycle.yml# # (c) Copyright 2015 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # --- - include: bm-target-no-default.yml when: dynamic_targets_created is undefined - hosts: dynamic_targets serial: 10 roles: - cobbler tasks: - include: roles/cobbler/tasks/power-cycle.yml 07070100000007000081A400000000000000000000000162FD641A0000036D000000000000000000000000000000000000003C00000000ardana-cobbler-8.0+git.1660773402.d845a45/bm-power-down.yml# # (c) Copyright 2015 Hewlett Packard Enterprise Development LP # (c) Copyright 2017-2018 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # --- - include: bm-target-no-default.yml when: dynamic_targets_created is undefined - hosts: dynamic_targets max_fail_percentage: 100 serial: 10 roles: - cobbler tasks: - include: roles/cobbler/tasks/power-down.yml 07070100000008000081A400000000000000000000000162FD641A00000409000000000000000000000000000000000000003E00000000ardana-cobbler-8.0+git.1660773402.d845a45/bm-power-status.yml# # (c) Copyright 2015 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # --- - include: pbstart.yml vars: playbook_name: "bm-power-status.yml" - include: bm-target-all-nodes.yml when: dynamic_targets_created is undefined - hosts: dynamic_targets roles: - cobbler tasks: - include: roles/cobbler/tasks/get-power-status.yml - debug: msg="{{ ipmi_connectivity.power }}" - include: pbfinish.yml vars: playbook_name: "bm-power-status.yml" 07070100000009000081A400000000000000000000000162FD641A0000034B000000000000000000000000000000000000003A00000000ardana-cobbler-8.0+git.1660773402.d845a45/bm-power-up.yml# # (c) Copyright 2015 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # --- - include: bm-target-no-default.yml when: dynamic_targets_created is undefined - hosts: dynamic_targets serial: 10 roles: - cobbler tasks: - include: roles/cobbler/tasks/power-up.yml 0707010000000A000081A400000000000000000000000162FD641A00000643000000000000000000000000000000000000003B00000000ardana-cobbler-8.0+git.1660773402.d845a45/bm-provision.yml# # (c) Copyright 2015-2016 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # --- - include: bm-target-netboot-nodes.yml when: dynamic_targets_created is undefined - hosts: localhost become: yes roles: - cobbler tasks: - shell: date +%Y%m%d%H%M%S > {{ local_timestamp_file }} # Cobbler cli is not thread safe so have to do these one at a time. - hosts: dynamic_targets serial: 1 roles: - cobbler tasks: - include: roles/cobbler/tasks/netboot-on.yml when: set_bootdev - hosts: dynamic_targets serial: "{{ bm_batch_size | default(20) }}" roles: - cobbler tasks: - name: "Starting reimage batch" pause: seconds: 10 - include: roles/cobbler/tasks/set-pxeboot.yml when: set_bootdev - include: roles/cobbler/tasks/power-cycle.yml - name: "These nodes have been instructed to install over PXE" pause: minutes: 3 - include: roles/cobbler/tasks/wait-for-shutdown.yml - include: roles/cobbler/tasks/set-diskboot.yml when: set_bootdev 0707010000000B000081A400000000000000000000000162FD641A00000512000000000000000000000000000000000000003900000000ardana-cobbler-8.0+git.1660773402.d845a45/bm-reimage.yml# # (c) Copyright 2015 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # --- - include: pbstart.yml vars: playbook_name: "bm-reimage.yml" - include: bm-target-netboot-nodes.yml when: dynamic_targets_created is undefined - hosts: localhost tasks: - name: The nodes listed above will be reimaged pause: minutes=1 - include: bm-power-down.yml - hosts: localhost tasks: - name: Waiting for the nodes to power off pause: minutes=4 - include: bm-assert-power-is-off.yml - include: bm-provision.yml - hosts: localhost tasks: - name: Pausing to allow nodes to fully shut down pause: minutes=1 - include: bm-diskboot.yml - include: pbfinish.yml vars: playbook_name: "bm-reimage.yml" 0707010000000C000081A400000000000000000000000162FD641A000002EF000000000000000000000000000000000000004200000000ardana-cobbler-8.0+git.1660773402.d845a45/bm-target-all-nodes.yml# # (c) Copyright 2015 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # --- - hosts: localhost roles: - cobbler tasks: - include: roles/cobbler/tasks/target-all-nodes.yml 0707010000000D000081A400000000000000000000000162FD641A000002F2000000000000000000000000000000000000004600000000ardana-cobbler-8.0+git.1660773402.d845a45/bm-target-netboot-nodes.yml# # (c) Copyright 2015 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # --- - hosts: localhost roles: - cobbler tasks: - include: roles/cobbler/tasks/target-netboot-nodes.yml 0707010000000E000081A400000000000000000000000162FD641A0000036B000000000000000000000000000000000000004300000000ardana-cobbler-8.0+git.1660773402.d845a45/bm-target-no-default.yml# # (c) Copyright 2015 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # --- - hosts: localhost roles: - cobbler tasks: # There's no default set of nodes for this command; needs to be # set by the caller, or on the command line by the user. - include: roles/cobbler/tasks/get-nodelist.yml 0707010000000F000081A400000000000000000000000162FD641A0000035A000000000000000000000000000000000000003800000000ardana-cobbler-8.0+git.1660773402.d845a45/bm-verify.yml# # (c) Copyright 2015 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # # Playbook used by vagrant to help provision virtual machines # You should not need to run this manually! --- - hosts: resources roles: - cobbler tasks: - include: roles/cobbler/tasks/verify-bm-install.yml 07070100000010000081A400000000000000000000000162FD641A00000346000000000000000000000000000000000000004300000000ardana-cobbler-8.0+git.1660773402.d845a45/bm-wait-for-shutdown.yml# # (c) Copyright 2015 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # --- - include: bm-target-all-nodes.yml when: dynamic_targets_created is undefined - hosts: dynamic_targets roles: - cobbler tasks: - include: roles/cobbler/tasks/wait-for-shutdown.yml 07070100000011000081A400000000000000000000000162FD641A00000341000000000000000000000000000000000000003E00000000ardana-cobbler-8.0+git.1660773402.d845a45/bm-wait-for-ssh.yml# # (c) Copyright 2015 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # --- - include: bm-target-all-nodes.yml when: dynamic_targets_created is undefined - hosts: dynamic_targets roles: - cobbler tasks: - include: roles/cobbler/tasks/wait-for-ssh.yml 07070100000012000081A400000000000000000000000162FD641A000005C7000000000000000000000000000000000000003D00000000ardana-cobbler-8.0+git.1660773402.d845a45/cobbler-deploy.yml# # (c) Copyright 2015-2017 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # --- - include: pbstart.yml vars: playbook_name: "cobbler-deploy.yml" - hosts: localhost roles: - cobbler - deployer-setup vars_prompt: - name: ardanauser_password prompt: "Enter the password that will be used to access provisioned nodes" private: yes confirm: yes when: ardanauser_password is not defined tasks: - include: roles/cobbler/tasks/set-vars.yml - include: roles/cobbler/tasks/install.yml - include: roles/cobbler/tasks/configure.yml - include: roles/cobbler/tasks/start.yml - include: roles/cobbler/tasks/get-baremetal-info.yml - include: roles/cobbler/tasks/populate-rhel.yml - include: roles/cobbler/tasks/populate-sles.yml - include: roles/cobbler/tasks/populate.yml - include: pbfinish.yml vars: playbook_name: "cobbler-deploy.yml" 07070100000013000081A400000000000000000000000162FD641A0000031C000000000000000000000000000000000000004200000000ardana-cobbler-8.0+git.1660773402.d845a45/cobbler-reconfigure.yml# # (c) Copyright 2016 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # --- - hosts: localhost roles: - cobbler tasks: - include: roles/cobbler/tasks/set-vars.yml - include: roles/cobbler/tasks/reconfig-dhcp.yml 07070100000014000041ED00000000000000000000000262FD641A00000000000000000000000000000000000000000000003200000000ardana-cobbler-8.0+git.1660773402.d845a45/library07070100000015000081A400000000000000000000000162FD641A000019FA000000000000000000000000000000000000003B00000000ardana-cobbler-8.0+git.1660773402.d845a45/library/bmconfig#!/usr/bin/env python # # An Ansible module to parse baremetalConfig.yml (or json) # # (c) Copyright 2015-2017 Hewlett Packard Enterprise Development LP # (c) Copyright 2017-2018 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. DOCUMENTATION = ''' --- module: bmconfig author: Joe Fegan short_description: Returns baremetal information from servers.yml description: - Isolates parsing of baremetal information from the playbooks that consume it. - By default this module returns a struct containing all information available. options: field: required: false description: - Returns just the value of this field, on stdout. node: required: false description: - Used with "field", returns just the value for this specific node. ''' EXAMPLES = ''' - bmconfig: file={{ baremetal_config }} - bmconfig: file={{ baremetal_config }} field=id - bmconfig: file={{ baremetal_config }} field=role node=ccn-0001 ''' import yaml class BmConfig(object): name = 'bmconfig' # The field that contains the node name. idfield = 'id' # The field that contains the primary IP of the node. ipaddrfield = 'ip_addr' # If this field is not present the node will be ignored. # Intended as a means of identifying nodes in the model # that we don't control e.g. pre-built VMs or the like. ignorefield = 'ilo_ip' # Old field names and their modern equivalents. fieldmap = { 'node_name': 'id', 'node_type': 'role', 'pxe_ip_addr': 'ip_addr', 'pxe_mac_addr': 'mac_addr', 'kopts_extra': 'kopt_extras' } def __init__(self, module): self.module = module try: self.fname = module.params["file"] self.field = module.params["field"] self.node = module.params["node"] except ValueError as e: self.fail(msg="%s: bad value %s" % (self.name, str(e))) def fail(self, **kwargs): return self.module.fail_json(**kwargs) def succeed(self, **kwargs): return self.module.exit_json(**kwargs) def execv(self, cmd, **kwargs): return self.module.run_command(cmd, **kwargs) # This doesn't do much yet, but in time it will handle more complex # data file locations and varying content. def load_data(self): y = yaml.safe_load(file(self.fname)) if 'servers' in y: key = 'servers' elif 'baremetal_servers' in y: # Backward compatibility key = 'baremetal_servers' else: raise AttributeError('no servers info found in %s' % self.fname) self.data = [self.map_fields(item) for item in y[key]] if 'baremetal' in y: key = 'baremetal' elif 'baremetal_network' in y: # Backward compatibility key = 'baremetal_network' else: raise AttributeError('no network info found in %s' % self.fname) self.network = self.map_fields(y[key]) if 'cidr' in self.network: if 'subnet' in self.network or 'netmask' in self.network: raise KeyError('cannot specify both cidr and subnet/netmask') self.network['subnet'], width = self.network['cidr'].split('/') shift = 32 - int(width) mask = 0xffffffff >> shift << shift self.network['netmask'] = "%d.%d.%d.%d" % \ ((mask & 0xff000000) >> 24, (mask & 0x00ff0000) >> 16, (mask & 0x0000ff00) >> 8, mask & 0x000000ff) else: binstr = "".join(["{0:08b}".format(int(x)) for x in self.network['netmask'].split('.')]) width = len(binstr.rstrip('0')) self.network['cidr'] = "%s/%s" % (self.network['subnet'], width) cmd = ['/bin/bash', '-c', 'ip a | awk \'/inet / {sub("/.*","",$2) ; print $2}\''] rc, out, err = self.execv(cmd, check_rc=True) self.localips = out.strip().split('\n') # Handle backward compatibility of field names. def map_fields(self, srv): result = dict() for (key, value) in srv.iteritems(): try: result[self.fieldmap[key]] = value except KeyError: # Ansible doesn't accept - in variable names. result[key.replace('-','_')] = value return result def action_field(self): lst = list() for srv in self.data: if self.node is None or srv[self.idfield] == self.node: lst.append(srv[self.field]) result = dict(stdout="\n".join(lst)) self.succeed(**result) def action_struct(self): lst = list() svrids = list() whoami = 'localhost' for srv in self.data: if self.ignorefield not in srv: continue lst.append(srv) svrids.append(srv[self.idfield]) if srv[self.ipaddrfield] in self.localips: whoami = srv[self.idfield] facts = {'bminfo': dict(servers=lst,network=self.network,server_ids=svrids,whoami=whoami)} result = dict(ansible_facts=facts) self.succeed(**result) def add_default(self): for srv in self.data: if "boot_from_san" not in srv: srv["boot_from_san"] = False if "fcoe_interfaces" not in srv: srv["fcoe_interfaces"] = [] if "persistent_interfaces" not in srv: srv["persistent_interfaces"] = [] if "distro_id" not in srv: srv["distro_id"] = "sles12sp3-x86_64" def execute(self): self.load_data() self.add_default() if self.field: return self.action_field() else: return self.action_struct() def main(): module = AnsibleModule( argument_spec=dict( file=dict(required=True), field=dict(required=False), node=dict(required=False) ) ) mod = BmConfig(module) return mod.execute() from ansible.module_utils.basic import * main() 07070100000016000081A400000000000000000000000162FD641A00001628000000000000000000000000000000000000003800000000ardana-cobbler-8.0+git.1660773402.d845a45/library/hpilo#!/usr/bin/env python # # (c) Copyright 2018 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # # An Ansible module to allow playbooks to communicate with # HP ILO devices using SMASH CLP commands. DOCUMENTATION = ''' --- module: hpiLO author: Wayne Okuma short_description: Issue a SMASH CLP command to HP-ILO hosts description: - Issue SMASH CLP commands to an HP ILO server. - HPILO credentials and network addresses can be specified in a JSON or YAML file, or can be retrieved from Cobbler. options: name: required: true description: - Name of the node to manage. credsfile: required: false description: - The Credentals file which contains the HP ILO user, password and IP-Address of the HP ILO server by the name specified (e.g., the servers.yml file). command: required: true description: - the SMASH CLP command to issue to the server. ''' EXAMPLES = ''' - hpilo: name=compute2 command="show /system1/bootconfig1 oemhp_bootmode" - hpilo: name=compute2 credsfile="/tmp/nodeinfo.yml" \ command="set /system1/bootconfig1/oemhp_uefibootsource4 bootorder=1" ''' import os import pexpect import re import time import yaml # Load the local module import imp ardanaencrypt = imp.load_source('ardanaencrypt', './ardanaencrypt.py') openssl_prefix = ardanaencrypt.openssl.prefix def decrypt(value): if value.startswith(openssl_prefix): decrypter = hosencrypt.openssl else: return value obj = decrypter() return obj.decrypt(value[len(obj.prefix):]) def parse_command_result_status(command_result): for line in command_result.strip().splitlines(): if line.find("status=") != -1: return line.strip("status=") return("-1") class HPilo(object): def __init__(self, module): self.module = module try: self.node = module.params["name"] self.credsfile = module.params["credsfile"] self.command = module.params["command"] except ValueError as e: self.module.fail_json(msg="hpilo: " + str(e)) def cobbler_creds(self, node): cmd = ["sudo", "cobbler", "system", "dumpvars", "--name=%s" % node] rc, out, err = self.execv(cmd, check_rc=True) creds = dict() translation = {"power_address": "ip", "power_user": "user", "power_pass": "password"} for line in out.splitlines(): key, value = line.split(" : ") if key in translation: if value == "": break creds[translation[key]] = value if len(translation) != len(creds): self.fail(msg="hpilo: missing creds for %s in cobbler" % node) return creds def file_creds(self, fname): data = yaml.safe_load(file(fname)) creds = dict() if "servers" in data: field = "servers" ident = "id" iloip = "ilo-ip" ilouser = "ilo-user" ilopassword = "ilo-password" else: # Backward compatibility field = "baremetal_servers" ident = "node_name" iloip = "ilo_ip" ilouser = "ilo_user" ilopassword = "ilo_password" for srv in data[field]: if srv[ident] == self.node: creds["ip"] = srv[iloip] creds["user"] = srv[ilouser] creds["password"] = decrypt(srv[ilopassword]) break return creds def get_creds(self, node): if self.credsfile: return self.file_creds(self.credsfile) else: return self.cobbler_creds(node) def execute(self): ssh_disable_host_key = '-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no ' try: creds = self.get_creds(self.node) child = pexpect.spawn('ssh ' + ssh_disable_host_key + creds["user"] + '@' + creds["ip"]) child.expect('password') child.sendline(creds["password"]) child.expect('</>hpiLO->') child.sendline(self.command) child.expect('</>hpiLO->') command_result = child.before child.sendline('exit') result = dict( changed=False, stdout=command_result, stderr='' ) print(command_result) rc = parse_command_result_status(command_result) if rc == '0': result['changed']=True self.module.exit_json(**result) else: self.module.fail_json(msg='command failed', **result) except Exception as e: self.module.fail_json(msg='hpilo: processing failed ' + str(e)) def main(): module = AnsibleModule( argument_spec=dict( name=dict(required=True), command=dict(required=True), credsfile=dict(required=False), ) ) hpilo = HPilo(module) return hpilo.execute() from ansible.module_utils.basic import * main() 07070100000017000081ED00000000000000000000000162FD641A00004AB8000000000000000000000000000000000000004000000000ardana-cobbler-8.0+git.1660773402.d845a45/library/hpilosetup.py#!/usr/bin/env python # # Copyright 2014 Hewlett-Packard Development Company, L.P. # Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from __future__ import print_function import argparse import json import sys # Need six > 1.3.0 (1.8.0 works) import six import urllib3 try: urllib3.disable_warnings(urllib3.exceptions.InsecurePlatformWarning) except: pass from proliantutils.ilo import ribcl from httplib import HTTPSConnection from base64 import b64encode def do_raw_cmd(cmd, hostname, path, headers, data=None): conn = HTTPSConnection(host=hostname, strict=True) conn.request(cmd, path, headers=headers, body=data) resp = conn.getresponse().read() return resp def do_raw_get(hostname, path, headers): return do_raw_cmd('GET', hostname, path, headers) def do_raw_patch(hostname, path, headers, data): return do_raw_cmd('PATCH', hostname, path, headers, data) def set_propagate_time(ilo_client, val='N'): """ Set PROPAGATE_TIME_TO_HOST configuration item If this is set, then the iLO can set the time on the host on powerup, and, if the iLO is misconfigured, the host can encounter time jumps that cause issues with other apps, including at installation time. """ import xml.etree.ElementTree as etree xml = ilo_client._create_dynamic_xml('MOD_GLOBAL_SETTINGS', 'RIB_INFO', 'write') if six.PY2: child_iterator = xml.getiterator() else: child_iterator = xml.iter() for child in child_iterator: if child.tag == 'MOD_GLOBAL_SETTINGS': etree.SubElement(child, 'PROPAGATE_TIME_TO_HOST', VALUE=val) d = ilo_client._request_ilo(xml) data = ilo_client._parse_output(d) return data def get_propagate_time(ilo_client): """ Get PROPAGATE_TIME_TO_HOST configuration item """ info = ilo_client._execute_command('GET_GLOBAL_SETTINGS', 'RIB_INFO', 'read') res = info['GET_GLOBAL_SETTINGS']['PROPAGATE_TIME_TO_HOST'] return res['VALUE'] def set_tz(ilo_client, val): """ Set TIMEZONE configuration item """ import xml.etree.ElementTree as etree xml = ilo_client._create_dynamic_xml('MOD_NETWORK_SETTINGS', 'RIB_INFO', 'write') if six.PY2: child_iterator = xml.getiterator() else: child_iterator = xml.iter() for child in child_iterator: if child.tag == 'MOD_NETWORK_SETTINGS': etree.SubElement(child, 'TIMEZONE', VALUE=val) d = ilo_client._request_ilo(xml) data = ilo_client._parse_output(d) return data def error(msg): print(msg, file=sys.stderr) def verbose(msg): print(msg, file=sys.stderr) def output(msg): print(msg, file=sys.stderr) def setup_ilo(user, password, host, tz=None, bootmode=None, check_privs=True, check_propagate=True, boot_from_dev=None, do_verbose=True, debug=False): """ Connect to a host to valdiate its iLO settings. If the host doesnt support ilo/ribcl return 1 else report on firmware settings optionally check the privileges optionally set the timezone check NTP propagate setting check bootmode and optionally set it """ # Make a connection try: if (do_verbose): verbose('Connecting to %s' % host) ilo_client = ribcl.IloClient(host, user, password) # if we cant get at least power status we stop. ilo_client.get_host_power_status() except ribcl.IloConnectionError as e: error('Error(%s) connecting to %s: %s' % (type(e), host, e)) return 1 except Exception as e: error('Error(%s) connecting to %s: %s' % (type(e), host, e)) return 1 auth = 'BASIC ' + b64encode(user + ':' + password) headers = {'Authorization': auth, 'Content-Type': 'application/json'} mp = None try: if (do_verbose): verbose('Getting f/w version') info = ilo_client._execute_command('GET_FW_VERSION', 'RIB_INFO', 'read') if (debug): verbose(info.keys()) for key in info['GET_FW_VERSION'].keys(): output("%s: %s" % (key, info['GET_FW_VERSION'][key])) # e.g.: 'iLO3' or 'iLO4' mp = info['GET_FW_VERSION'].get('MANAGEMENT_PROCESSOR') except Exception as e: error('Error(%s) getting f/w version from %s: %s' % (type(e), host, e)) # Get the user privileges - fail if the check was requested and # if the required privileges arent present. # Its useful to fail early if you get a user without Administrator privs if check_privs: try: if (do_verbose): verbose('Getting user info') user_dict = {'USER_LOGIN': user} info = ilo_client._execute_command('GET_USER', 'USER_INFO', 'read', user_dict) if ('CONFIG_ILO_PRIV' in info['GET_USER']): if (info['GET_USER']['CONFIG_ILO_PRIV'] != 'Y'): error('Insufficient privs: CONFIG_ILO_PRIV is required') for key in info['GET_USER'].keys(): verbose("%s: %s" % (key, info['GET_USER'][key])) return 1 else: # Maybe its an older iLO? pass except Exception as e: error('Error(%s) getting user info from %s: %s' % (type(e), host, e)) # Get the timezone - dont fail if it cant be read. # UTC is NOT a valid timezone for iLO. Africa/Accra? if (do_verbose): verbose('Getting network settings') try: info = ilo_client._execute_command('GET_NETWORK_SETTINGS', 'RIB_INFO', 'read') now_tz = info['GET_NETWORK_SETTINGS']['TIMEZONE']['VALUE'] verbose('Current timezone is: %s' % tz) if (tz and now_tz != tz): if (do_verbose): verbose('Setting timezone=%s' % tz) try: set_tz(ilo_client, tz) except Exception as e: error('Error(%s) setting tz %s for %s: %s' % (type(e), args.tz, args.host, e)) except Exception as e: error('Error(%s) getting tz for %s: %s' % (type(e), host, e)) # Get the propagate flag - dont fail if it cant be read. if (do_verbose): verbose('Getting global settings') try: propagate = get_propagate_time(ilo_client) verbose('Current time propagate setting is: %s' % propagate) if check_propagate and propagate != 'N': if (do_verbose): verbose('Setting time propagate OFF') try: set_propagate_time(ilo_client, 'N') except Exception as e: error('Error(%s) setting time propagate %s for %s: %s' % (type(e), host, e)) propagate = get_propagate_time(ilo_client) if propagate != 'N': verbose('Failed setting time propagate OFF') except Exception as e: error('Error(%s) getting time propagate for %s: %s' % (type(e), host, e)) # bootmode = 'LEGACY' current_mode = None pending_mode = None if mp and mp == 'iLO4': try: # GET_SUPPORTED_BOOT_MODE = LEGACY_ONLY, UEFI_ONLY, # LEGACY_UEFI, UNKNOWN supported_modes = ilo_client.get_supported_boot_mode() if (do_verbose): verbose("Supported modes are: %s" % supported_modes) # Possible return values are LEGACY, UEFI, or UNKNOWN current_mode = ilo_client.get_current_boot_mode() pending_mode = ilo_client.get_pending_boot_mode() if (do_verbose): verbose("Current boot mode is: %s" % current_mode) verbose("Pending boot mode is: %s" % pending_mode) if bootmode is not None: if pending_mode != bootmode: try: if (do_verbose): verbose("Setting *next* boot mode as: %s" % bootmode) ilo_client.set_pending_boot_mode(bootmode) except Exception as e: error('Error(%s) setting boot_mode to %s for %s: %s' % (type(e), bootmode, host, e)) except ribcl.IloError as e: if 'Feature not supported' in repr(e): error(e) except Exception as e: error('Error(%s) getting current boot mode for %s: %s' % (type(e), host, e)) _process_bootmode(ilo_client, host, headers, boot_from_dev, current_mode, pending_mode, do_verbose, debug) return 0 def _update_boot_order(ilo_client, host, headers, boot_order, boot_from_dev, current_mode): if current_mode == 'UEFI': offset = 0 for item in boot_order: if item == boot_from_dev: break offset += 1 if offset < len(boot_order) and offset != 0: tosend = {'PersistentBootConfigOrder': boot_order} master = tosend['PersistentBootConfigOrder'][offset] del tosend['PersistentBootConfigOrder'][offset] tosend['PersistentBootConfigOrder'].insert(0, master) resp = do_raw_patch(host, '/rest/v1/Systems/1/BIOS/Boot/Settings', headers, json.dumps(tosend)) result = json.loads(resp) if 'Messages' in result: for message in result['Messages']: if "MessageID" in message: verbose('Boot order update completed with status: %s' % message["MessageID"]) else: error('Unexpected status received while setting boot order') # expect this response # {"Messages":[{"MessageID":"iLO.0.10.SystemResetRequired"}], # "Name":"Extended Error Information", # "Type":"ExtendedError.0.9.5"} # # and so no point in trying to GET the current value after setting # to check as the system must be reset. else: verbose("boot_from_dev value (%s) is invalid" % boot_from_dev) else: offset = 0 for item in boot_order: if item['value'] == boot_from_dev: break offset += 1 if offset < len(boot_order) and offset != 0: master = boot_order[offset] del boot_order[offset] boot_order.insert(0, master) resp = ilo_client._get_persistent_boot() # ilo_client.update_persistent_boot will fail on 'USB', so use _set resp = ilo_client._set_persistent_boot( [item['value'] for item in boot_order if item['value'] != 'Unknown']) else: verbose("boot_from_dev value is either invalid or the default") def _list_uefi_boot_order(host, headers, do_verbose=True, debug=True): try: # Use the HP Rest interface to get and set boot order newbios = json.loads(do_raw_get(host, '/rest/v1/Systems/1/BIOS/Boot', headers)) if debug: verbose(newbios) for source in newbios['PersistentBootConfigOrder']: verbose("\t%s" % (source)) verbose('Valid boot sources are:') for source in newbios['BootSources']: verbose('\t%s: \"%s\"' % (source['StructuredBootString'], source['BootString'])) return newbios['PersistentBootConfigOrder'] except: pass def _list_legacy_boot_order(ilo_client, current_mode, do_verbose=True, debug=True): try: info = ilo_client._execute_command('GET_PERSISTENT_BOOT', 'SERVER_INFO', 'read') boot_order = info['PERSISTENT_BOOT']['DEVICE'] # boot_order is an ordered list of dicts with key 'value' # if 'DESCRIPTION' in boot_order[0]: then its a UEFI list if debug: verbose(json.dumps(boot_order, indent=2)) for item in boot_order: if current_mode == 'UEFI' and 'DESCRIPTION' in item: verbose("\t%s: %s" % (item['value'], item['DESCRIPTION'])) else: verbose("\t%s" % (item['value'])) return boot_order except: pass def _process_bootmode(ilo_client, host, headers, boot_from_dev, current_mode, pending_mode, do_verbose, debug): # Note on boot settings: # LEGACY BIOS and UEFI BIOS treat boot order separately and differently # # LEGACY BIOS: # The boot order can be set via ilo to a list # e.g. CDROM USB HDD NETWORK # The relative order of the network devices can be set using # a POST to a json interface # NETWORK1 NETWORK2 NETWORK3 ... # **not implemented** # allowable values are CDROM USB HDD NETWORK # It is NOT possible in LEGACY BIOS to *programmatically* # list devices # determine what device is NETWORK1,2 etc # enable a device for network boot # determine what devices have links connected # # UEFI # The boot order can be found via ilo api call GET_PERSISTENT_BOOT # The boot order can be found via json api call /json/boot_order # The boot order can be set via ilo api call # The boot order can be set explictly using POST to a json interface # Boot000A, etc ... # HD.Emb.1.3 NIC.FlexLOM.1.1.IPv4 NIC.LOM.1.1.IPv4 # These names can be mapped to devices via GET_PERSISTENT_BOOT # It is NOT possible in UEFI mode to *programmatically* # enable a device for network boot # determine what devices have links connected # # This request can be used to list all network devices, BUT doesnt return # link status, or if network boot enabled, just port, location and mac addr resp = ilo_client.get_host_health_data() nic_info = resp['GET_EMBEDDED_HEALTH_DATA'].get('NIC_INFORMATION', None) if nic_info: nics = nic_info['NIC'] else: nics = [] verbose('No NIC information for this host') if debug: verbose(json.dumps(nics, indent=2)) if len(nics) > 0: verbose('Found NICs on system') for item in nics: verbose('\tMAC: %s LOCATION: %s PORT: %s' % (item['MAC_ADDRESS']['VALUE'], item['LOCATION']['VALUE'], item['NETWORK_PORT']['VALUE'])) if boot_from_dev: try: if (do_verbose): verbose('Listing persistent boot order:') if current_mode == 'UEFI': boot_order = _list_uefi_boot_order(host, headers, do_verbose, debug) else: boot_order = _list_legacy_boot_order(ilo_client, current_mode, do_verbose, debug) if boot_from_dev != '?': if (do_verbose): verbose('Updating boot device') if pending_mode != current_mode: error("Changing boot order when pending boot mode (%s) is " "not the same as current mode (%s) is not possible" % (pending_mode, current_mode)) else: _update_boot_order(ilo_client, host, headers, boot_order, boot_from_dev, current_mode) except Exception as e: error('Error(%s) getting persistent boot for %s: %s' % (type(e), host, e)) return 0 if __name__ == '__main__': parser = argparse.ArgumentParser(description='Utility to setup HP iLO') parser.add_argument('-U', '--user', required=True, help='Username') parser.add_argument('-P', '--password', required=True, help='Password') parser.add_argument('-H', '--host', required=True, help='Host') parser.add_argument('-c', '--check_privs', action='store_true', help='Check iLO privs') parser.add_argument('-t', '--check_propagate_time', action='store_true', help='Check iLO propagate time to BIOS setting is OFF') parser.add_argument('-z', '--tz', default=None, help='TimeZone') parser.add_argument('-m', '--bootmode', default=None, help='iLO4 bootmode') parser.add_argument('-d', '--debug', action='store_true', help='Debug') parser.add_argument('-v', '--verbose', action='store_true', help='Verbose') parser.add_argument('-n', '--boot_from_dev', default=None, help="""Device from which to boot. For LEGACY systems the allowable values are CDROM HDD USB NETWORK. This utility cannot determine the Nic names associated with NETWORK, or the order of the NETWORK (PXE-enabled) Nics. For UEFI systems the allowable values can be determined from the system by running this command with a value for this argument of ? For example: 'NIC.FlexLOM.1.1.IPv4'""") parser.add_argument('--boot-from-dev', dest='boot_from_dev') args = parser.parse_args() if (args.debug): # Need six > 1.3.0 (1.8.0 works) verbose(six.__version__) setup_ilo(args.user, args.password, args.host, args.tz, args.bootmode, args.check_privs, args.check_propagate_time, args.boot_from_dev, args.verbose, args.debug) sys.exit(0) 07070100000018000081A400000000000000000000000162FD641A00002DE8000000000000000000000000000000000000003700000000ardana-cobbler-8.0+git.1660773402.d845a45/library/ipmi#!/usr/bin/env python # # An Ansible module to allow playbooks to communicate with # remote devices using IPMI. # # (c) Copyright 2015 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. DOCUMENTATION = ''' --- module: ipmi author: Joe Fegan short_description: Issue IPMI commands to network targets description: - Issue IPMI commands to systems that are accessible over the network from this node. - IPMI credentials and network addresses can be specified in a JSON or YAML file, or can be retrieved from Cobbler. options: name: required: true description: - Name of the node to manage. retry_interval: required: false default: 5 description: - Interval in seconds between retries. retry_max: required: false default: 12 description: - Max number of retries. power: required: false description: - An IPMI power command to be sent to the target. choices: [ "on", "off", "status" ] bootdev: required: false description: - A bootdev command to be sent to the target. - For example to boot from PXE first, disk first, etc. options: required: false description: - Options for the bootdev command. passthru: required: false description: - Any artibrary IPMI command to be sent to the target. - This is a fallback for obscure commands. Any that you use regularly should be wrapped up in a proper handler like power and bootdev. ''' EXAMPLES = ''' - ipmi: name=cpn-0001 power=off - ipmi: name=cpn-0001 bootdev=pxe options=persistent - ipmi: name=cpn-0001 credsfile="/tmp/nodeinfo.yml" passthru="mc reset warm" ''' import os import re import time import yaml # Load the local module import imp ardanaencrypt = imp.load_source('ardanaencrypt', './ardanaencrypt.py') openssl_prefix = ardanaencrypt.openssl.prefix legacy_prefix = ardanaencrypt.openssl.legacy_prefix def decrypt(value): prefix = None if value.startswith(openssl_prefix): decrypter = ardanaencrypt.openssl prefix = openssl_prefix elif value.startswith(legacy_prefix): decrypter = ardanaencrypt.openssl prefix = legacy_prefix else: return value obj = decrypter() return obj.decrypt(value[len(prefix):]) # Take something like "Chassis Power Control: Up/On" and return # the last word. The exact format of the input varies a lot. def parse_power_status(raw_status): return raw_status.split()[-1].split("/")[-1].lower() # Something like "Set Boot Device to disk". def parse_bootdev(raw_status): return raw_status.split()[-1].lower() # Take an HP Moonshot server locator like c12n4 and return a list containing # the extra IPMI addressing flags needed to send commands to that node. def parse_moonshot(locator): r = re.compile('^c([0-9]+)n([0-9]+)$') m = r.match(locator.strip().lower()) if not m: raise ValueError('unable to parse Moonshot id "%s"' % locator) (cartridge, node) = m.groups() transit = 0x80 + (int(cartridge) * 2) target = 0x70 + (int(node) * 2) return ['-B0', '-b7', '-T%#02x' % transit, '-t%#02x' % target] class Ipmi(object): def __init__(self, module): self.module = module self.target = None try: self.node = module.params["name"] self.credsfile = module.params["credsfile"] self.bootdev = module.params["bootdev"] self.options = module.params["options"] self.power = module.params["power"] self.passthru = module.params["passthru"] self.retry_interval = int(module.params["retry_interval"]) self.retry_max = int(module.params["retry_max"]) self.retries = int(module.params["retries"]) self.delay = int(module.params["delay"]) secs = module.params["sleep"] if not secs: self.sleep = None elif secs[-1] == "m": self.sleep = 60.0 * float(secs[:-1]) elif secs[-1] == "s": self.sleep = float(secs[:-1]) else: self.sleep = float(secs) except ValueError as e: self.fail(msg="ipmi: " + str(e)) def fail(self, **kwargs): return self.module.fail_json(**kwargs) def succeed(self, **kwargs): if self.sleep: time.sleep(self.sleep) return self.module.exit_json(**kwargs) def execv(self, cmd, **kwargs): return self.module.run_command(cmd, **kwargs) def cobbler_creds(self, node): cmd = ["sudo", "cobbler", "system", "dumpvars", "--name=%s" % node] rc, out, err = self.execv(cmd, check_rc=True) creds = dict() translation = {"power_address": "ip", "power_user": "user", "power_pass": "password"} for line in out.splitlines(): key, value = line.split(" : ") if key in translation: if value == "": break creds[translation[key]] = value if len(translation) != len(creds): self.fail(msg="ipmi: missing creds for %s in cobbler" % node) return creds def file_creds(self, fname): data = yaml.safe_load(file(fname)) creds = dict() if "servers" in data: field = "servers" ident = "id" iloip = "ilo-ip" ilouser = "ilo-user" ilopassword = "ilo-password" iloextras = "ilo-extras" else: # Backward compatibility field = "baremetal_servers" ident = "node_name" iloip = "ilo_ip" ilouser = "ilo_user" ilopassword = "ilo_password" iloextras = "ilo_extras" for srv in data[field]: if srv[ident] == self.node: creds["ip"] = srv[iloip] creds["user"] = srv[ilouser] creds["password"] = decrypt(srv[ilopassword]) if "moonshot" in srv: creds["moonshot"] = parse_moonshot(srv["moonshot"]) if iloextras in srv: creds["extras"] = srv[iloextras].split(" ") break return creds def get_creds(self, node): if self.credsfile: return self.file_creds(self.credsfile) else: return self.cobbler_creds(node) def set_target(self, node): creds = self.get_creds(node) # we're in a subprocess, so our environment should be private. os.environ["IPMI_PASSWORD"] = creds["password"] self.ip = creds["ip"] self.target = ["ipmitool", "-I", "lanplus", "-E", "-N", str(self.retry_interval), "-R", str(self.retry_max), "-U", creds["user"], "-H", self.ip] if "moonshot" in creds: self.target += creds["moonshot"] if "extras" in creds: self.target += creds["extras"] # This will send any ipmi command you like to the target and return its # stdout and stderr. I thought twice about providing this, because the # proper thing to do is to create custom handlers for specific actions # (like action_power below), but in the end passthru is pragmatic for # rarely used commands. It can't populate the Ansible "changed" field # because it has no idea what the command was. def action_passthru(self, action): cmd = self.target + action.split() rc, out, err = self.execv(cmd, check_rc=True) result = dict(rc=rc, stdout=out, stderr=err) self.succeed(**result) # This sends ipmi "power" commands to the target and returns a proper # "changed" status to Ansible by inspecting the before and after state. # It also parses stdout of the reply and returns a simple "on" or "off" # value, which is much easier to cope with in a playbook. def action_power(self, action): attempts = 0 rc = -1 cmd = self.target + ["power", "status"] while rc != 0 and attempts <= self.retries: attempts = attempts + 1 if attempts > 1: time.sleep(self.delay) rc, out, err = self.execv(cmd, check_rc=False) if rc != 0: self.fail(msg="%s (%d attempts) %s" % (self.ip, attempts, err)) before = parse_power_status(out) desired = action.strip().lower() if desired == "status" or desired == before: after = before else: cmd = self.target + ["power", action] rc, out, err = self.execv(cmd, check_rc=True) after = parse_power_status(out) if attempts > 1: out = "%s: success after %d attempts" % (self.ip, attempts) else: out = "" result = dict(stdout=out, power=after, changed=(before != after)) self.succeed(**result) # This sends ipmi "bootdev" commands to the target. It also parses stdout # of the reply and returns a simple value, which is much easier to cope # with in a playbook. I can't find a way to query the current bootdev # through IPMI so can't return a proper "changed" status to Ansible. def action_bootdev(self, action): cmd = self.target + ["chassis", "bootdev", action] if self.options: cmd.append("options=%s" % self.options) rc, out, err = self.execv(cmd, check_rc=True) dev = parse_bootdev(out) if len(dev) == 0: self.fail(msg="ipmi: can't parse bootdev response", stdout=out, stderr=err) result = dict(bootdev=dev, options=self.options, changed=True) self.succeed(**result) def execute(self): try: self.set_target(self.node) action = self.bootdev if action: return self.action_bootdev(action) action = self.power if action: return self.action_power(action) action = self.passthru if action: return self.action_passthru(action) self.fail(msg="usage: ipmi name=<node> <action>") except Exception as e: self.fail(msg="ipmi: " + str(e)) def main(): module = AnsibleModule( argument_spec=dict( name=dict(required=True), credsfile=dict(required=False), bootdev=dict(required=False, default=None), options=dict(required=False, default=None), power=dict(required=False, default=None), passthru=dict(required=False, default=None), sleep=dict(required=False, default=None), retry_interval=dict(required=False, default=5), retry_max=dict(required=False, default=12), retries=dict(required=False, default=0), delay=dict(required=False, default=0) ) ) ipmi = Ipmi(module) return ipmi.execute() from ansible.module_utils.basic import * main() 07070100000019000081A400000000000000000000000162FD641A00000E29000000000000000000000000000000000000003D00000000ardana-cobbler-8.0+git.1660773402.d845a45/library/match-cidr#!/usr/bin/env python # # (c) Copyright 2015 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. DOCUMENTATION = ''' --- module: matchcidr author: Joe Fegan short_description: Find a nic matching the given search creteria description: - Searches the output of "ip a" for nics matching the given search criteria options: cidr: required: true description: - Find nics that have addresses on this cidr. ips: required: true description: - List of candidate interfaces and ips, newline separated. ''' EXAMPLES = ''' - matchcidr: cidr="10.1.11.0/24" ips="eth0 10.1.11.56/24\neth1 192.168.24.54/16\n" ''' from socket import inet_aton class MatchCidr(object): name = 'matchcidr' def __init__(self, module): self.module = module self.ips = module.params['ips'] self.cidr = module.params['cidr'] def fail(self, **kwargs): return self.module.fail_json(**kwargs) def succeed(self, **kwargs): return self.module.exit_json(**kwargs) def mkint(self, ipstr): binstr = inet_aton(ipstr) value = ((ord(binstr[0]) & 0xff) << 24) | \ ((ord(binstr[1]) & 0xff) << 16) | \ ((ord(binstr[2]) & 0xff) << 8) | \ (ord(binstr[3]) & 0xff) return value def cidrmatch(self, cidr): ip, width = cidr.split('/') if int(width) < self.width: return False if self.mkint(ip) & self.mask != self.subnet: return False return True def execute(self): try: # convert mask etc to integers. subnet, width = self.cidr.split('/') self.width = int(width) shift = 32 - self.width self.mask = 0xffffffff >> shift << shift self.subnet = self.mkint(subnet) & self.mask # look for nics matching this. result = None for candidate in self.ips.split('\n'): nic, thiscidr = candidate.split(' ') if self.cidrmatch(thiscidr): if result: if result['stdout'] == nic: continue self.fail(msg='%s: multiple nics matching %s\n%s' % (self.name, self.cidr, self.ips)) ip, width = thiscidr.split('/') result = dict(stdout=nic, ip=ip, cidr=self.cidr, subnet=hex(self.subnet), mask=hex(self.mask)) if result: self.succeed(**result) else: self.fail(msg='%s: no nic matching %s\n%s' % (self.name, self.cidr, self.ips)) except Exception as e: self.fail(msg='%s: %s %s' % (self.name, str(type(e)), str(e))) def main(): module = AnsibleModule( argument_spec=dict( cidr=dict(required=True), ips=dict(required=True) ) ) mod = MatchCidr(module) return mod.execute() from ansible.module_utils.basic import * main() 0707010000001A000081A400000000000000000000000162FD641A00000335000000000000000000000000000000000000004100000000ardana-cobbler-8.0+git.1660773402.d845a45/prepare-rhel-grub2.yml# # (c) Copyright 2016 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # --- - hosts: localhost roles: - cobbler tasks: - include: roles/cobbler/tasks/set-vars.yml - include: roles/cobbler/tasks/create-rhel-grub2.yml node={{ nodelist }} 0707010000001B000081A400000000000000000000000162FD641A000003C5000000000000000000000000000000000000004200000000ardana-cobbler-8.0+git.1660773402.d845a45/prepare-rhel-loader.yml# # (c) Copyright 2016 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # --- - hosts: localhost roles: - cobbler tasks: - include: roles/cobbler/tasks/set-vars.yml - include: roles/cobbler/tasks/get-rhel-loader-file.yml vars: filepath: "{{ file }}" when: file is defined - include: roles/cobbler/tasks/get-rhel-loader.yml when: file is not defined 0707010000001C000081A400000000000000000000000162FD641A000000DD000000000000000000000000000000000000004100000000ardana-cobbler-8.0+git.1660773402.d845a45/prepare-sles-grub2.yml# # (c) Copyright 2017,2018 SUSE LLC # --- - hosts: localhost roles: - cobbler tasks: - include: roles/cobbler/tasks/set-vars.yml - include: roles/cobbler/tasks/create-sles-grub2.yml node={{ nodelist }} 0707010000001D000081A400000000000000000000000162FD641A000001B6000000000000000000000000000000000000004200000000ardana-cobbler-8.0+git.1660773402.d845a45/prepare-sles-loader.yml# # (c) Copyright 2017,2018 SUSE LLC # --- - hosts: localhost roles: - cobbler tasks: - include: roles/cobbler/tasks/set-vars.yml - include: roles/cobbler/tasks/get-sles-loader-file.yml vars: filepath: "{{ file }}" when: file is defined and (ansible_os_family == 'Debian') - include: roles/cobbler/tasks/get-sles-loader.yml when: file is not defined and (ansible_os_family == 'Debian') 0707010000001E000041ED00000000000000000000000362FD641A00000000000000000000000000000000000000000000003000000000ardana-cobbler-8.0+git.1660773402.d845a45/roles0707010000001F000041ED00000000000000000000000762FD641A00000000000000000000000000000000000000000000003800000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler07070100000020000041ED00000000000000000000000262FD641A00000000000000000000000000000000000000000000004100000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/defaults07070100000021000081A400000000000000000000000162FD641A00000B8E000000000000000000000000000000000000004A00000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/defaults/main.yml# # (c) Copyright 2015-2017 Hewlett Packard Enterprise Development LP # (c) Copyright 2017,2018 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # # Variables for getting to the apt servers --- hlinux_distro: "cattleprod" remote_distros: - { name: hlinux, arch: x86_64, breed: debian, distro: cattleprod, url: "{{ hlinux_url }}", url_boot_path: main/installer-amd64/current/images/netboot/debian-installer/amd64, kickstart: hlinux-server-vm.preseed, file: "/srv/www/cobbler/ks_mirror/hlinux-{{ hlinux_distro }}", initrd: initrd.gz, kernel: linux, # keep it blank as 'managed_by' non-empty value has significance managed_by: '' } - { name: sles12sp3, arch: x86_64, kickstart: sles12sp3-autoyast.xml, managed_by: sles } - { name: rhel72, arch: x86_64, kickstart: rhel72-anaconda-ks.cfg, managed_by: rhel, entry_name: 'RHEL 7.2', grub2_efi_rpm: "grub2-efi-[0-9]*.rpm", rhel_shim_rpm: "shim-[0-9]*rpm" } - { name: rhel73, arch: x86_64, kickstart: rhel73-anaconda-ks.cfg, managed_by: rhel, entry_name: 'RHEL 7.3', grub2_efi_rpm: "grub2-efi-[0-9]*.rpm", rhel_shim_rpm: "shim-[0-9]*rpm" } - { name: rhel75, arch: x86_64, kickstart: rhel75-anaconda-ks.cfg, managed_by: rhel, entry_name: 'RHEL 7.5', grub2_efi_rpm: "grub2-efi-x64-[0-9]*.rpm", rhel_shim_rpm: "shim-x64-[0-9]*rpm" } rhel_iso_location: "{{ ardanauser_deployer_home }}/rhel7.iso" grubx64_location: "boot/efi/EFI/*/grubx64.efi" rhel_shim_location: "boot/efi/EFI/*/shim.efi" # SLES Profile Variables sles_profile_name: 'sles12sp3' current_sles_version: 'SLES 12 SP3' sles_iso_location: "{{ ardanauser_deployer_home }}/{{ sles_profile_name }}.iso" # SLES UEFI Variables sles_grub2_efi_rpm: "grub2-x86_64-efi-[0-9]*.rpm" sles_shim_rpm: "shim-[0-9]*rpm" sles_grubx64_location: "usr/lib/grub2/x86_64-efi/grub.efi" sles_regexp_location: "usr/lib/grub2/x86_64-efi/regexp.mod" sles_shim_location: "usr/lib64/efi/shim-sles.efi" sles_expected_media_repos: - alias: PTF name: PTF - alias: SLES12-SP3-Pool name: SLES12-SP3-Pool - alias: SLES12-SP3-Updates name: SLES12-SP3-Updates # Variable to hold list of repos configured on deployer sles_configured_media_repos: [] sles_dhcpd_start_limit_interval: 30 sles_dhcpd_start_limit_burst: 25 07070100000022000041ED00000000000000000000000262FD641A00000000000000000000000000000000000000000000003E00000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/files07070100000023000081A400000000000000000000000162FD641A000000A5000000000000000000000000000000000000004500000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/files/atftpdUSE_INETD=false OPTIONS="--tftpd-timeout 300 --retry-timeout 5 --mcast-port 1758 --mcast-addr 239.239.239.0-255 --mcast-ttl 1 --maxthread 100 --verbose=5 /srv/tftp" 07070100000024000081A400000000000000000000000162FD641A0000001C000000000000000000000000000000000000004900000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/files/bnx2x.confoptions bnx2x disable_tpa=1 07070100000025000081A400000000000000000000000162FD641A00000084000000000000000000000000000000000000004E00000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/files/configure_kdump#!/bin/bash sed -i 's/GRUB_CMDLINE_LINUX=""/GRUB_CMDLINE_LINUX="crashkernel=384M-2G:64M,2G-:256M"/g' /etc/default/grub update-grub 07070100000026000081A400000000000000000000000162FD641A000000A8000000000000000000000000000000000000005500000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/files/configure_partitioningif [ -e /sys/firmware/efi ] then wget -O ./partition_scheme http://$1/preseed/partition-uefi else wget -O ./partition_scheme http://$1/preseed/partition-pxe fi 07070100000027000081A400000000000000000000000162FD641A00000063000000000000000000000000000000000000005600000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/files/fence_ipmitool.templateaction=$power_mode ipaddr=$power_address login=$power_user passwd=$power_pass lanplus power_wait=4 07070100000028000081A400000000000000000000000162FD641A000002A1000000000000000000000000000000000000004C00000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/files/partition-pxeardana-config :: 1 1 1 free $bios_boot{ } method{ biosgrub } . 512 39000 512 free $primary{ } method{ keep } . 512 38000 512 ext3 $primary{ } $bootable{ } method{ format } format{ } use_filesystem{ } filesystem{ ext3 } mountpoint{ /boot } . 32000 32000 32000 ext4 $lvmok{ } lv_name{ root } method{ format } format{ } use_filesystem{ } filesystem{ ext4 } mountpoint{ / } . 3000 3000 100000 ext4 $lvmok{ } lv_name{ unused } method{ format } format{ } use_filesystem{ } filesystem{ ext4 } mountpoint{ /unused } . 07070100000029000081A400000000000000000000000162FD641A000002C0000000000000000000000000000000000000004D00000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/files/partition-uefiardana-config :: 1 1 1 free $bios_boot{ } method{ biosgrub } . 512 39000 512 fat32 $primary{ } method{ efi } format{ } $bootable{ } . 512 38000 512 ext3 $primary{ } $bootable{ } method{ format } format{ } use_filesystem{ } filesystem{ ext3 } mountpoint{ /boot } . 32000 32000 32000 ext4 $lvmok{ } lv_name{ root } method{ format } format{ } use_filesystem{ } filesystem{ ext4 } mountpoint{ / } . 3000 3000 100000 ext4 $lvmok{ } lv_name{ unused } method{ format } format{ } use_filesystem{ } filesystem{ ext4 } mountpoint{ /unused } . 0707010000002A000081A400000000000000000000000162FD641A0000B2B7000000000000000000000000000000000000005200000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/files/update_fcoe_udev.py#!/usr/bin/env python # # (c) Copyright 2016 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """update_fcoe_udev.py Provides tooling that can be used to manage the persistent ordering of network devices for use with FCOE deployments. Usage: update_fcoe_udev.py [--prefix|-p <prefix>] Where: --prefix, -p <prefix> specifies the path to prefix system file access with. Example: When running during a preseed install, the installed system hierarchy is mounted under /target, so invoke the command as follows: % update_fcoe_udev.py -p /target """ from argparse import ArgumentParser from collections import OrderedDict from glob import glob from hashlib import md5 as hasher from operator import attrgetter, itemgetter import os import re import sys class ArdanaSystemPathsError(RuntimeError): def __init__(self, *args, **kwargs): super(ArdanaSystemPathsError, self).__init__(*args, **kwargs) class DictReplacerError(RuntimeError): def __init__(self, *args, **kwargs): super(DictReplacerError, self).__init__(*args, **kwargs) class ConfFileError(RuntimeError): def __init__(self, *args, **kwargs): super(ConfFileError, self).__init__(*args, **kwargs) class PhaseRenameError(ConfFileError): def __init__(self, *args, **kwargs): super(PhaseRenameError, self).__init__(*args, **kwargs) class NetRulesError(RuntimeError): def __init__(self, *args, **kwargs): super(NetRulesError, self).__init__(*args, **kwargs) class NotRuleError(NetRulesError): def __init__(self, *args, **kwargs): super(NotRuleError, self).__init__(*args, **kwargs) class NotRule70Error(NetRulesError): def __init__(self, *args, **kwargs): super(NotRule70Error, self).__init__(*args, **kwargs) class NotRule71Error(NetRulesError): def __init__(self, *args, **kwargs): super(NotRule71Error, self).__init__(*args, **kwargs) class RenameError(NetRulesError): def __init__(self, *args, **kwargs): super(RenameError, self).__init__(*args, **kwargs) class InvalidRuleError(NetRulesError): def __init__(self, *args, **kwargs): super(InvalidRuleError, self).__init__(*args, **kwargs) class InvalidDeviceNameError(NetRulesError): def __init__(self, *args, **kwargs): super(InvalidDeviceNameError, self).__init__(*args, **kwargs) class ArdanaSystemPaths(object): """Helper class for system path access. Implements a simple helper class used to manage access the important system paths, potentially accessed under a provided offset, e.g. during an install. """ _default_path_prefix = "/" _default_flag_dir = "/etc/ardana" _default_flag_name = "udev_net_rules_updated" _rules_file_70 = "/etc/udev/rules.d/70-persistent-net.rules" _rules_file_71 = "/etc/udev/rules.d/71-persistent-net.rules" _fcoe_dir = "/etc/fcoe" _ifaces_file = "/etc/network/interfaces" _ifaces_dir = "/etc/network/interfaces.d" def __init__(self, prefix=None, sys_prefix=None, flag_dir=None, flag_name=None): """Initialise instance settings. The prefix argument specifies an offset path for all path resolution, e.g. /target if invoked during preseed install. The flag_dir and flag_name combined specify a flag file, the presence of which indicates that the associated operations have already been performed. """ if prefix is None: prefix = self._default_path_prefix if sys_prefix is None: sys_prefix = self._default_path_prefix if flag_dir is None: flag_dir = self._default_flag_dir if flag_name is None: flag_name = self._default_flag_name if not os.path.exists(prefix): raise ArdanaSystemPathsError("Prefix '%s' doesn't exist!" % prefix) self._path_prefix = prefix self._path_sys_prefix = sys_prefix self._flag_dir = flag_dir self._flag_name = flag_name @property def prefix(self): """Expose prefix path as readonly attr.""" return self._path_prefix @prefix.setter def prefix(self, prefix): """Update the prefix path to a new value.""" self._path_prefix = prefix def system_path(self, path): """Returns the actual path to use to access specified path.""" return os.path.join(self.prefix, path.lstrip('/')) @property def sys_prefix(self): """Expose sys_prefix path as readonly attr.""" return self._path_sys_prefix @sys_prefix.setter def sys_prefix(self, sys_prefix): """Update the sys_prefix path to a new value.""" self._path_sys_prefix = sys_prefix def system_sys_path(self, *args): """Returns the actual path to use to access specified path.""" return os.path.join(self.sys_prefix, "sys", *args) @property def rules_file_70(self): """System path to persistent udev rules file.""" return self.system_path(self._rules_file_70) @property def rules_file_71(self): """System path to persistent udev rules file.""" return self.system_path(self._rules_file_71) @property def fcoe_dir(self): """System path to FCOE config directory.""" return self.system_path(self._fcoe_dir) @property def ifaces_file(self): """System path to network interfaces config file.""" return self.system_path(self._ifaces_file) @property def ifaces_dir(self): """System path to network interfaces config directory.""" return self.system_path(self._ifaces_dir) @property def flag_dir(self): """System path to directory holding flag files.""" return self.system_path(self._flag_dir) @property def flag_name(self): """Expose flag name as readonly attr.""" return self._flag_name @property def flag_file(self): """System path to specified flag file.""" return os.path.join(self.flag_dir, self.flag_name) @property def flag_exists(self): """True if specified flag file exists.""" return os.path.exists(self.flag_file) class DictReplacer(object): """Manage text replacement based upon lookup table. Instances of this class can be used to manage updating contents of lines where the replacement value is dynamically looked up in a provided dictionary, based on the value to be replaced; if no value is found in provided dictionary then leave unchanged. """ def __init__(self, replacer, lookup, field=1, skipper=None): """Initialise the instance settings. The replacer argument must include at least one group specifier identifying the value to be replaced. The lookup argument must be a dictionary line object that maps candidate values onto there replacements. The field argument specifies which group's value should be looked up in the lookup map when doing replacement. The skipper argument can optionally specify a pattern that can be used to skip processing, e.g. ignore comment or blank lines. NOTE: The replacer and skipper can be provided as either compiled pattern objects, or pattern strings which will be automatically compiled, and the compiled versions used. """ if isinstance(replacer, str): replacer = re.compile(replacer) if isinstance(skipper, str): skipper = re.compile(skipper) if not replacer.groups: raise DictReplacerError("Invalid replacer pattern: no groups " "specified - '%s'" % replacer.pattern) self._replacer = replacer self._lookup = lookup self._field = field self._skipper = skipper @property def replacer(self): """Expose replacer as a readonly attr.""" return self._replacer @property def lookup(self): """Expose lookup as a readonly attr.""" return self._lookup @property def field(self): """Expose field as a readonly attr.""" return self._field @property def skipper(self): """Expose skipper as a readonly attr.""" return self._skipper def should_skip(self, text): """Check if we should skip processing of this text. Returns true if a skipper pattern has been provided, and the pattern matches the specified value. """ return self.skipper and self.skipper.match(text) def _callback(self, matcher): """Callback handling lookup of the substitution value.""" matched_field = matcher.group(self.field) replacement = self.lookup.get(matched_field) if not replacement: return matcher.group(0) fields = list(f or "" for f in matcher.groups()) fields[self.field - 1] = replacement return "".join(fields) def replace(self, text): """Replace content in text based upon lookup table. Based upon the content of the associated lookup table, replace any occurrences of any matching keys with their associated values that may be found in the provided text. """ if self.should_skip(text): return text return self.replacer.sub(self._callback, text) class ConfEntry(object): """Basic Conf File Entry handler.""" def __init__(self, line, lineno, syspaths): """Record line and line number.""" self._line = line self._lineno = lineno self._orig_line = None self._syspaths = syspaths def __str__(self): """Return line as str() value.""" return self._line @property def syspaths(self): """Syspaths object to use when resolving paths.""" return self._syspaths @property def lineno(self): """Line number of this line in the file.""" return self._lineno @property def orig_line(self): """Original line content.""" if self._orig_line is None: return self._line return self._orig_line def _backup_line(self): """Backup line content if not previously done.""" if self._orig_line is None: self._orig_line = self._line def update(self, new_line): """Update line with new content, backing up if needed.""" if new_line == self._line: return self._backup_line() self._line = new_line @property def dirty(self): """True if line has in fact been modified.""" return self._orig_line is not None class UdevNetEntry(ConfEntry): """Manage Udev persistent network rule entry. Class used to manage a specific udev persistent net rules, allowing renaming of associated device and checking whether the device exists on the system, and whether the configured settings match the actual settings in use.. """ def __init__(self, line, lineno, syspaths): """Record line and line number, and parse fields from line.""" super(UdevNetEntry, self).__init__(line, lineno, syspaths) self._orig_dev_name = None self._fields = self._parse_line() def _parse_line(self): """Parse line into fields, skipping comment and blank lines.""" # check if line contains a rule or not stripped = self._line.strip() if not stripped or stripped.startswith("#"): return None # strip out double quotes from values, and simplify equals strings simplified = self._line.replace("==", "=").replace('"', '') # return a dictionary formed from the key=value pairs found in line return dict(f.strip().split("=", 1) for f in simplified.split(",")) def _backup_dev_name(self): """Backup original device name if not previously done.""" if self._orig_dev_name is None: self._orig_dev_name = self.dev_name @property def is_rule(self): """True if line represents a udev rule.""" return self._fields is not None @property def mac(self): """Expose parsed MAC address as a readonly attr.""" if not self.is_rule: raise NotRuleError("No 'ATTR{address}' field.") if "ATTR{address}" not in self._fields: raise NotRule70Error("No 'ATTR{address}' field.") return self._fields["ATTR{address}"] @property def dev_name(self): """Expose parsed device name as a readonly attr.""" if not self.is_rule: raise NotRuleError("No 'NAME' field.") return self._fields["NAME"] _name_re = re.compile(r"^(\D+)(\d+)$") @property def is_dev_name_valid(self): """True if device name is valid format.""" return self._name_re.match(self.dev_name) is not None @property def dev_name_prefix(self): """Device name prefix string. Expose the device name prefix string, e.g. eth for ethN, as a readonly attr. """ match = self._name_re.match(self.dev_name) if not match: raise InvalidDeviceNameError("Not a valid device name: '%s'" % self.dev_name) return match.group(1) @property def orig_dev_name(self): """Expose original device name as a readonly attr.""" if not self.is_rule: raise NotRuleError("No original name to find.") if self._orig_dev_name: return self._orig_dev_name return self.dev_name _dev_rename_re = re.compile(r'(\sNAME=")([^"]+)(")') def dev_rename(self, new_dev_name): """Rename device associated with rule. Rename the device associated with a given rule, if the name has in fact changed, and the device hasn't already been re-ordered. """ if not self.is_rule: raise NotRuleError("Rename not possible.") if new_dev_name == self.dev_name: return if self.reordered: return self._backup_dev_name() repl_value = r'\1' + new_dev_name + r'\3' new_line, count = self._dev_rename_re.subn(repl_value, self._line, 1) if not count: raise InvalidRuleError("Failed to update NAME field") self.update(new_line) self._fields["NAME"] = new_dev_name @property def sys_class_orig_path(self): """Expose path to original /sys/class/net entry as readonly attr.""" if not self.is_rule: raise NotRuleError("Cannot determine /sys/class/net path") return self.syspaths.system_sys_path('class/net', self.orig_dev_name) @property def sys_class_path(self): """Expose path to current /sys/class/net entry as readonly attr.""" if not self.is_rule: raise NotRuleError("Cannot determine /sys/class/net path") return self.syspaths.system_sys_path('class/net', self.dev_name) @property def sys_path_exists(self): """True if original /sys/class/net path exists.""" return os.path.exists(self.sys_class_orig_path) @property def sys_dev_port(self): """The PCI device port of the device associated with this rule. Expose PCI Device port associated with original device name as readonly attr. """ try: with open(os.path.join(self.sys_class_orig_path, "dev_port")) as f: dev_port = f.read().strip('\0').strip() except Exception: sys.stderr.write("Failed to read dev_port for entry: %s\n" % (self._orig_line)) raise return dev_port @property def dev_port(self): """The ATTR{dev_port} specified in this rule.""" if not self.is_rule: raise NotRuleError("No 'ATTR{dev_port}' field.") if "ATTR{dev_port}" not in self._fields: raise NotRule71Error("No 'ATTR{dev_port}' field.") return self._fields["ATTR{dev_port}"] @property def devpath(self): """The DEVPATH specified in this rule.""" if not self.is_rule: raise NotRuleError("No 'DEVPATH' field.") if "DEVPATH" not in self._fields: raise NotRule71Error("No 'DEVPATH' field.") return self._fields["DEVPATH"] @property def sys_mac(self): """The system MAC address associated with rules current device. Expose the MAC address associated with the current device name as a readonly attr. Used in determining if network devices have already been re-ordered. """ try: with open(os.path.join(self.sys_class_path, "address")) as f: sys_mac = f.read().strip('\0').strip() except Exception: sys.stderr.write("Failed to read address for entry: %s\n" % (self._orig_line)) raise return sys_mac @property def pci_dev(self): """The PCI device ID associated with rules network device. Expose the PCI Device ID associated with the original device name as a readonly attr. """ return os.path.realpath(self.sys_class_orig_path).split("/")[-3] @property def pci_order(self): """Returns constructed PCI ordering string for use in sorting.""" return "%s:%s" % (self.pci_dev, self.sys_dev_port) @property def reordered(self): """Has this rule already been re-ordered. True if device associated with has already been reordered, either by us or a previous run. """ if "ATTR{address}" in self._fields: return self.mac != self.sys_mac if "DEVPATH" in self._fields: return self.devpath != ("*/%s/*" % self.pci_dev) class ConfFile(object): """Class used to manage on-disk config files""" def __init__(self, conf_file, syspaths, handler=None): """Initialise instance settings. If no handler specified, use default, i.e. ConfEntry. Track name changes for conf file via path list. """ if handler is None: handler = ConfEntry self._path = [conf_file] self._rename_phase = 0 self._handler = handler self._lines = [] self._linemap = {} self._syspaths = syspaths @property def syspaths(self): """System paths manager to use when resolving paths.""" return self._syspaths @property def path(self): """Current file path.""" return self._path[-1] @path.setter def path(self, new_path): """Change file path to new name.""" if new_path == self.path: return self._path.append(new_path) @property def paths(self): """Expose rename paths list as readonly attr.""" return tuple(self._path) @property def orig_path(self): """Expose original file path as readonly attr.""" return self._path[0] @property def rename_phases(self): """Total number of renames for this conf file.""" return len(self._path) - 1 @property def has_moved(self): """True if a file has been renamed.""" return bool(self.rename_phases) @property def renames_remaining(self): """Number of outstanding rename operations. Remaining number of renames for this conf file that haven't yet been performed. """ return self.rename_phases - self._rename_phase @property def rename_phase_src(self): """Source path for current rename phase.""" return self._path[self._rename_phase] @property def rename_phase_dst(self): """Destination path for current rename phase.""" if not self.renames_remaining: raise PhaseRenameError("File '%s' already fully renamed to '%s'" % (self.orig_path, self.path)) return self._path[self._rename_phase + 1] def _load_file(self): """Load entries from on-disk file. Load the conf file lines each as an instance of provided handler, and record associated line number mapping. """ try: with open(self.path) as f: conf_lines = f.readlines() except Exception: sys.stderr.write("open('%s') failed: %s\n" % (self.path, sys.exc_info()[1])) raise for lineno, line in enumerate(conf_lines): entry = self._handler(line, lineno, self.syspaths) self._lines.append(entry) self._linemap[lineno] = entry @property def entries(self): """List of entries in the file. Expose list of entries in the conf file as a readonly attr, dynamically loading the file lines if necessary. """ if not self._lines: self._load_file() return tuple(self._lines) @property def lines(self): """Expose text lines of conf file as readonly attr.""" return tuple(str(e) for e in self.entries) @property def content(self): """Expose text content of conf file as readonly attr.""" return "".join(self.lines) @property def ondisk_digest(self): """Generate hashed digest of on-disk file content. Returns hashed digest based upon on-disk file content for current file name; used in determining whether file has been modified. """ with open(self.rename_phase_src) as f: return hasher(f.read()).hexdigest() @property def incore_digest(self): """Generate hashed digest of in-code file content. Returns hashed digest based upon in-core file content for conf file; used in determining whether file has been modified. """ return hasher(self.content).hexdigest() @property def consistent(self): """True if in-core and on-disk content digests match.""" return self.incore_digest == self.ondisk_digest def _update_ondisk(self): """Write out in-core file content to disk.""" with open(self.orig_path, "w") as f: f.write(self.content) @property def dirty(self): """True if in-core and on-disk content differs.""" return not self.consistent def replace(self, replacer): """Replace specific values based upon lookup table. Update file content via the provided DictReplacer instance, which will replace matching values based upon their current value, looked up in the replacer's lookup table. """ for e in self.entries: e.update(replacer.replace(str(e))) def _rename_ondisk(self): """Perform an on-disk rename action. Perform the next on-disk rename of this conf file, if one is pending. """ if not self.has_moved or not self.renames_remaining: return try: os.rename(self.rename_phase_src, self.rename_phase_dst) except Exception: sys.stderr.write("Failed to renamed '%s' to '%s'\n" % (self.rename_phase_src, self.rename_phase_dst)) raise self._rename_phase += 1 def commit(self, phases=1): """Commit pending changes for this conf file. Write any required changes to the conf file if it is dirty, and perform specified number of rename phases, where -1 means all remaining phases. The latter special value should only be used if we are certain that we are not trying to swap the names of two conf files. """ if self.dirty: self._update_ondisk() if self.has_moved and self.renames_remaining: if phases == -1: phases = self.renames_remaining for phase in range(phases): self._rename_ondisk() class UdevNetRulesFile(ConfFile): """Manage a udev net rules file. Provides common framework for managing net rules files. """ def __init__(self, conf_file, syspaths): """Manage this conf file using the UdevNetEntry handler.""" super(UdevNetRulesFile, self).__init__(conf_file, syspaths, UdevNetEntry) @property def rules(self): """Expose list of rules as readonly attr.""" return tuple(e for e in self.entries if e.is_rule) @property def reordered_rules(self): """Expose list of re-ordered rules as readonly attr.""" return tuple(r for r in self.rules if r.reordered) @property def reordered(self): """True if any rules have been re-ordered.""" return bool(self.reordered_rules) @property def devices_exist(self): """Check that all rule network devices exist. Returns true only if all the /sys/class/net devices associated with all rules still exist. """ return all(r.sys_path_exists for r in self.rules) class UdevNetRulesFile70(UdevNetRulesFile): """Manage a udev 70-persistent-net.rules file. This class manages the contents of the udev persistent net rules file /etc/udev/rules.d/70-persistent-net.rules. """ def __init__(self, syspaths): """Manage this conf file using the UdevNetEntry handler.""" super(UdevNetRulesFile70, self).__init__(syspaths.rules_file_70, syspaths) def reorder_rules(self): """Re-order the device names in the rules by PCI device. Sort rule devices according to the associated pci_order value, and rename device names based upon that ordering. """ new_order = sorted(self.rules, key=attrgetter("pci_order")) for idx, r in enumerate(new_order): r.dev_rename("%s%s" % (r.dev_name_prefix, idx)) class UdevNetRulesFile71(UdevNetRulesFile): """Manage a udev 71-persistent-net.rules file. This class manages the contents of the udev persistent net rules file /etc/udev/rules.d/71-persistent-net.rules. """ def __init__(self, syspaths): """Manage this conf file using the UdevNetEntry handler.""" super(UdevNetRulesFile71, self).__init__(syspaths.rules_file_71, syspaths) def reorder_rules(self): raise NetRulesError("Re-ordering not supported for " "71-persistent-net.rules file.") class UdevNetRulesManager(object): """Udev Net Rules Manager Class used to make the udev persistent net rules settings for a system. Generates a 71-persistent-net.rules file that orders network devices by PCI order, superceding any existing 70-persistent-net.rules file. We will also update the 70-persistent-net.rules file to match the new order. """ def __init__(self, syspaths): """Initialise instance settings. The syspaths object manages access to the system paths against which the operations should be performed. """ self._syspaths = syspaths self._rules_70 = None self._rules_71 = None self._rules_71_created = False @property def syspaths(self): return self._syspaths @property def rules_70(self): if not self._rules_70: self._load_rules_70() return self._rules_70 @property def rules_71(self): if not self._rules_71: self._load_rules_71() return self._rules_71 @property def rules_71_created(self): return self._rules_71_created @property def rules_file_70_exists(self): return os.path.exists(self._syspaths.rules_file_70) @property def rules_file_71_exists(self): return os.path.exists(self._syspaths.rules_file_71) def _load_rules_70(self): if not self.rules_file_70_exists: return self._rules_70 = UdevNetRulesFile70(self.syspaths) def _load_rules_71(self): if not self.rules_file_71_exists: self._gen_rules_file_71() self._rules_71 = UdevNetRulesFile71(self.syspaths) @staticmethod def _get_net_dev_info(net_dev_path): dev_name = os.path.basename(net_dev_path) pci = os.path.realpath(net_dev_path).split('/')[-3] with file(os.path.join(net_dev_path, 'dev_port')) as fp: port = fp.read().strip('\0').strip() with file(os.path.join(net_dev_path, 'address')) as fp: address = fp.read().strip('\0').strip() return dict(dev_name=dev_name, pci=pci, port=port, address=address) @property def system_eth_devices(self): class_net = self.syspaths.system_sys_path('class', 'net') eth_dev_info = list(self._get_net_dev_info(e) for e in glob(os.path.join(class_net, 'eth*'))) return {e['dev_name']: e for e in eth_dev_info} @property def ordered_eth_devices(self): sys_devs = self.system_eth_devices pci_ordered = sorted(sys_devs.values(), key=lambda x: '%s:%s' % (x['pci'], x['port'])) ordered_devs = OrderedDict() for i, e in enumerate(pci_ordered): dev_name = 'eth%d' % i new_e = e.copy() new_e.update(dict(dev_name=dev_name)) ordered_devs[dev_name] = new_e return ordered_devs @property def reordered(self): sys_devs = self.system_eth_devices ordered_devs = self.ordered_eth_devices return (sys_devs != ordered_devs) @property def reordered_devices(self): sys_devs = self.system_eth_devices sys_set = set("%s:%s#%s" % (e['pci'], e['port'], e['dev_name']) for e in sys_devs.itervalues()) ordered_devs = self.ordered_eth_devices ordered_set = set("%s:%s#%s" % (e['pci'], e['port'], e['dev_name']) for e in ordered_devs.itervalues()) set_diffs = sys_set.symmetric_difference(ordered_set) diff_map = {} for d in set_diffs: d_pci, d_name = d.split('#') if d_pci not in diff_map: diff_map[d_pci] = {} if d in sys_set: diff_map[d_pci]['from'] = d_name else: diff_map[d_pci]['to'] = d_name return sorted(diff_map.itervalues(), key=itemgetter('from')) @staticmethod def _gen_rules_71_entry(e): return ['', ('SUBSYSTEM=="net", ACTION=="add", DEVPATH=="*/%s/*", ' 'ATTR{dev_port}=="%s", NAME="%s"' % (e['pci'], e['port'], e['dev_name']))] def _gen_rules_file_71(self): ordered_devs = self.ordered_eth_devices content = ["# ARDANA-MANAGED - Managed by Ardana - Do not edit", "# Generated by update_fcoe_udev during install/setup", "#", ("# udev rules to persistently map physical PCI devices " "to ethX device names."), ("# This is used to hard-wire specific ethX names to a " "specific (PCI address,"), ("# dev_port) pairings so that the names don't change " "across reboots.")] for e in ordered_devs: content.extend(self._gen_rules_71_entry(ordered_devs[e])) rules_file = self.syspaths.rules_file_71 with file(rules_file, "w") as fp: fp.write("\n".join(content)) self._rules_71_created = True @property def dirty(self): if self.rules_71_created and self.reordered: return True if self.rules_70: if self.rules_70.dirty: return True return False @property def devices_exist(self): if not self.rules_71.devices_exist: return False if self.rules_71: if not self.rules_71.devices_exist: return False return True def reorder_rules(self): if self.rules_70: self.rules_70.reorder_rules() # We should never need to re-order the entries in rules_71 def commit(self): if self.rules_70: self.rules_70.commit() class NetworkDeviceManager(object): """Network Device Management Helper Class used to manage updating system configuration files as a result of reordering network devices in PCI device order. """ def __init__(self, prefix, sys_prefix, syspaths=None): """Initialise instance settings. The arguments that we support are: * prefix - path The path under which to look for network configuration files. * sys_prefix - path The path under which to perform /sys lookups """ if syspaths is None: syspaths = ArdanaSystemPaths(prefix, sys_prefix) self._syspaths = syspaths self._udev = UdevNetRulesManager(syspaths) self._fcoe_confs = [] self._ifaces_confs = [] self._remap_renamer = None @property def syspaths(self): """Expose syspaths as a readonly attr.""" return self._syspaths @property def udev(self): """Expose udev as a readonly attr.""" return self._udev @property def fcoe_confs(self): """Expose fcoe_confs as a readonly attr.""" return tuple(self._fcoe_confs) @property def ifaces_confs(self): """Expose ifaces_confs as a readonly attr.""" return tuple(self._ifaces_confs) @property def remap_renamer(self): """Renamer tool used to manage content updates. Dynamically creates a DictReplacer instance to be used for updating config files the first this is called after devices have been reordered, and thereafter returns that DictReplacer instance. """ if self._remap_renamer is None and self.udev.reordered: # Construct a DictReplacer instance that can be used to # rename the device names within config files. reordered = self.udev.reordered_devices rename_map = dict(((r['from'], r['to']) for r in reordered)) self._remap_renamer = DictReplacer(r"(eth\d+)", rename_map) return self._remap_renamer _noreorder_flag = "fcoe_noreorder" @property def dont_run(self): """Returns true if flag found in /proc/cmdline.""" cmdline_file = "/proc/cmdline" try: with open(cmdline_file) as f: cmdline = f.read() except Exception: sys.stderr.write("Failed to open '%s': %s\n" % (cmdline_file, sys.exc_info()[1])) raise return self._noreorder_flag in cmdline @property def system_valid(self): """Check that system state is consistent and valid. Returns false if any of the network devices identified in ther persistent udev net rules doesn't exist. """ return self.udev.devices_exist @property def already_processed(self): """Check if a system has already been processed. Should be called before doing anything to check if system has already been processed, and or needs a reboot. """ # If the flag file has been created by a previous run # or if any of the rules have already been re-ordered # then we shouldn't make any more changes and instead # the system needs to be rebooted. return self.syspaths.flag_exists @property def needs_reboot(self): return self.udev.reordered def reorder_udev_rules(self): """Re-order network devcies in Udev persistent rules.""" self.udev.reorder_rules() @property def fcoe_dirty(self): """True if any FCOE config changes pending.""" return any(c.dirty or c.renames_remaining for c in self.fcoe_confs) @property def ifaces_dirty(self): """True if any network interface config changes pending.""" return any(c.dirty or c.renames_remaining for c in self.ifaces_confs) @property def dirty(self): """True if any udev, FCOE or network config changes pending.""" return self.udev.dirty or self.fcoe_dirty or self.ifaces_dirty def _process_candidate_conf_files(self, reordered_files): """Process specified conf files. Given a list of (rule, file) pairs, weed out those for which the conf file doesn't exist and then process the remaining conf files, updating their content as appropriate and then rename them in a 2 phase process; this allows us to safely swap files. Return the resulting list of ConfFile instances. """ confs = [] for r, f in reordered_files: if not os.path.exists(f): continue conf = ConfFile(f, self.syspaths) conf.replace(self.remap_renamer) temp_name = "%s...%s" % (r['from'], r['to']) conf.path = conf.path.replace(r['from'], temp_name) conf.path = conf.path.replace(temp_name, r['to']) confs.append(conf) return confs def update_fcoe_configs(self): """Update FCOE config based on re-ordered udev rules.""" # Nothing to be done if no reordering has occurred. reordered = self.udev.reordered_devices if not reordered: return # Skip if we have already completed this stage if self.fcoe_confs: return # Generate candidate list of fcoe conf files, with # associated rule, that need to be processed reordered_files = tuple((r, os.path.join(self.syspaths.fcoe_dir, "cfg-%s" % r['from'])) for r in reordered) # At this stage changes have been prepared but are not yet # committed to disk self._fcoe_confs = self._process_candidate_conf_files(reordered_files) def update_ifaces_configs(self): """Update network config based on re-ordered udev rules.""" # Nothing to be done if no reordering has occurred. reordered = self.udev.reordered_devices if not reordered: return # Skip if we have already completed this stage if self.ifaces_confs: return # Generate candidate list of iface conf files, with # associated rule, that need to be processed. reordered_files = tuple((r, os.path.join(self.syspaths.ifaces_dir, r['from'])) for r in reordered) ifaces_confs = self._process_candidate_conf_files(reordered_files) # Process the main interfaces file, and if it was modified, then # include it in the list of interface conf objects to be tracked conf = ConfFile(self.syspaths.ifaces_file, self.syspaths) conf.replace(self.remap_renamer) if conf.dirty: ifaces_confs.append(conf) # At this stage changes have been prepared but are not yet # committed to disk self._ifaces_confs = ifaces_confs @staticmethod def _gen_conf_changes_text(action, title, conf_list): """Generate change info text.""" if not (conf_list and any(c.dirty or c.has_moved for c in conf_list)): return "" lines = ["%s %s Changes:" % (action, title)] if any(c.has_moved for c in conf_list): lines.append(" Reordering:") lines.extend([" %s ==> %s" % (c.orig_path, c.path) for c in conf_list if c.has_moved]) if any(c.dirty for c in conf_list): lines.append(" Modifying:") lines.extend([" %s" % c.path for c in conf_list if c.has_moved]) lines.append("") return "\n".join(lines) @staticmethod def _gen_udev_changes_text(action, reordered_list): """Generate device reorder change text.""" if not reordered_list: return "" lines = ["%s Device Re-ordering:" % action] lines.extend([" %6s ==> %s" % (r['from'], r['to']) for r in reordered_list]) lines.append("") return "\n".join(lines) def _gen_changes_text(self, action): reordered = self.udev.reordered_devices changes = [self._gen_udev_changes_text(action, reordered), self._gen_conf_changes_text(action, "FCOE", self.fcoe_confs), self._gen_conf_changes_text(action, "Network", self.ifaces_confs)] return "\n".join(c for c in changes if c) def _create_flag_file(self, content): """Create flag file with provided content.""" if not os.path.exists(self.syspaths.flag_dir): try: os.makedirs(self.syspaths.flag_dir) except Exception: sys.stderr.write("Failed to create flag directory '%s': %s\n" % (self.syspaths.flag_dir, sys.exc_info()[1])) raise try: with open(self.syspaths.flag_file, "w") as f: f.write(content) except Exception: sys.stderr.write("Failed to create flag file '%s': %s\n" % (self.syspaths.flag_file, sys.exc_info()[1])) raise def commit(self): """Commit any pending changes to disk.""" changes = "No reordering required." msg = "No device reordering required on this system." if self.dirty: print(self._gen_changes_text("Proposed")) # Generate committed changes text before committing. changes = self._gen_changes_text("Committed") # If the rules have been updated commit those changes if self.udev.dirty: self.udev.commit() # If any of the fcoe or interfaces files have been # updated or renamed then commit those changes if self.fcoe_dirty or self.ifaces_dirty: conf_list = self.fcoe_confs + self.ifaces_confs rename_phases = max(c.renames_remaining for c in conf_list) # We want to iterate at least once, and up to max # number of rename operations outstanding. for i in range(max(1, rename_phases)): for conf in conf_list: # First time through will update file content, and # peforms first rename if any; subsequent commits # perform any remaining renames conf.commit() msg = ("All device reordering changes committed to disk.\n" "NOTE:\n" " Please ensure that the ramdisk is updated and the\n" " system is rebooted for these changes to take effect.") self._create_flag_file(changes) print(msg) def process_system(self): """Process the current system. Update the system by re-ordering the udev persistent network rules according to PCI device order, and then reflect those reordering changes in the system FCOE and network interfaces configurations, and then commit those changes to disk. """ if self.already_processed or self.dont_run or not self.system_valid: return self.reorder_udev_rules() self.update_fcoe_configs() self.update_ifaces_configs() self.commit() def main(): """Main body for script.""" parser = ArgumentParser(description="Update FCOE device udev persisted " "ordering.") parser.add_argument("--prefix", "-p", default="/target", help="System files will be accessed under this " "prefix") parser.add_argument("--sys-prefix", "-s", default="/", help="The /sys file system files will be accessed " "under this prefix") args = parser.parse_args() NetworkDeviceManager(args.prefix, args.sys_prefix).process_system() if __name__ == '__main__': main() 0707010000002B000081ED00000000000000000000000162FD641A0000020A000000000000000000000000000000000000004C00000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/files/validate_yaml#!/usr/bin/python import json import jsonschema import sys import yaml with open(sys.argv[1], 'r') as schema: schema_yml = yaml.load(schema) schema_json = json.dumps(schema_yml) schema_contents = json.loads(schema_json) with open(sys.argv[2], 'r') as data_file: data_yml = yaml.load(data_file) data_json = json.dumps(data_yml) data_contents = json.loads(data_json) try: jsonschema.validate(data_contents, schema_contents) except Exception as e: print "ERROR: " + str(e) sys.exit(1) 0707010000002C000041ED00000000000000000000000262FD641A00000000000000000000000000000000000000000000003E00000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks0707010000002D000081A400000000000000000000000162FD641A000003F5000000000000000000000000000000000000006000000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks/assert-nodes-are-not-pingable.yml# # (c) Copyright 2015 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. --- - name: cobbler | assert-nodes-are-not-pingable | Derive node ips local_action: bmconfig file={{ baremetal_config }} node={{ inventory_hostname }} field=ip_addr register: cobbler_ip - name: cobbler | assert-nodes-are-not-pingable | ping IPs become: yes shell: ping -c 3 "{{ cobbler_ip.stdout }}" register: ping failed_when: ping.rc == 0 changed_when: false 0707010000002E000081A400000000000000000000000162FD641A0000035C000000000000000000000000000000000000005600000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks/assert-power-is-off.yml# (c) Copyright 2015 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # - name: cobbler | assert-power-is-off | Check node power status ipmi: name={{ inventory_hostname }} credsfile={{ baremetal_config }} power=status register: pstate failed_when: pstate | failed or pstate.power != "off" 0707010000002F000081A400000000000000000000000162FD641A000006AB000000000000000000000000000000000000005300000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks/check-sles-repos.yml# # (c) Copyright 2018 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # # Task to check whether zypper repos are configured on deployer # and repos URI has expected input uri pattern # Check is done via using 'alias' attribute in input repos list # # Pass following variable to include file. # vars: # _input_repos_list: "{{ sles_expected_media_repos }}" # _input_uri_pattern: "^dir:\\/\\/\\/srv\\/www\\/suse-12.3\\/" # - name: cobbler | check-sles-repos | Check repos configured on deployer delegate_to: "localhost" become: yes shell: > zypper lr -u | awk '$3 == "{{ item.alias }}" && $15 ~ /{{ _input_uri_pattern}}/ {print $3}' with_items: _input_repos_list register: _repos_found_result - name: cobbler | check-sles-repos | Create configured repos list set_fact: sles_configured_media_repos: > {%- set _c = [] -%} {%- for _item in _input_repos_list -%} {%- if _repos_found_result.results | selectattr('stdout', 'equalto', _item.alias) | list | count > 0 -%} {%- set _ = _c.append(_item) -%} {%- endif -%} {%- endfor -%} {{ _c }} when: - _repos_found_result is defined - _repos_found_result.results | length > 0 07070100000030000081A400000000000000000000000162FD641A00001535000000000000000000000000000000000000004C00000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks/configure.yml# # (c) Copyright 2015-2017 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # --- - name: cobbler | configure | Set vars dependent on target OS include_vars: "{{ ansible_os_family.split(' ')[0] | lower | replace('open','') }}.yml" # Cobbler deb package installs conf file into wrong folder /etc/apache2/conf.d - name: cobbler | configure | Debian - symlink cobbler apache configuration become: yes file: src: /etc/apache2/conf.d/cobbler.conf dest: /etc/apache2/conf-available/cobbler.conf state: link when: not cobbler_is_sles - name: cobbler | configure | Debian - enable cobbler apache configuration become: yes command: a2enconf cobbler when: not cobbler_is_sles - name: cobbler | configure | Suse - create apache configuration for /srv become: yes template: src=srv.conf.j2 dest=/etc/apache2/conf.d/srv.conf when: cobbler_is_sles - name: cobbler | configure | Debian - create apache configuration for /srv become: yes template: src=srv.conf.j2 dest=/etc/apache2/conf-available/srv.conf when: not cobbler_is_sles - name: cobbler | configure | Debian - enable apache configuration for /srv become: yes command: a2enconf srv when: not cobbler_is_sles - name: cobbler | configure | set default passwd set_fact: cobbler_default_passwd="{{ item }}" with_password: /tmp/cobbler_setup encrypt=sha512_crypt - name: cobbler | configure | rm temp file file: path: /tmp/cobbler_setup state: absent recurse: no - name: cobbler | configure | Adding cobbler settings file become: yes template: src=settings.j2 dest=/etc/cobbler/settings - name: cobbler | configure | Suse - fix cobbler tftpd template become: yes lineinfile: dest: /etc/cobbler/tftpd.template state: present regexp: '^\s*server_args\s*=.*' line: ' server_args = -u tftp -B 1380 -vvvv -s $args' when: cobbler_is_sles - name: cobbler | configure | Create directory for preseed content become: yes file: path: /srv/www/preseed state: directory mode: 0755 - name: cobbler | configure | Copy preseed content become: yes copy: src={{ item }} dest=/srv/www/preseed with_items: - partition-pxe - partition-uefi - configure_partitioning - configure_kdump - bnx2x.conf - update_fcoe_udev.py - name: cobbler | configure | Add option to add gateway become: yes template: src: configure_network.sh.j2 dest: /srv/www/preseed/configure_network.sh - name: cobbler | configure | set timestamp for installs become: yes shell: date +%Y%m%d%H%M%S > {{ local_timestamp_file }} # Temp until CI updated - name: cobbler | configure | Set local stamp become: yes copy: src={{ local_timestamp_file }} dest=/etc/cobbler_ardana_installed # Get syslinux bootloaders - name: cobbler | configure | Create bootloader directory become: yes file: path: /var/lib/cobbler/loaders state: directory mode: 0755 # Copy module behaves weird with with_items - name: cobbler | configure | Copy various loaders to cobbler loaders dir become: yes shell: cp -Lf {{ item.src }} /var/lib/cobbler/loaders/{{ item.filename }} with_items: cobbler_bootloader_sources - name: cobbler | configure | Adding cobbler dhcp template become: yes template: src=cobbler.dhcp.template.j2 dest=/etc/cobbler/dhcp.template - name: cobbler | configure | Enable apache modules become: yes command: "a2enmod {{ item }}" with_items: - proxy - proxy_http - access_compat - name: cobbler | configure | Check SLES Profile become: yes command: > cobbler profile report --name {{ sles_profile_name }}-x86_64 register: _sles_profile_exist_result failed_when: false changed_when: false - name: cobbler | configure | Locate distro_signatures.json files set_fact: distro_signatures_files: - /etc/cobbler/distro_signatures.json - /var/lib/cobbler/distro_signatures.json when: _sles_profile_exist_result.rc != 0 - name: cobbler | configure | Fix line endings in distro_signatures.json files become: yes replace: dest="{{ item }}" regexp="\\r" with_items: distro_signatures_files when: _sles_profile_exist_result.rc != 0 - name: cobbler | configure | Modify distro_signatures.json for sles12sp3 become: yes lineinfile: dest: "{{ item }}" state: present regexp: '^\s*"sles12(sp3)?":' line: ' "sles12sp3": {' with_items: distro_signatures_files when: _sles_profile_exist_result.rc != 0 - name: cobbler | configure | Modify distro_signatires.json for sles12sp3 become: yes lineinfile: dest: "{{ item }}" state: present regexp: '^\s*"version_file":"\(sles|SLES-for-VMware\)-release-12(\.3)?-"' line: ' "version_file":"(sles|SLES-for-VMware)-release-12.3-(.*).rpm",' with_items: distro_signatures_files when: _sles_profile_exist_result.rc != 0 07070100000031000081A400000000000000000000000162FD641A000004D9000000000000000000000000000000000000005400000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks/create-rhel-grub2.yml# # (c) Copyright 2016 Hewlett Packard Enterprise Development LP # (c) Copyright 2017,2018 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # --- - name: cobbler | create-rhel-grub2 | Set vars dependent on target OS include_vars: "{{ ansible_os_family.split(' ')[0] | lower | replace('open','') }}.yml" - name: cobbler | create-rhel-grub2 | Derive nodes mac address local_action: bmconfig file={{ baremetal_config }} node={{ item }} field=mac_addr with_items: "{{ node | split(',') }}" register: node_mac - name: cobbler | create-rhel-grub2 | Create nodes grub2 files become: yes template: src: grub2.j2 dest: '{{ cobbler_tftp_dir }}/grub/grub.cfg-01-{{ item.stdout | lower }}' with_items: "{{ node_mac.results }}" 07070100000032000081A400000000000000000000000162FD641A000004DE000000000000000000000000000000000000005400000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks/create-sles-grub2.yml# # (c) Copyright 2016 Hewlett Packard Enterprise Development LP # (c) Copyright 2017,2018 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # --- - name: cobbler | create-sles-grub2 | Set vars dependent on target OS include_vars: "{{ ansible_os_family.split(' ')[0] | lower | replace('open','') }}.yml" - name: cobbler | create-sles-grub2 | Derive nodes mac address local_action: bmconfig file={{ baremetal_config }} node={{ item }} field=mac_addr with_items: "{{ node | split(',') }}" register: node_mac - name: cobbler | create-sles-grub2 | Create nodes grub2 files become: yes template: src: sles.grub2.j2 dest: '{{ cobbler_tftp_dir }}/grub/grub.cfg-01-{{ item.stdout | lower }}' with_items: "{{ node_mac.results }}" 07070100000033000081A400000000000000000000000162FD641A0000068B000000000000000000000000000000000000005500000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks/get-baremetal-info.yml# # (c) Copyright 2015-2016 Hewlett Packard Enterprise Development LP # (c) Copyright 2017,2018 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # # This task runs a module on localhost that extracts networking information # from the baremetal section of the model and returns it in a convenient struct # that is consumed by various other plays. I'm using run_once because this task # might get run against a bunch of nodes in parallel. That's not dangerous or # anything, but they'd all get the same answer (because they're all working # with the same source data from localhost) so it's pointless repetition. # Run once, we don't even care on what node; the result will be the same. - name: cobbler | get-baremetal-info | Get baremetal info local_action: bmconfig file={{ baremetal_config }} - name: cobbler | check-ipmi-credentials-provided | Check at least one server has ipmi credentials fail: msg: > There were no servers found with ipmi credentials defined. If you want to use cobbler to deploy servers, you must include proper ipmi credentials for each server you want to deploy with cobbler. when: bminfo.servers | length == 0 07070100000034000081A400000000000000000000000162FD641A0000066D000000000000000000000000000000000000004F00000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks/get-nodelist.yml# # (c) Copyright 2015 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # - include: get-baremetal-info.yml # Allow the user to specify -e nodelist="ccn-0001,cpn-0003" on the # command line to target a specific set of nodes. - name: cobbler | get-nodelist | User-specified target list set_fact: target_nodes="{{ nodelist | split(',') }}" when: nodelist is defined and nodelist != "all" # Allow the user to specify -e nodelist=all on the command line. - name: cobbler | get-nodelist | Compute generic target list set_fact: target_nodes="{{ bminfo.server_ids }}" when: nodelist is defined and nodelist == "all" - name: cobbler | get-nodelist | Check we have targets fail: msg="There is no default set of nodes for this command, use -e nodelist" when: target_nodes is undefined - name: cobbler | get-nodelist | Create dynamic host group, minus myself add_host: name={{ item }} groups=dynamic_targets ansible_connection=local with_items: target_nodes when: dynamic_targets_created is undefined and bminfo.whoami != item - set_fact: dynamic_targets_created=True 07070100000035000081A400000000000000000000000162FD641A00000327000000000000000000000000000000000000005300000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks/get-power-status.yml# # (c) Copyright 2015 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # - name: cobbler | get-power-status | Get power status ipmi: name={{ inventory_hostname }} credsfile={{ baremetal_config }} power=status register: ipmi_connectivity 07070100000036000081A400000000000000000000000162FD641A00000544000000000000000000000000000000000000005700000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks/get-rhel-loader-file.yml# # (c) Copyright 2016 Hewlett Packard Enterprise Development LP # (c) Copyright 2017,2018 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # --- - name: cobbler | create-rhel-loader-file | Set vars dependent on target OS include_vars: "{{ ansible_os_family.split(' ')[0] | lower | replace('open','') }}.yml" - name: cobbler | get-rhel-loader-file | define grub file to load set_fact: dest_file: grubx64.efi when: filepath | basename == "grubx64.efi" - name: cobbler | get-rhel-loader-file | define shim file to load set_fact: dest_file: shim.efi.signed when: filepath | basename == "shim.efi" - name: cobbler | get-rhel-loader-file | Move loader into cobbler become: yes copy: src: "{{ filepath }}" dest: "{{ cobbler_tftp_dir }}/grub/{{ dest_file }}" owner: root group: root when: dest_file is defined 07070100000037000081A400000000000000000000000162FD641A00000C02000000000000000000000000000000000000005200000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks/get-rhel-loader.yml# # (c) Copyright 2016 Hewlett Packard Enterprise Development LP # (c) Copyright 2017-2018 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # --- - name: cobbler | get-rhel-loader | Set vars dependent on target OS include_vars: "{{ ansible_os_family.split(' ')[0] | lower | replace('open','') }}.yml" - name: cobbler | get-rhel-loader | Install rpm2cpio for debian host become: yes apt: name: rpm2cpio state: installed when: ansible_os_family | lower == 'debian' - name: cobbler | get-rhel-loader | Mount iso on deployer become: yes mount: name: /mnt src: "{{ rhel_iso_location }}" fstype: iso9660 opts: ro state: mounted - name: cobbler | get-rhel-loader | Create tmp dir on deployer command: mktemp -dt ardana.XXXXXXXX register: uefi_deployer_tmp_dir_result - name: cobbler | get-rhel-loader | Define deployer tmp dir fact set_fact: uefi_deployer_tmp_dir: "{{ uefi_deployer_tmp_dir_result.stdout }}" - name: cobbler | get-rhel-loader | Extract shim/grub on deployer become: yes copy: src: "{{ item }}" dest: "{{ uefi_deployer_tmp_dir }}" with_fileglob: - /mnt/Packages/{{ rhel_shim_rpm }} - /mnt/Packages/{{ rhel_grub2_efi_rpm }} - name: cobbler | get-rhel-loader | Unmount iso on deployer become: yes mount: name: /mnt src: "{{ rhel_iso_location }}" fstype: iso9660 state: unmounted - name: cobbler | get-rhel-loader | Execute rpm2cpio become: yes shell: rpm2cpio {{ item }} | cpio -dimv args: chdir: "{{ uefi_deployer_tmp_dir }}" with_fileglob: - "{{ uefi_deployer_tmp_dir }}/{{ rhel_shim_rpm }}" - "{{ uefi_deployer_tmp_dir }}/{{ rhel_grub2_efi_rpm }}" - name: cobbler | get-rhel-loader | Move loader into cobbler become: yes shell: > mv {{ uefi_deployer_tmp_dir }}/{{ grubx64_location }} \ "{{ cobbler_tftp_dir }}/grub" - name: cobbler | get-rhel-loader | Move shim into cobbler become: yes shell: > mv {{ uefi_deployer_tmp_dir }}/{{ rhel_shim_location }} \ "{{ cobbler_tftp_dir }}/grub/shim.efi.signed" - name: cobbler | get-rhel-loader | root owns the loader become: yes file: path: "{{ cobbler_tftp_dir }}/grub/grubx64.efi" owner: root group: root mode: 0644 - name: cobbler | get-rhel-loader | root owns the shim become: yes file: path: "{{ cobbler_tftp_dir }}/grub/shim.efi.signed" owner: root group: root mode: 0644 - name: cobbler | get-rhel-loader | Cleanup deployer tmp dir become: yes file: path: "{{ uefi_deployer_tmp_dir }}" state: absent 07070100000038000081A400000000000000000000000162FD641A00000541000000000000000000000000000000000000005700000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks/get-sles-loader-file.yml# # (c) Copyright 2016 Hewlett Packard Enterprise Development LP # (c) Copyright 2017,2018 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # --- - name: cobbler | get-sles-loader-file | Set vars dependent on target OS include_vars: "{{ ansible_os_family.split(' ')[0] | lower | replace('open','') }}.yml" - name: cobbler | get-sles-loader-file | define grub file to load set_fact: dest_file: grubx64.efi when: filepath | basename == "grubx64.efi" - name: cobbler | get-sles-loader-file | define shim file to load set_fact: dest_file: shim.efi.signed when: filepath | basename == "shim.efi" - name: cobbler | get-sles-loader-file | Move loader into cobbler become: yes copy: src: "{{ filepath }}" dest: "{{ cobbler_tftp_dir }}/grub/{{ dest_file }}" owner: root group: root when: dest_file is defined 07070100000039000081A400000000000000000000000162FD641A00000D4C000000000000000000000000000000000000005200000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks/get-sles-loader.yml# # (c) Copyright 2016 Hewlett Packard Enterprise Development LP # (c) Copyright 2017,2018 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # --- - name: cobbler | get-sles-loader | Set vars dependent on target OS include_vars: "{{ ansible_os_family.split(' ')[0] | lower | replace('open','') }}.yml" - name: cobbler | get-sles-loader | Install rpm2cpio become: yes apt: name: rpm2cpio state: installed - name: cobbler | get-sles-loader | Mount iso on deployer become: yes mount: name: /mnt src: "{{ sles_iso_location }}" fstype: iso9660 opts: ro state: mounted - name: cobbler | get-sles-loader | Create tmp dir on deployer command: mktemp -dt ardana.XXXXXXXX register: uefi_deployer_tmp_dir_result - name: cobbler | get-sles-loader | Define deployer tmp dir fact set_fact: uefi_deployer_tmp_dir: "{{ uefi_deployer_tmp_dir_result.stdout }}" - name: cobbler | get-sles-loader | Extract shim/grub on deployer become: yes copy: src: "{{ item }}" dest: "{{ uefi_deployer_tmp_dir }}" with_fileglob: - /mnt/suse/x86_64/{{ sles_shim_rpm }} - /mnt/suse/x86_64/{{ sles_grub2_efi_rpm }} - name: cobbler | get-sles-loader | Unmount iso on deployer become: yes mount: name: /mnt src: "{{ sles_iso_location }}" fstype: iso9660 state: unmounted - name: cobbler | get-sles-loader | Execute rpm2cpio become: yes shell: rpm2cpio {{ item }} | cpio -dimv args: chdir: "{{ uefi_deployer_tmp_dir }}" with_fileglob: - "{{ uefi_deployer_tmp_dir }}/{{ sles_shim_rpm }}" - "{{ uefi_deployer_tmp_dir }}/{{ sles_grub2_efi_rpm }}" - name: cobbler | get-sles-loader | Move loader into cobbler become: yes command: > mv "{{ uefi_deployer_tmp_dir }}/{{ sles_grubx64_location }} " "{{ cobbler_tftp_dir }}/grub/grub.efi" - name: cobbler | get-sles-loader | Make x86_64-efi module directory become: yes command: > mkdir "{{ cobbler_tftp_dir }}/grub/x86_64-efi" - name: cobbler | get-sles-loader | Move regexp module into cobbler become: yes command: > mv "{{ uefi_deployer_tmp_dir }}/{{ sles_regexp_location }}" "{{ cobbler_tftp_dir }}/grub/x86_64-efi/regexp.mod" - name: cobbler | get-sles-loader | Move shim into cobbler become: yes command: > mv "{{ uefi_deployer_tmp_dir }}/{{ sles_shim_location }} " "{{ cobbler_tftp_dir }}/grub/shim.efi.signed" - name: cobbler | get-sles-loader | root owns the loader become: yes file: path: "{{ cobbler_tftp_dir }}/grub/grub.efi" owner: root group: root mode: 0644 - name: cobbler | get-sles-loader | root owns the shim become: yes file: path: "{{ cobbler_tftp_dir }}/grub/shim.efi.signed" owner: root group: root mode: 0644 - name: cobbler | get-sles-loader | Cleanup deployer tmp dir become: yes file: path: "{{ uefi_deployer_tmp_dir }}" state: absent 0707010000003A000081A400000000000000000000000162FD641A000012B4000000000000000000000000000000000000004A00000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks/install.yml# # (c) Copyright 2015-2017 Hewlett Packard Enterprise Development LP # (c) Copyright 2017-2018 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # # Playbook for installing cobbler --- - name: cobbler | install | Set vars dependent on target OS include_vars: "{{ ansible_os_family.split(' ')[0] | lower | replace('open','') }}.yml" # Remove any old atftp (this also stops the service) - name: cobbler | install | Remove conflicting packages become: yes package: name: "{{ item }}" state: absent with_items: cobbler_remove_packages - name: cobbler | install | Install cobbler and dependencies become: yes package: name: "{{ item }}" state: present with_items: cobbler_install_packages - name: cobbler | install | Create validate json script copy: src: validate_yaml dest: ~/ mode: "u=rwx" - name: cobbler | install | Set bm_schema_{base_dir,path} for nonlegacy layout set_fact: bm_schema_base_dir: "{{ lookup( 'pipe', '/usr/bin/python -c \"import ardana_configurationprocessor as acp; print(acp.__file__)\"' | quote) | quote | dirname }}" bm_schema_path: '/data/Site/Schema/2.0/server.yml' when: deployer_media_legacy_layout|bool == False - name: cobbler | install | Validate json schema command: ~/validate_yaml {{ bm_schema_base_dir }}{{ bm_schema_path }} {{ baremetal_config }} - name: cobbler | install | stop tftpd become: yes command: "systemctl stop {{ cobbler_tftp_service_name }}" - name: cobbler | install | disable tftpd become: yes command: "systemctl disable {{ cobbler_tftp_service_name }}" - name: cobbler install | Get interface name shell: netstat -ie | grep -B1 "{{ cobbler_server_ip_addr }}" | head -n1 | awk '{ print $1 }' register: interface_name changed_when: false - name: check if interface matches baremetal file fail: msg: "Please update your baremetal file with the new interface name {{ interface_name.stdout }}" when: interface_name.stdout != cobbler_server_interface # isc-dhcp-server will fail to install if dest=/etc/default/isc-dhcp-server is not present # and containing the INTERFACES param # TODO - Log bugzilla for this packaging issue - name: cobbler | install | Create isc-dhcp-server conf file become: yes template: src: isc-dhcp-server.j2 dest: /etc/default/isc-dhcp-server when: not cobbler_is_sles - name: cobbler | install | Install isc-dhcp-server become: yes package: name: "{{ cobbler_dhcp_package_name }}" state: present - name: cobbler | install | Create dhcp conf file become: yes template: src: dhcpd.conf.j2 dest: "{{ cobbler_dhcp_config_file }}" - name: cobbler | install | Populate isc-dhcp-server sysconfig file become: yes lineinfile: dest: /etc/sysconfig/dhcpd regexp: '^DHCPD_INTERFACE=.*' line: 'DHCPD_INTERFACE="{{ cobbler_server_interface }}"' when: cobbler_is_sles - name: cobbler | install | Create dhcpd.service.d systemd path become: yes file: path: /etc/systemd/system/dhcpd.service.d state: directory mode: 0755 when: cobbler_is_sles - name: cobbler | install | Create dhcpd.service.d/start-limit.conf become: yes template: src: dhcpd-start-limit.conf.j2 dest: /etc/systemd/system/dhcpd.service.d/start-limit.conf mode: 0644 register: _dhcpd_conf_result when: cobbler_is_sles - name: cobbler | install | Reload systemd for dhcpd.service extension become: yes command: systemctl daemon-reload when: cobbler_is_sles and _dhcpd_conf_result | changed - name: cobbler | install | Create ipmi lanplus power file become: yes copy: src: fence_ipmitool.template dest: /etc/cobbler/power/fence_ipmitool.template - name: cobbler | install | Get deployer pub ssh key command: cat {{ ardanauser_deployer_home }}/.ssh/id_rsa.pub register: sshkeyoutput - name: cobbler | install | Save deployer ssh key set_fact: deployer_ssh_pub_key: "{{ sshkeyoutput.stdout }}" - name: cobbler | install | Install kickstarts become: yes template: src: "{{ item[0].kickstart }}.j2" dest: "/var/lib/cobbler/kickstarts/{{ item[0].kickstart }}-{{ item[1].id }}" when: "'{{ item[0].name }}-{{ item[0].arch }}' == '{{ item[1].distro_id }}'" with_nested: - remote_distros - bminfo.servers 0707010000003B000081A400000000000000000000000162FD641A0000031C000000000000000000000000000000000000004E00000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks/netboot-off.yml# # (c) Copyright 2015 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # - name: cobbler | netboot-off | Disallow netboot in Cobbler become: yes command: cobbler system edit --name={{ inventory_hostname }} --netboot-enabled=0 0707010000003C000081A400000000000000000000000162FD641A00000318000000000000000000000000000000000000004D00000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks/netboot-on.yml# # (c) Copyright 2015 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # - name: cobbler | netboot-on | Allow netboot in Cobbler become: yes command: cobbler system edit --name={{ inventory_hostname }} --netboot-enabled=1 0707010000003D000081A400000000000000000000000162FD641A00000E04000000000000000000000000000000000000005C00000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks/populate-rhel-per-profile.yml# # (c) Copyright 2017-2018 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # --- - name: cobbler | populate-rhel-per-profile | Check RHEL Distro become: yes command: > cobbler distro report --name {{ use_rhel_profile }}-x86_64 register: _rhel_distro_exist_result failed_when: false changed_when: false - name: cobbler | populate-rhel-per-profile | Install RHEL kickstarts become: yes template: src: "{{ use_rhel_profile }}-anaconda-ks.cfg.j2" dest: "/var/lib/cobbler/kickstarts/{{ item }}" owner: "root" group: "root" mode: 0644 with_items: - "{{ use_rhel_profile }}-anaconda-ks.cfg" - "{{ use_rhel_profile }}-anaconda-ks-multipath.cfg" - name: cobbler | populate-rhel-per-profile | Customize multipath kickstart become: yes replace: dest: "/var/lib/cobbler/kickstarts/{{ use_rhel_profile }}-anaconda-ks-multipath.cfg" regexp: "{{ cobbler_root_device }}" replace: "{{ boot_from_san_root_device }}" - name: cobbler | populate-rhel-per-profile | Test for RHEL7 ISO stat: path: "{{ ardanauser_deployer_home }}/{{ deployer_rhel7_iso }}" get_checksum: no get_md5: no register: _deployer_rhel7_iso_exists_result - name: cobbler | populate-rhel-per-profile | Create temporary mount directory become: yes command: mktemp -d -p /srv register: _mount_tmpdir when: _deployer_rhel7_iso_exists_result.stat.exists and _rhel_distro_exist_result.rc != 0 - name: cobbler | populate-rhel-per-profile | Mount RHEL ISO become: yes shell: | mount -o loop "{{ ardanauser_deployer_home }}/{{ deployer_rhel7_iso }}" "{{ _mount_tmpdir.stdout }}" when: _deployer_rhel7_iso_exists_result.stat.exists and _rhel_distro_exist_result.rc != 0 - name: cobbler | populate-rhel-per-profile | Cobbler import become: yes shell: > cobbler import --path {{ _mount_tmpdir.stdout }} --name {{ use_rhel_profile }} --kickstart "/var/lib/cobbler/kickstarts/{{ use_rhel_profile }}-anaconda-ks.cfg" when: _deployer_rhel7_iso_exists_result.stat.exists and _rhel_distro_exist_result.rc != 0 - name: cobbler | populate-rhel-per-profile | Create multipath profiles become: yes shell: > cobbler profile report --name "{{ item.distro_id }}-{{ item.id }}" || cobbler profile add --name="{{ item.distro_id }}-{{ item.id }}" --distro="{{ use_rhel_profile }}-x86_64" --kickstart "/var/lib/cobbler/kickstarts/{{ use_rhel_profile }}-anaconda-ks-multipath.cfg" when: "'{{ item.distro_id }}' == '{{ use_rhel_profile }}-x86_64-multipath' and _deployer_rhel7_iso_exists_result.stat.exists" with_items: bminfo.servers - name: cobbler | populate-rhel-per-profile | Umount ISO become: yes shell: | umount {{ _mount_tmpdir.stdout }} when: _deployer_rhel7_iso_exists_result.stat.exists and _rhel_distro_exist_result.rc != 0 - name: cobbler | populate-rhel-per-profile | Remove temporary mount directory become: yes file: path: "{{ _mount_tmpdir.stdout }}" state: absent when: _deployer_rhel7_iso_exists_result.stat.exists and _rhel_distro_exist_result.rc != 0 0707010000003E000081A400000000000000000000000162FD641A00000366000000000000000000000000000000000000005000000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks/populate-rhel.yml# # (c) Copyright 2016-2017 Hewlett Packard Enterprise Development LP # (c) Copyright 2017-2018 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # --- - include_vars: ../../deployer-setup/defaults/ardana_tar_locations.yml - include: populate-rhel-per-profile.yml vars: use_rhel_profile: "{{ rhel_profile_name }}" when: rhel_profile_name | default('') != '' 0707010000003F000081A400000000000000000000000162FD641A00000DEC000000000000000000000000000000000000005000000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks/populate-sles.yml# # (c) Copyright 2017 Hewlett Packard Enterprise Development LP # (c) Copyright 2017-2018 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # --- - include_vars: ../../deployer-setup/defaults/ardana_tar_locations.yml - name: cobbler | populate-sles | Check SLES Distro become: yes command: > cobbler distro report --name="{{ sles_profile_name }}-x86_64" register: _sles12_distro_exist_result failed_when: false changed_when: false - name: cobbler | populate-sles | Install SLES kickstart (autoyast) become: yes template: src: "sles12sp3-autoyast.xml.j2" dest: "/var/lib/cobbler/kickstarts/sles12sp3-autoyast.xml" owner: "root" group: "root" mode: 0644 - name: cobbler | populate-sles | Test for SLES ISO file in home folder stat: path: "{{ ardanauser_deployer_home }}/{{ deployer_sles12_iso }}" get_checksum: no get_md5: no register: _deployer_sles12_iso_exists_result - name: cobbler | populate-sles | Test for SLES ISO mounted at /media/cdrom stat: path: "/media/cdrom/suse" get_checksum: no get_md5: no register: _deployer_sles12_cdrom_exists_result - name: cobbler | populate-sles | Create temporary mount directory become: yes command: mktemp -d -p /srv register: _mount_tmpdir when: (_deployer_sles12_iso_exists_result.stat.exists or _deployer_sles12_cdrom_exists_result.stat.exists) and _sles12_distro_exist_result.rc != 0 - name: cobbler | populate-sles | Mount SLES ISO become: yes command: > mount -o ro,loop "{{ ardanauser_deployer_home }}/{{ deployer_sles12_iso }}" \ "{{ _mount_tmpdir.stdout }}" when: _deployer_sles12_iso_exists_result.stat.exists and _sles12_distro_exist_result.rc != 0 - name: cobbler | populate-sles | Rsync SLES ISO to temporary folder become: yes synchronize: src: "/media/cdrom/" dest: "{{ _mount_tmpdir.stdout }}/" delete: true times: no rsync_opts: - "--exclude=ardana" when: _deployer_sles12_cdrom_exists_result.stat.exists and not _deployer_sles12_iso_exists_result.stat.exists and _sles12_distro_exist_result.rc != 0 - name: cobbler | populate-sles | Cobbler import become: yes command: > cobbler import --path {{ _mount_tmpdir.stdout }} --name {{ sles_profile_name }} --kickstart /var/lib/cobbler/kickstarts/sles12sp3-autoyast.xml when: (_deployer_sles12_iso_exists_result.stat.exists or _deployer_sles12_cdrom_exists_result.stat.exists) and _sles12_distro_exist_result.rc != 0 - name: cobbler | populate-sles | Umount ISO become: yes command: > umount {{ _mount_tmpdir.stdout }} when: _deployer_sles12_iso_exists_result.stat.exists and _sles12_distro_exist_result.rc != 0 - name: cobbler | populate-sles | Remove temporary directory become: yes file: path: "{{ _mount_tmpdir.stdout }}" state: absent when: (_deployer_sles12_iso_exists_result.stat.exists or _deployer_sles12_cdrom_exists_result.stat.exists) and _sles12_distro_exist_result.rc != 0 07070100000040000081A400000000000000000000000162FD641A00001A6B000000000000000000000000000000000000004B00000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks/populate.yml# # (c) Copyright 2015-2017 Hewlett Packard Enterprise Development LP # (c) Copyright 2017-2018 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # --- # Make path for isos - name: cobbler | populate | Create directory for isos become: yes file: path: /srv/www/cobbler/iso state: directory mode: 0755 # Remote distros - name: Compile distro in-use list set_fact: remote_distros_inuse: > {%- set distros = [] %} {%- for distro_id in bminfo.servers | map(attribute='distro_id') | unique %} {%- for distro in remote_distros %} {%- if [distro.name, distro.arch] | join('-') == distro_id %} {%- set _ = distros.append(distro) %} {%- endif %} {%- endfor %} {%- endfor %} {{- distros -}} - name: cobbler | populate | Check distro exists in cobbler become: yes with_items: remote_distros_inuse command: cobbler distro report --name={{ item.name }}-{{ item.arch }} register: distro_exists changed_when: false failed_when: false - name: cobbler | populate | Fail if any managed distro(s) are missing fail: msg: "Cobbler distro {{ item.item.name }}-{{ item.item.arch }}, managed by '{{ item.item.managed_by }}', does not exist" when: item.rc != 0 and item.item.managed_by|default('') != '' with_items: distro_exists.results - name: cobbler | populate | Create directory for net images become: yes file: path: "{{ item.item.file }}" state: directory mode: 0755 when: item.rc != 0 and item.item.managed_by|default('') == '' with_items: distro_exists.results - name: cobbler | populate | Get net kernel become: yes get_url: url: "{{ item.item.url }}/dists/{{ item.item.distro }}/{{ item.item.url_boot_path }}/{{ item.item.kernel }}" dest: "{{ item.item.file }}" when: item.item.managed_by|default('') == '' with_items: distro_exists.results - name: cobbler | populate | Get net initrd become: yes get_url: url: "{{ item.item.url }}/dists/{{ item.item.distro }}/{{ item.item.url_boot_path }}/{{ item.item.initrd }}" dest: "{{ item.item.file }}" when: item.item.managed_by|default('') == '' with_items: distro_exists.results - name: cobbler | populate | Add distro become: yes shell: > cobbler distro add --name="{{ item.item.name }}-{{ item.item.arch }}" --kernel="{{ item.item.file }}/{{ item.item.kernel }}" --initrd="{{ item.item.file }}/{{ item.item.initrd }}" {% if item.item.os_version is defined %}--os-version={{ item.item.os_version }}{% endif %} --arch={{ item.item.arch | quote }} --breed={{ item.item.breed }} --kopts="{{ item.item.kopts | default('') }}" when: item.rc != 0 and item.item.managed_by|default('') == '' with_items: distro_exists.results - name: cobbler | populate | Add Profile become: yes shell: > cobbler profile report --name "{{ item[1].distro_id }}-{{ item[1].id }}" || cobbler profile add --name="{{ item[1].distro_id }}-{{ item[1].id }}" --distro="{{ item[1].distro_id }}" --kickstart="/var/lib/cobbler/kickstarts/{{ item[0].item.kickstart }}-{{ item[1].id }}" when: "'{{ item[0].item.name }}-{{ item[0].item.arch }}' == '{{ item[1].distro_id }}'" with_nested: - distro_exists.results - bminfo.servers - name: cobbler | populate | Check system exists in cobbler become: yes with_items: bminfo.servers command: cobbler system report --name={{ item.id | quote }} register: systems_exists changed_when: false failed_when: false # I think we should probably assign the ip addresses here as static # Need to get dhcp managed by cobbler - name: cobbler | populate | Load servers into cobbler become: yes shell: > cobbler system add --name={{ item.item.id | quote }} --profile="{{ item.item.distro_id }}-{{ item.item.id }}" --ip-address={{ item.item.ip_addr | quote }} {% if item.item.distro_id | search('^hlinux') or item.item.distro_id | search('^rhel') %} --kopts="interface={{ item.item.mac_addr }} netcfg/dhcp_timeout={{ dhcp_timeout }} {{ item.item.kopt_extras | default('') }}" {% elif item.item.distro_id | search('^sles') %} --kopts="ifcfg={{ item.item.mac_addr }}=dhcp4,DHCLIENT_WAIT_AT_BOOT={{ dhcp_timeout }},WAIT_FOR_INTERFACES={{ dhcp_timeout }} {{ item.item.kopt_extras | default('') }}" {% endif %} --gateway={{ cobbler_gateway }} --mac={{ item.item.mac_addr | quote }} --interface={{ item.item.mac_addr | quote }} --hostname={{ item.item.id | quote }} --netboot-enabled=true --power-type=ipmitool --power-address={{ item.item.ilo_ip | quote }} --power-user="redacted" --power-pass="redacted" when: item.rc != 0 and bminfo.whoami != item.item.id with_items: systems_exists.results - name: cobbler | populate | Cobbler sync become: yes command: cobbler sync # WARNING: If you need to call cobbler sync again, files listed below need to be # copied again to tftp dir, because cobbler sync will remove them. # In Debian, pxelinux v6 needs additional loadable module which is not properly # copied during cobbler sync. In SLES, pxelinux v4 does not require this module. - name: cobbler | populate | Insert ldlinux.c32 file become: yes command: "cp -f /var/lib/cobbler/loaders/ldlinux.c32 {{ cobbler_tftp_dir }}/ldlinux.c32" when: ansible_os_family == 'Debian' # grub/shim.efi.signed and grub/grub.cfg are needed for UEFI boot - name: cobbler | populate | Insert shim.efi.signed file become: yes command: "cp -f /var/lib/cobbler/loaders/shim.efi.signed {{ cobbler_tftp_dir }}/grub" # in SLES/OpenSUSE, cobbler puts invalid symlink for grub/grub.efi, where we need a hardcopy file - name: cobbler | populate | Insert shim.efi.signed file become: yes command: "cp -f --remove-destination {{ cobbler_tftp_dir }}/grub/x86_64-efi/grub.efi {{ cobbler_tftp_dir }}/grub/grub.efi" when: cobbler_is_sles - name: cobbler | populate | Insert grub.cfg file become: yes template: src: grub.cfg.j2 dest: "{{ cobbler_tftp_dir }}/grub/grub.cfg" # Seems we need the xinetd restart here - name: cobbler | populate | Enable and restart xinetd become: yes service: name: xinetd state: restarted enabled: yes 07070100000041000081A400000000000000000000000162FD641A00000478000000000000000000000000000000000000004E00000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks/power-cycle.yml# # (c) Copyright 2015 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # - name: cobbler | power-cycle | Check power status ipmi: name={{ inventory_hostname }} credsfile={{ baremetal_config }} power=status register: pstatus - name: cobbler | power-cycle | Power cycle node if on ipmi: name={{ inventory_hostname }} credsfile={{ baremetal_config }} power=cycle sleep=1 when: pstatus.power == "on" - name: cobbler | power-cycle | Power up node if off ipmi: name={{ inventory_hostname }} credsfile={{ baremetal_config }} power=on sleep=1 when: pstatus.power == "off" 07070100000042000081A400000000000000000000000162FD641A000003DB000000000000000000000000000000000000004D00000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks/power-down.yml# # (c) Copyright 2015 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # # We probably don't want to power down potentially hundreds of nodes in the # data center in one go. For now we will simply pause between commands, but # longer term we may need something more sophisticated. - name: cobbler | power-down | Power the node down ipmi: name={{ inventory_hostname }} credsfile={{ baremetal_config }} power=off sleep=1 07070100000043000081A400000000000000000000000162FD641A00000302000000000000000000000000000000000000004B00000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks/power-up.yml# # (c) Copyright 2015 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # - name: cobbler | power-up | Power node up ipmi: name={{ inventory_hostname }} credsfile={{ baremetal_config }} power=on sleep=3 07070100000044000081A400000000000000000000000162FD641A000006B3000000000000000000000000000000000000005000000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks/reconfig-dhcp.yml# # (c) Copyright 2016 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # # -------------------------------------------------------------------------- # The name of the network interface that Cobbler is using will potentially # change after the NIC Mappings are applied in osconfig-run. If that happens # then the Cobbler DHCP configuration will be stale and we need to update it # with the new name of that interface. The correct value has already been # computed in set-vars and is available to us as "cobbler_server_interface". --- - name: cobbler | reconfig-dhcp | am i running cobbler dhcp stat: path: /etc/init.d/isc-dhcp-server register: cobbler_dhcp_here_result - name: cobbler | reconfig-dhcp | set interface name become: yes lineinfile: create: no dest: /etc/default/isc-dhcp-server regexp: ^INTERFACES=.* line: INTERFACES="{{ cobbler_server_interface }}" when: cobbler_dhcp_here_result.stat.exists register: cobbler_dhcp_changed_result - name: cobbler | reconfig-dhcp | restart service become: yes service: name: isc-dhcp-server state: restarted when: cobbler_dhcp_changed_result | changed 07070100000045000081A400000000000000000000000162FD641A0000080F000000000000000000000000000000000000004F00000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks/set-diskboot.yml# # (c) Copyright 2015 Hewlett Packard Enterprise Development LP # (c) Copyright 2017-2018 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # - name: cobbler | set-diskboot | Set boot order to local disk ipmi: name={{ inventory_hostname }} credsfile={{ baremetal_config }} bootdev=disk options=persistent # BUG 1484 Sending options=persistent to a node that is in UEFI mode # will cause it to switch to Legacy BIOS on its next reset. We don't # want that to happen, so send it options=efiboot to tell it that it's # it's OK to stay in UEFI mode. Despite its name, this option means # "stay in whatever boot mode you're in" so it is safe to send to # Legacy nodes also i.e. it will not switch them to UEFI. # Some older iLOs don't support this flag and will return an error. - name: cobbler | set-diskboot | Get bios mode ipmi: name={{ inventory_hostname }} credsfile={{ baremetal_config }} passthru="mc info" register: my_result - name: cobbler | set-diskboot | Get the oemhp_bootmode when HP ILO hpilo: name={{ inventory_hostname }} credsfile={{ baremetal_config }} command="show /system1/bootconfig1 oemhp_bootmode" register: oemhp_bootmode when: my_result.stdout | search("Hewlett-Packard") - name: cobbler | set-diskboot | Make UEFI/Legacy mode sticky ipmi: name={{ inventory_hostname }} credsfile={{ baremetal_config }} bootdev=disk options=efiboot ignore_errors: True when: not my_result.stdout | search("Hewlett-Packard") or (my_result.stdout | search("Hewlett-Packard") and oemhp_bootmode.stdout | search("UEFI")) 07070100000046000081A400000000000000000000000162FD641A00000801000000000000000000000000000000000000004E00000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks/set-pxeboot.yml# # (c) Copyright 2015 Hewlett Packard Enterprise Development LP # (c) Copyright 2017-2018 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # - name: cobbler | set-pxeboot | Set boot order to PXE ipmi: name={{ inventory_hostname }} credsfile={{ baremetal_config }} bootdev=pxe options=persistent # BUG 1484 Sending options=persistent to a node that is in UEFI mode # will cause it to switch to Legacy BIOS on its next reset. We don't # want that to happen, so send it options=efiboot to tell it that it's # it's OK to stay in UEFI mode. Despite its name, this option means # "stay in whatever boot mode you're in" so it is safe to send to # Legacy nodes also i.e. it will not switch them to UEFI. # Some older iLOs don't support this flag and will return an error. - name: cobbler | set-pxeboot | Get bios mode ipmi: name={{ inventory_hostname }} credsfile={{ baremetal_config }} passthru="mc info" register: my_result - name: cobbler | set-pxeboot | Get the oemhp_bootmode when HP ILO hpilo: name={{ inventory_hostname }} credsfile={{ baremetal_config }} command="show /system1/bootconfig1 oemhp_bootmode" register: oemhp_bootmode when: my_result.stdout | search("Hewlett-Packard") - name: cobbler | set-pxeboot | Make UEFI/Legacy mode sticky ipmi: name={{ inventory_hostname }} credsfile={{ baremetal_config }} bootdev=pxe options=efiboot ignore_errors: True when: not my_result.stdout | search("Hewlett-Packard") or (my_result.stdout | search("Hewlett-Packard") and oemhp_bootmode.stdout | search("UEFI")) 07070100000047000081A400000000000000000000000162FD641A00000477000000000000000000000000000000000000005000000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks/set-rhel-vars.yml# # (c) Copyright 2017-2018 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # --- - name: cobbler | set-rhel-vars | Set rhel vars for distro used via supported distro and bminfo servers data set_fact: rhel_profile_name: "{{ item[0].name }}" rhel_entry_name: "{{ item[0].entry_name }}" rhel_grub2_efi_rpm: "{{ item[0].grub2_efi_rpm }}" rhel_shim_rpm: "{{ item[0].rhel_shim_rpm }}" when: "'{{ item[0].name }}-{{ item[0].arch }}' == '{{ item[1].distro_id }}' and \ {{ 'managed_by' in item[0] }} and \ '{{ item[0].managed_by }}' == 'rhel'" with_nested: - remote_distros - bminfo.servers 07070100000048000081A400000000000000000000000162FD641A00000320000000000000000000000000000000000000005000000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks/set-sles-vars.yml# # (c) Copyright 2018 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # --- # Set vars for SUSE repos - include: check-sles-repos.yml vars: _input_repos_list: "{{ sles_expected_media_repos }}" _input_uri_pattern: "^dir\\:\\/\\/\\/srv\\/www\\/suse-{{ansible_distribution_version}}\\/" 07070100000049000081A400000000000000000000000162FD641A00000C61000000000000000000000000000000000000004B00000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks/set-vars.yml# # (c) Copyright 2015-2017 Hewlett Packard Enterprise Development LP # (c) Copyright 2017-2018 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # # This task uses the bminfo struct from get-baremetal-info.yml to derive a # bunch of convenience variables that are used in various other plays. It then # goes further and figures out the name of the network interface that Cobbler # is using, by comparing the baremetal CIDR specified in the model with the # actual values in "ip a" on localhost. --- - include: get-baremetal-info.yml - name: cobbler | set-vars | Set baremetal network subnet set_fact: cobbler_subnet: "{{ bminfo.network.subnet }}" when: cobbler_subnet is not defined - name: cobbler | set-vars | Set baremetal network netmask set_fact: cobbler_netmask: "{{ bminfo.network.netmask }}" when: cobbler_netmask is not defined - name: cobbler | set-vars | Set baremetal network cidr set_fact: cobbler_cidr: "{{ bminfo.network.cidr }}" when: cobbler_cidr is not defined - name: cobbler | set-vars | List available nics local_action: shell ip a | awk '/^[0-9]/ { sub(":","",$2) ; iface=$2 } $1 == "inet" {print iface, $2 }' register: _candidates when: cobbler_server_interface is not defined changed_when: false - name: cobbler | set-vars | Search for an interface on this cidr match-cidr: cidr="{{ cobbler_cidr }}" ips="{{ _candidates.stdout }}" register: _selected when: cobbler_server_interface is not defined # We want this in the log for debug purposes, in case it's wrong and needs manual override. - debug: var=_selected when: _selected is defined - name: cobbler | set-vars | Select this interface set_fact: cobbler_server_interface: "{{ _selected.stdout }}" when: cobbler_server_interface is not defined - name: cobbler | set-vars | Select ip address set_fact: cobbler_server_ip_addr: "{{ _selected.ip }}" when: cobbler_server_ip_addr is not defined # An override gateway for CI - name: cobbler | set-vars | Set baremetal network gateway set_fact: cobbler_gateway: "{{ cobbler_server_ip_addr }}" when: cobbler_gateway is not defined # An override nameserver for CI - name: cobbler | set-vars | Set baremetal network name server set_fact: cobbler_name_server: "{{ cobbler_server_ip_addr }}" when: cobbler_name_server is not defined - name: cobbler | set-vars | Set local repo ip url set_fact: deployer_server: "http://{{ cobbler_server_ip_addr }}:{{ deployer_server_port }}" when: deployer_server is not defined # Set vars for currently used rhel distro - include: set-rhel-vars.yml # Set vars for currently used SLES distro - include: set-sles-vars.yml 0707010000004A000081A400000000000000000000000162FD641A00000486000000000000000000000000000000000000004800000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks/start.yml# # (c) Copyright 2015-2017 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # --- - name: cobbler | start | Enable and restart dhcp service become: yes service: name={{ cobbler_dhcp_service_name }} state=restarted enabled=yes - name: cobbler | start | Enable and restart apache2 become: yes service: name=apache2 state=restarted enabled=yes - name: cobbler | start | Enable and restart cobblerd become: yes service: name=cobblerd state=restarted enabled=yes - name: cobbler | start | Enable and restart xinetd become: yes service: name=xinetd state=restarted enabled=yes 0707010000004B000081A400000000000000000000000162FD641A000006F3000000000000000000000000000000000000005200000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks/synchronize-iso.yml# # (c) Copyright 2017 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # --- - name: cobbler | synchronize-iso | Check if ISO exists stat: path: "{{ iso_src }}" get_checksum: no get_md5: no register: _iso_exists - name: cobbler | synchronize-iso | Create temporary mount directory command: mktemp -d register: _mount_tmpdir when: _iso_exists.stat.exists - name: cobbler | synchronize-iso | Mount ISO become: yes shell: | mount -o loop "{{ iso_src }}" "{{ _mount_tmpdir.stdout }}" when: _iso_exists.stat.exists - name: cobbler | synchronize-iso | Create ISO destination become: yes file: path: "{{ iso_dest }}" state: directory mode: 0755 when: _iso_exists.stat.exists - name: cobbler | synchronize-iso | Synchronize ISO become: yes synchronize: src: "{{ _mount_tmpdir.stdout }}/" dest: "{{ iso_dest }}" when: _iso_exists.stat.exists - name: cobbler | synchronize-iso | Umount ISO become: yes shell: | umount {{ _mount_tmpdir.stdout }} when: _iso_exists.stat.exists - name: cobbler | synchronize-iso | Remove temporary mount directory file: path: "{{ _mount_tmpdir.stdout }}" state: absent when: _iso_exists.stat.exists 0707010000004C000081A400000000000000000000000162FD641A0000039F000000000000000000000000000000000000005300000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks/target-all-nodes.yml# # (c) Copyright 2015 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # --- # If the caller has already set target_nodes then we'll respect that. - include: get-baremetal-info.yml - name: cobbler | target-all-nodes | Compute generic target list set_fact: target_nodes="{{ bminfo.server_ids }}" when: target_nodes is undefined - include: get-nodelist.yml 0707010000004D000081A400000000000000000000000162FD641A000004BE000000000000000000000000000000000000005700000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks/target-netboot-nodes.yml# # (c) Copyright 2015 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # --- # If the caller has already set target_nodes then we'll respect that. - name: cobbler | target-netboot-nodes | Compute the list of netboot nodes become: yes shell: cobbler system report | awk '/^Name *:/ {name=$NF} /^Netboot Enabled *. True/ {print name}' | sort -n register: netbootnodes when: target_nodes is undefined changed_when: false - name: cobbler | target-netboot-nodes | Target the netboot nodes set_fact: target_nodes="{{ netbootnodes.stdout_lines }}" when: target_nodes is undefined and netbootnodes.stdout != "" - include: get-nodelist.yml 0707010000004E000081A400000000000000000000000162FD641A00000441000000000000000000000000000000000000005400000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks/verify-bm-install.yml# # (c) Copyright 2015 Hewlett Packard Enterprise Development LP # (c) Copyright 2017,2018 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # --- - name: vagrant-vm | verify-bm-install | Get md5sum local_action: shell md5sum {{ local_timestamp_file }} | awk '{print $1}' register: local_md5sum_data - name: vagrant-vm | verify-bm-install | Stat baremetal install verification file become: yes shell: md5sum /etc/cobbler_ardana_installed | awk '{print $1}' register: remote_md5sum_data failed_when: remote_md5sum_data.stdout != local_md5sum_data.stdout changed_when: false 0707010000004F000081A400000000000000000000000162FD641A00000479000000000000000000000000000000000000005400000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks/wait-for-shutdown.yml# # (c) Copyright 2015 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # - name: cobbler | wait-for-shutdown | Wait for nodes to power down after network install ipmi: name={{ inventory_hostname }} credsfile={{ baremetal_config }} power=status retries=8 delay=20 register: pstate until: pstate | failed or pstate.power == "off" retries: "{{ off_poll_retries }}" delay: "{{ off_poll_seconds }}" failed_when: pstate | failed or pstate.power != "off" - name: cobbler | wait-for-shutdown | Report any retries debug: msg="{{pstate.stdout}}" when: pstate.stdout != "" 07070100000050000081A400000000000000000000000162FD641A00000757000000000000000000000000000000000000004F00000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/tasks/wait-for-ssh.yml# # (c) Copyright 2015-2017 Hewlett Packard Enterprise Development LP # (c) Copyright 2017,2018 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # --- - name: cobbler | wait-for-ssh | Derive node ip local_action: bmconfig file={{ baremetal_config }} node={{ inventory_hostname }} field=ip_addr register: cobbler_ip - name: cobbler | wait-for-ssh | Wait for ssh to come online local_action: wait_for port=22 host="{{ cobbler_ip.stdout }}" search_regex=OpenSSH timeout="{{ ssh_wait_seconds }}" - name: cobbler | wait-for-ssh | Wait for pam_nologin module to cease local_action: | shell ssh -l {{ ardanauser }} -o StrictHostKeyChecking=no \ -o UserKnownHostsFile=/dev/null {{ cobbler_ip.stdout }} hostname register: remote_ssh_test_result until: remote_ssh_test_result.stderr.find("pam_nologin") == -1 retries: 10 delay: 5 - name: cobbler | wait-for-ssh | Get md5sum local_action: shell md5sum {{ local_timestamp_file }} | awk '{print $1}' register: local_md5sum_data - name: cobbler | wait-for-ssh | check the timestamp on the dest with local local_action: | shell ssh -l {{ ardanauser }} -o StrictHostKeyChecking=no \ -o UserKnownHostsFile=/dev/null {{ cobbler_ip.stdout }} \ md5sum /etc/cobbler_ardana_installed | awk '{print $1}' register: remote_md5sum_data failed_when: remote_md5sum_data.stdout != local_md5sum_data.stdout 07070100000051000041ED00000000000000000000000262FD641A00000000000000000000000000000000000000000000004200000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/templates07070100000052000081A400000000000000000000000162FD641A00000A2A000000000000000000000000000000000000005B00000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/templates/cobbler.dhcp.template.j2{# # # (c) Copyright 2015 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # #} # ****************************************************************** # Cobbler managed dhcpd.conf file # # generated from cobbler dhcp.conf template ($date) # Do NOT make changes to /etc/dhcpd.conf. Instead, make your changes # in /etc/cobbler/dhcp.template, as /etc/dhcpd.conf will be # overwritten. # # ****************************************************************** ddns-update-style interim; allow booting; allow bootp; ignore client-updates; set vendorclass = option vendor-class-identifier; option pxe-system-type code 93 = unsigned integer 16; subnet {{ cobbler_subnet }} netmask {{ cobbler_netmask }} { option routers {{ cobbler_gateway }}; option domain-name-servers {{ cobbler_name_server }}; option subnet-mask {{ cobbler_netmask }}; deny unknown-clients; default-lease-time 21600; max-lease-time 43200; next-server $next_server; class "pxeclients" { match if substring (option vendor-class-identifier, 0, 9) = "PXEClient"; if option pxe-system-type = 00:02 { filename "ia64/elilo.efi"; } else if option pxe-system-type = 00:06 { filename "grub/grub-x86.efi"; } else if option pxe-system-type = 00:07 { filename "grub/shim.efi.signed"; } else { filename "pxelinux.0"; } } } #for dhcp_tag in $dhcp_tags.keys(): ## group could be subnet if your dhcp tags line up with your subnets ## or really any valid dhcpd.conf construct ... if you only use the ## default dhcp tag in cobbler, the group block can be deleted for a ## flat configuration # group for Cobbler DHCP tag: $dhcp_tag group { #for mac in $dhcp_tags[$dhcp_tag].keys(): #set iface = $dhcp_tags[$dhcp_tag][$mac] host $iface.name { hardware ethernet $mac; #if $iface.ip_address: fixed-address $iface.ip_address; #end if #if $iface.hostname: option host-name "$iface.hostname"; #end if #if $iface.netmask: option subnet-mask $iface.netmask; #end if #if $iface.gateway: option routers $iface.gateway; #end if ## Cobbler defaults to $next_server, but some users ## may like to use $iface.system.server for proxied setups next-server $next_server; ## next-server $iface.next_server; } #end for } #end for 07070100000053000081A400000000000000000000000162FD641A00000686000000000000000000000000000000000000005A00000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/templates/configure_network.sh.j2#!/bin/bash {# # (c) Copyright 2016-2017 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. #} intf=$(ip addr | grep -v inet6 | awk '/scope global/ { print $NF }') cidr=$(ip addr | grep -v inet6 | awk '/scope global/ {print $2}') gateway=$(ip route | awk '/default/ {print $3}') #Check for SLES if [[ -e /etc/SuSE-release ]] || grep -qsi suse /etc/*-release then intf=$(echo ${intf} | cut -d' ' -f1) cidr=$(echo ${cidr} | cut -d' ' -f1) cat > /etc/sysconfig/network/ifcfg-${intf} << EOF BOOTPROTO='static' BROADCAST='' ETHTOOL_OPTIONS='' IPADDR=${cidr} MTU='' REMOTE_IPADDR='' STARTMODE='auto' USERCONTROL='no' EOF else echo source "/etc/network/interfaces.d/*" > /etc/network/interfaces echo auto lo >> /etc/network/interfaces echo iface lo inet loopback >> /etc/network/interfaces echo auto ${intf} > /etc/network/interfaces.d/${intf} echo iface ${intf} inet static >> /etc/network/interfaces.d/${intf} echo address ${cidr} >> /etc/network/interfaces.d/${intf} {% if enable_gateway %} echo gateway ${gateway} >> /etc/network/interfaces.d/${intf} {% endif %} fi 07070100000054000081A400000000000000000000000162FD641A000002BB000000000000000000000000000000000000005C00000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/templates/dhcpd-start-limit.conf.j2{# # # (c) Copyright 2018 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # #} [Service] StartLimitInterval={{ sles_dhcpd_start_limit_interval }} StartLimitBurst={{ sles_dhcpd_start_limit_burst }}07070100000055000081A400000000000000000000000162FD641A000003DC000000000000000000000000000000000000005000000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/templates/dhcpd.conf.j2{# # # (c) Copyright 2015 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # #} option domain-name "deployer"; subnet {{ cobbler_subnet }} netmask {{ cobbler_netmask }} { option subnet-mask {{ cobbler_netmask }}; option routers {{ cobbler_gateway }}; deny unknown-clients; option domain-name-servers {{ cobbler_gateway }}; filename "/pxelinux.0"; next-server {{ cobbler_server_ip_addr }}; } 07070100000056000081A400000000000000000000000162FD641A00000199000000000000000000000000000000000000004E00000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/templates/grub.cfg.j2{# # # (c) Copyright 2015 Hewlett Packard Enterprise Development LP # (c) Copyright 2017,2018 SUSE LLC # #} set default=0 loadfont /boot/grub/fonts/unicode.pf2 set gfxmode=auto insmod efi_gop insmod efi_uga insmod gfxterm insmod legacycfg set locale_dir=/boot/grub/locale set lang=en_US set timeout=10 insmod gettext terminal_output gfxterm configfile=/grub/grub.cfg-01-$net_default_mac source "$configfile" 07070100000057000081A400000000000000000000000162FD641A0000022C000000000000000000000000000000000000004B00000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/templates/grub2.j2{# # # (c) Copyright 2016-2017 Hewlett Packard Enterprise Development LP # (c) Copyright 2017-2018 SUSE LLC # #} set timeout=5 menuentry '{{ rhel_entry_name }} Cobbler install' { linuxefi images/{{ rhel_profile_name }}-x86_64/vmlinuz interface={{ item.stdout }} inst.ks=http://{{ cobbler_server_ip_addr }}:79/cblr/svc/op/ks/system/{{ item.item }} inst.repo=http://{{ cobbler_server_ip_addr }}:79/cblr/ks_mirror/{{ rhel_profile_name }} inst.ks.sendmac inst.text ip=dhcp ksdevice=bootif lang= initrdefi images/{{ rhel_profile_name }}-x86_64/initrd.img } 07070100000058000081A400000000000000000000000162FD641A00001C67000000000000000000000000000000000000005E00000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/templates/hlinux-server-vm.preseed.j2{# # # (c) Copyright 2015-2016 Hewlett Packard Enterprise Development LP # (c) Copyright 2017-2018 SUSE LLC # #} #Necessary to access the remote hlinux repo # Will need to be change to point to local d-i mirror/suite string {{ hlinux_distro }} d-i mirror/udeb/suite string {{ hlinux_distro }} {% if item[1].boot_from_san %} disk-detect disk-detect/multipath/enable boolean true {% endif %} d-i mirror/protocol string http d-i mirror/country string manual d-i mirror/http/hostname string {{ deployer_server | replace('http://', '') }} d-i mirror/http/hostname seen true d-i mirror/http/directory string /{{ hlinux_path }} d-i mirror/http/directory seen true d-i mirror/codename string {{ hlinux_distro }} #Ensure the Keyboard config is set ok d-i debian-installer/locale string en_US.UTF-8 d-i keymap select us d-i keyboard-configuration/xkb-keymap select us d-i debian-installer/splash boolean false d-i console-setup/ask_detect boolean false d-i console-setup/layoutcode string us d-i console-setup/variantcode string #May need to modify this for static assignment d-i netcfg/get_nameservers string d-i netcfg/get_ipaddress string d-i netcfg/get_netmask string {{ cobbler_netmask }} d-i netcfg/get_gateway string d-i netcfg/dhcp_timeout string 240 d-i netcfg/confirm_static boolean true d-i netcfg/hostname string ardana #Do not attempt remote ntp config d-i clock-setup/ntp boolean false d-i time/zone string UTC d-i clock-setup/utc boolean true # The d-i netcfg/hostname string ardana does not appear to work # The vgremove should be conditional - as should the rest of # directives to blow away existing config d-i partman/early_command string \ hostname ardana; \ echo ardana > /etc/hostname; \ vgremove -f ardana-vg; \ wget http://$http_server/preseed/configure_partitioning; \ sh ./configure_partitioning $http_server d-i partman-auto/method string lvm # Blow away without prejudice what was there previously # May need to be a bit more conservative here for BM # Also need to add more intelligence to the disk partitioning {% if item[1].boot_from_san %} d-i partman-auto/disk string {{ boot_from_san_root_device }} {% else %} d-i partman-auto/disk string {{ cobbler_root_device }} {% endif %} {% if item[1].persistent_interfaces | length > 0 %} d-i netcfg/persistent_interfaces string {{ item[1].persistent_interfaces | join (", ") }} {% endif %} {% if (item[1].fcoe_interfaces) | length > 0 %} d-i partman-fcoe/interfaces string {{ item[1].fcoe_interfaces | join(',') }} d-i disk-detect/fcoe/enable boolean true {% endif %} d-i partman-auto/purge_lvm_from_device boolean true d-i partman-lvm/device_remove_lvm boolean true d-i partman-md/device_remove_md boolean true d-i partman-lvm/device_remove_lvm_span boolean true d-i partman-lvm/confirm boolean true d-i partman-lvm/confirm_nooverwrite boolean true d-i partman-basicmethods/method_only boolean false d-i partman-auto/choose_recipe select ardana-config d-i partman-auto/expert_recipe_file string /partition_scheme d-i partman-partitioning/confirm_write_new_label boolean true d-i partman/choose_partition select finish d-i partman-md/confirm boolean true d-i partman/confirm boolean true d-i partman/confirm_nooverwrite boolean true d-i partman-basicfilesystems/no_swap boolean false d-i partman-basicfilesystems partman-basicfilesystems/no_mount_point boolean false d-i partman-lvm/device_remove_lvm boolean true d-i partman-lvm/device_remove_lvm_span boolean true d-i partman-lvm/confirm boolean true d-i partman-lvm/confirm_nooverwrite boolean true d-i partman-efi/non_efi_system true # Do not set up additional apt repos for now d-i apt-setup/services-select multiselect d-i apt-setup/security_host string d-i base-installer/kernel/image string linux-server # Do not install any extra packages tasksel tasksel/first multiselect none # Other than these specific ones d-i pkgsel/include string dbus eject openssh-server rsync python python-apt hpssacli gdisk d-i passwd/root-login boolean false d-i passwd/make-user boolean true d-i passwd/user-fullname string {{ ardanauser }} d-i passwd/username string {{ ardanauser }} # Need to generate this on the fly d-i passwd/user-password-crypted password {{ ardanauser_password | password_hash('sha512') }} d-i passwd/user-uid string d-i user-setup/allow-password-weak boolean false d-i user-setup/encrypt-home boolean false d-i debian-installer/allow_unauthenticated string false # The ssh key populate may need more review - ok for now # The wget at the end is so that the net boot is turned off once installed # as per cobbler pxe_just_once settings d-i preseed/late_command string \ wget http://$http_server/preseed/timestamp;\ in-target touch /etc/cobbler_ardana_installed;\ cp ./timestamp /target/etc/cobbler_ardana_installed;\ in-target mkdir -p {{ ardanauser_home }}/.ssh;\ in-target chown {{ ardanauser }}:{{ ardanauser }} {{ ardanauser_home }}/.ssh;\ in-target chmod 700 {{ ardanauser_home }}/.ssh;\ echo "{{ deployer_ssh_pub_key }}" > /target/{{ ardanauser_home }}/.ssh/authorized_keys;\ in-target chown {{ ardanauser }}:{{ ardanauser }} {{ ardanauser_home }}/.ssh/authorized_keys;\ in-target sed -i "s,sudo[\t]ALL=(ALL:ALL) ALL,sudo ALL = (ALL) NOPASSWD: ALL,g" /etc/sudoers;\ {% if disable_pwd_auth == true %} in-target sed -i "s,#PasswordAuthentication yes,PasswordAuthentication no,g" /etc/ssh/sshd_config;\ {% endif %} umount /target/unused; \ lvremove -f /dev/ardana-vg/unused;\ in-target sed -i '/unused/d' /etc/fstab;\ wget http://$http_server/preseed/configure_network.sh; \ cp ./configure_network.sh /target/tmp;\ in-target bash /tmp/configure_network.sh ;\ in-target rm /tmp/configure_network.sh;\ wget http://$http_server/preseed/configure_kdump; \ cp ./configure_kdump /target/tmp;\ in-target bash /tmp/configure_kdump ;\ in-target rm /tmp/configure_kdump;\ sed -i "s,deb http,deb [arch=amd64] http,g" /target/etc/apt/sources.list;\ echo "deb [arch=i386] http://$http_server/ardana/cmc32 cattleprod main" >> /target/etc/apt/sources.list;\ in-target dpkg --add-architecture i386;\ in-target apt-get update;\ in-target rm /etc/resolv.conf;\ wget http://$http_server/preseed/bnx2x.conf;\ touch /target/etc/modprobe.d/bnx2x.conf;\ cp ./bnx2x.conf /target/etc/modprobe.d/bnx2x.conf;\ chmod 644 /target/etc/modprobe.d/bnx2x.conf;\ {% if (item[1].fcoe_interfaces) | length > 0 %} wget http://$http_server/preseed/update_fcoe_udev.py; \ /target/usr/bin/python ./update_fcoe_udev.py;\ in-target update-initramfs -k all -u ;\ {% endif %} wget http://$http_server/cblr/svc/op/nopxe/system/$name d-i pkgsel/update-policy select none {% if item[1].boot_from_san %} d-i grub-installer/bootdev string {{ boot_from_san_root_device }} {% else %} d-i grub-installer/bootdev string {{ cobbler_root_device }} {% endif %} d-i grub-installer/skip boolean false d-i lilo-installer/skip boolean false d-i grub-installer/only_debian boolean true d-i grub-installer/with_other_os boolean true d-i finish-install/keep-consoles boolean false d-i finish-install/reboot_in_progress note d-i cdrom-detect/eject boolean true #d-i debian-installer/exit/halt boolean true # Power off machine at the end d-i debian-installer/exit/poweroff boolean true 07070100000059000081A400000000000000000000000162FD641A0000031E000000000000000000000000000000000000005500000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/templates/isc-dhcp-server.j2{# # # (c) Copyright 2015 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # #} # Defaults for isc-dhcp-server initscript # sourced by /etc/init.d/isc-dhcp-server # installed at /etc/default/isc-dhcp-server by the maintainer scripts # # This is a POSIX shell fragment # # Path to dhcpd's config file (default: /etc/dhcp/dhcpd.conf). #DHCPD_CONF=/etc/dhcp/dhcpd.conf # Path to dhcpd's PID file (default: /var/run/dhcpd.pid). #DHCPD_PID=/var/run/dhcpd.pid # Additional options to start dhcpd with. # Don't use options -cf or -pf here; use DHCPD_CONF/ DHCPD_PID instead #OPTIONS="" # On what interfaces should the DHCP server (dhcpd) serve DHCP requests? # Separate multiple interfaces with spaces, e.g. "eth0 eth1". INTERFACES="{{ cobbler_server_interface }}" 0707010000005A000081A400000000000000000000000162FD641A00001B20000000000000000000000000000000000000005C00000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/templates/rhel72-anaconda-ks.cfg.j2# (c) Copyright 2016 Hewlett Packard Enterprise Development LP # (c) Copyright 2017 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # #version=DEVEL # System authorization information auth --enableshadow --passalgo=sha512 repo --name="Server-HighAvailability" --baseurl=file:///run/install/repo/addons/HighAvailability repo --name="Server-ResilientStorage" --baseurl=file:///run/install/repo/addons/ResilientStorage url --url=$tree # Run the Setup Agent on first boot firstboot --enable # Keyboard layouts keyboard --vckeymap=us --xlayouts='us' # System language lang en_US.utf8 # System timezone timezone Etc/UTC --isUtc --nontp # Misc firewall --disabled poweroff # Network information # Qlogic-FCOE: Uncomment the below lines if using qlogic fcoe boot from san # Modify the interface names (ens1f2, ens1f3) if appropriate # fcoe --nic=ens1f2 --autovlan # fcoe --nic=ens1f3 --autovlan # Root password user --groups=wheel --name="{{ ardanauser }}" --password="{{ ardanauser_password | password_hash('sha512') }}" --iscrypted --gecos="{{ ardanauser }}" # System bootloader configuration bootloader --location=mbr --boot-drive={{ cobbler_root_device }} zerombr # TODO: Target only cobbler_root_device not all disks. # ignoredisk --only-use={{ cobbler_root_device }} # Blow away without prejudice what was there previously - same as we do on hLinux clearpart --all --initlabel # Disk partitioning information #part biosboot --fstype="biosboot" --size=1 part /boot --fstype="ext3" --ondisk={{ cobbler_root_device }} --size=512 part /boot/efi --fstype="efi" --ondisk={{ cobbler_root_device }} --size=512 part pv.275 --fstype="lvmpv" --ondisk={{ cobbler_root_device }} --size=1 --grow volgroup ardana-vg --pesize=4096 pv.275 logvol / --fstype="ext4" --name=root --vgname=ardana-vg --size=32000 %packages @^minimal @core kexec-tools dbus eject openssh-server rsync python gdisk %end %pre --log=/var/log/anaconda-pre.log --erroronfail # Qlogic-FCOE: Uncomment the below lines if using qlogic fcoe boot from san # Modify the interface names (ens1f2, ens1f3) if appropriate # cat /proc/partitions # ip link set ens1f2 up # ip link set ens1f3 up # modprobe 8021q # modprobe fcoe # fipvlan -c -s ens1f2 # fipvlan -c -s ens1f3 # cat /proc/partitions # sleep 240 # cat /proc/partitions set -eux set -o pipefail date df -h cat /proc/partitions if which multipath ; then multipath -ll fi # record the "before" picture in the log file. vgs lvs pvs lsblk if vgs | grep -w ardana-vg ; then # This is an old volume group that we inherited from a previous # install of the node. Wipe the filesystems on it and then remove. # It's important to remove the filesystems because otherwise they # will be rediscovered by lvcreate in osconfig and it'll ask if you # want to keep them - and hang because you can't answer. DEBUG 3431. vgreduce --debug --yes -ff --removemissing ardana-vg luns="`ls -l /dev/ardana-vg/ | awk 'NR > 1 {print $NF}' | tr '\n' ' '`" for lun in $luns do wipefs -af /dev/ardana-vg/$lun # belt and braces as wipefs is unreliable. use +e in case the # device is so small that we overrun the end. set +e dd if=/dev/zero of=/dev/ardana-vg/$lun bs=1048576 count=1000 oflag=direct dsize=`blockdev --getsz /dev/ardana-vg/$lun` (( seek_value = dsize*512/1048576 - 1000 )) dd if=/dev/zero of=/dev/ardana-vg/$lun bs=1048576 count=1000 seek=$seek_value oflag=direct set -e done devs="`pvs | awk '$2 == \"ardana-vg\" { print $1 }' | tr '\n' ' '`" lvremove --debug --yes -ff ardana-vg vgremove --debug --yes -ff ardana-vg for d in $devs do pvremove --debug --yes -ff $d done # record the "after" picture in the log file. vgs lvs pvs lsblk fi date %end # Instead of this we use the ip addr script below # network --device=eth2 --bootproto=static --ip=192.168.10.8 --netmask=255.255.255.0 %post --log=/var/log/anaconda-post.log --erroronfail set -eux set -o pipefail # Allow ssh from deployer mkdir --mode=0700 {{ ardanauser_home }}/.ssh chown {{ ardanauser }}:{{ ardanauser }} {{ ardanauser_home }}/.ssh deployer_ssh_pub_key="{{ deployer_ssh_pub_key }}" echo "$deployer_ssh_pub_key" > {{ ardanauser_home }}/.ssh/authorized_keys chown {{ ardanauser }}:{{ ardanauser }} {{ ardanauser_home }}/.ssh/authorized_keys chmod 0600 {{ ardanauser_home }}/.ssh/authorized_keys systemctl disable NetworkManager # Configure sudo to not require tty sed -r -i "s,^(Defaults\s+requiretty),# \0," /etc/sudoers sed -r -i "s,^(Defaults\s+\!visiblepw),# \0," /etc/sudoers # In a nutshell we copy this from configure_network.sh.j2 but during RHEL kickstart # all devices are marked as UP but have only the one configured by cobbler has an ip. # So we have to do things slightly differently here. ip addr intf=`ip addr | awk '/scope global/ { print $NF }'` cidr=`ip addr | awk '/scope global/ { print $2 }'` ipaddr=`echo $cidr | awk -F/ '{ print $1 }'` ipprefix=`echo $cidr | awk -F/ '{ print $2 }'` gateway=`ip route | awk '/default/ { print $3 }'` cat <<EOF | tee /etc/sysconfig/network-scripts/ifcfg-$intf # Kickstart $intf initialization TYPE=Ethernet DEVICE=$intf BOOTPROTO=none IPADDR=$ipaddr PREFIX=$ipprefix ONBOOT=yes EOF # Enable passwordless sudo access for ardanauser echo "{{ ardanauser }} ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/{{ ardanauser }} chmod 0440 /etc/sudoers.d/{{ ardanauser }} {% if disable_pwd_auth == true %} sed -i "s/^PasswordAuthentication yes/PasswordAuthentication no/g" /etc/ssh/sshd_config {% endif %} if [ -e /etc/yum/pluginconf.d/subscription-manager.conf ] ; then sed -i "s/enabled=1/enabled=0/g" /etc/yum/pluginconf.d/subscription-manager.conf fi # remove external yum repo definitions, if any rm -f /etc/yum.repos.d/*.repo $yum_config_stanza # Anaconda will have configured the node to use the deployer as a gateway # which is wrong. A correct version will be written later, in osconfig. rm /etc/resolv.conf # Configure bnx2x driver module options curl http://$http_server/preseed/bnx2x.conf > /etc/modprobe.d/bnx2x.conf chmod 0644 /etc/modprobe.d/bnx2x.conf # Let Ardana know that we completed successfully. curl http://$http_server/preseed/timestamp > /etc/cobbler_ardana_installed # Let Cobbler know curl http://$http_server/cblr/svc/op/nopxe/system/$name > /dev/null %end %addon com_redhat_kdump --enable --reserve-mb='auto' %end 0707010000005B000081A400000000000000000000000162FD641A00001BBB000000000000000000000000000000000000005C00000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/templates/rhel73-anaconda-ks.cfg.j2# # (c) Copyright 2015-2017 Hewlett Packard Enterprise Development LP # (c) Copyright 2017-2018 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # #version=DEVEL # System authorization information auth --enableshadow --passalgo=sha512 repo --name="Server-HighAvailability" --baseurl=file:///run/install/repo/addons/HighAvailability repo --name="Server-ResilientStorage" --baseurl=file:///run/install/repo/addons/ResilientStorage url --url=$tree # Run the Setup Agent on first boot firstboot --enable # Keyboard layouts keyboard --vckeymap=us --xlayouts='us' # System language lang en_US.utf8 # System timezone timezone Etc/UTC --isUtc --nontp # Misc firewall --disabled poweroff # Network information # Qlogic-FCOE: Uncomment the below lines if using qlogic fcoe boot from san # Modify the interface names (ens1f2, ens1f3) if appropriate # fcoe --nic=ens1f2 --autovlan # fcoe --nic=ens1f3 --autovlan # Root password user --groups=wheel --name="{{ ardanauser }}" --password="{{ ardanauser_password | password_hash('sha512') }}" --homedir="{{ ardanauser_home }}" --iscrypted --gecos="{{ ardanauser }}" # System bootloader configuration bootloader --location=mbr --boot-drive={{ cobbler_root_device }} zerombr # TODO: Target only cobbler_root_device not all disks. # ignoredisk --only-use={{ cobbler_root_device }} # Blow away without prejudice what was there previously - same as we do on hLinux clearpart --all --initlabel # Disk partitioning information #part biosboot --fstype="biosboot" --size=1 part /boot --fstype="ext3" --ondisk={{ cobbler_root_device }} --size=512 part /boot/efi --fstype="efi" --ondisk={{ cobbler_root_device }} --size=512 part pv.275 --fstype="lvmpv" --ondisk={{ cobbler_root_device }} --size=1 --grow volgroup ardana-vg --pesize=4096 pv.275 logvol / --fstype="ext4" --name=root --vgname=ardana-vg --size=32000 %packages @^minimal @core kexec-tools dbus eject openssh-server rsync python gdisk wget %end %pre --log=/var/log/anaconda-pre.log --erroronfail # Qlogic-FCOE: Uncomment the below lines if using qlogic fcoe boot from san # Modify the interface names (ens1f2, ens1f3) if appropriate # cat /proc/partitions # ip link set ens1f2 up # ip link set ens1f3 up # modprobe 8021q # modprobe fcoe # fipvlan -c -s ens1f2 # fipvlan -c -s ens1f3 # cat /proc/partitions # sleep 240 # cat /proc/partitions set -eux set -o pipefail date df -h cat /proc/partitions if which multipath ; then multipath -ll fi # record the "before" picture in the log file. vgs lvs pvs lsblk if vgs | grep -w ardana-vg ; then # This is an old volume group that we inherited from a previous # install of the node. Wipe the filesystems on it and then remove. # It's important to remove the filesystems because otherwise they # will be rediscovered by lvcreate in osconfig and it'll ask if you # want to keep them - and hang because you can't answer. DEBUG 3431. vgreduce --debug --yes -ff --removemissing ardana-vg luns="`ls -l /dev/ardana-vg/ | awk 'NR > 1 {print $NF}' | tr '\n' ' '`" for lun in $luns do wipefs -af /dev/ardana-vg/$lun # belt and braces as wipefs is unreliable. use +e in case the # device is so small that we overrun the end. set +e dd if=/dev/zero of=/dev/ardana-vg/$lun bs=1048576 count=1000 oflag=direct dsize=`blockdev --getsz /dev/ardana-vg/$lun` (( seek_value = dsize*512/1048576 - 1000 )) dd if=/dev/zero of=/dev/ardana-vg/$lun bs=1048576 count=1000 seek=$seek_value oflag=direct set -e done devs="`pvs | awk '$2 == \"ardana-vg\" { print $1 }' | tr '\n' ' '`" lvremove --debug --yes -ff ardana-vg vgremove --debug --yes -ff ardana-vg for d in $devs do pvremove --debug --yes -ff $d done # record the "after" picture in the log file. vgs lvs pvs lsblk fi date %end # Instead of this we use the ip addr script below # network --device=eth2 --bootproto=static --ip=192.168.10.8 --netmask=255.255.255.0 %post --log=/var/log/anaconda-post.log --erroronfail set -eux set -o pipefail # Allow ssh from deployer mkdir --mode=0700 {{ ardanauser_home }}/.ssh chown {{ ardanauser }}:{{ ardanauser }} {{ ardanauser_home }}/.ssh deployer_ssh_pub_key="{{ deployer_ssh_pub_key }}" echo "$deployer_ssh_pub_key" > {{ ardanauser_home }}/.ssh/authorized_keys chown {{ ardanauser }}:{{ ardanauser }} {{ ardanauser_home }}/.ssh/authorized_keys chmod 0600 {{ ardanauser_home }}/.ssh/authorized_keys systemctl disable NetworkManager # Configure sudo to not require tty sed -r -i "s,^(Defaults\s+requiretty),# \0," /etc/sudoers sed -r -i "s,^(Defaults\s+\!visiblepw),# \0," /etc/sudoers # In a nutshell we copy this from configure_network.sh.j2 but during RHEL kickstart # all devices are marked as UP but have only the one configured by cobbler has an ip. # So we have to do things slightly differently here. ip addr intf=`ip addr | grep -v inet6 | awk '/scope global/ { print $NF }'` cidr=`ip addr | grep -v inet6 | awk '/scope global/ { print $2 }'` intf=`echo ${intf} | cut -d' ' -f1` cidr=`echo ${cidr} | cut -d' ' -f1` ipaddr=`echo $cidr | awk -F/ '{ print $1 }'` ipprefix=`echo $cidr | awk -F/ '{ print $2 }'` gateway=`ip route | awk '/default/ { print $3 }'` cat <<EOF | tee /etc/sysconfig/network-scripts/ifcfg-$intf # Kickstart $intf initialization TYPE=Ethernet DEVICE=$intf BOOTPROTO=none IPADDR=$ipaddr PREFIX=$ipprefix ONBOOT=yes EOF # Enable passwordless sudo access for ardanauser echo "{{ ardanauser }} ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/{{ ardanauser }} chmod 0440 /etc/sudoers.d/{{ ardanauser }} {% if disable_pwd_auth == true %} sed -i "s/^PasswordAuthentication yes/PasswordAuthentication no/g" /etc/ssh/sshd_config {% endif %} if [ -e /etc/yum/pluginconf.d/subscription-manager.conf ] ; then sed -i "s/enabled=1/enabled=0/g" /etc/yum/pluginconf.d/subscription-manager.conf fi # remove external yum repo definitions, if any rm -f /etc/yum.repos.d/*.repo $yum_config_stanza # Anaconda will have configured the node to use the deployer as a gateway # which is wrong. A correct version will be written later, in osconfig. rm /etc/resolv.conf # Configure bnx2x driver module options curl http://$http_server/preseed/bnx2x.conf > /etc/modprobe.d/bnx2x.conf chmod 0644 /etc/modprobe.d/bnx2x.conf # Let Ardana know that we completed successfully. curl http://$http_server/preseed/timestamp > /etc/cobbler_ardana_installed # Let Cobbler know curl http://$http_server/cblr/svc/op/nopxe/system/$name > /dev/null %end %addon com_redhat_kdump --enable --reserve-mb='auto' %end 0707010000005C000081A400000000000000000000000162FD641A00001BBB000000000000000000000000000000000000005C00000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/templates/rhel75-anaconda-ks.cfg.j2# # (c) Copyright 2015-2017 Hewlett Packard Enterprise Development LP # (c) Copyright 2017-2018 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # #version=DEVEL # System authorization information auth --enableshadow --passalgo=sha512 repo --name="Server-HighAvailability" --baseurl=file:///run/install/repo/addons/HighAvailability repo --name="Server-ResilientStorage" --baseurl=file:///run/install/repo/addons/ResilientStorage url --url=$tree # Run the Setup Agent on first boot firstboot --enable # Keyboard layouts keyboard --vckeymap=us --xlayouts='us' # System language lang en_US.utf8 # System timezone timezone Etc/UTC --isUtc --nontp # Misc firewall --disabled poweroff # Network information # Qlogic-FCOE: Uncomment the below lines if using qlogic fcoe boot from san # Modify the interface names (ens1f2, ens1f3) if appropriate # fcoe --nic=ens1f2 --autovlan # fcoe --nic=ens1f3 --autovlan # Root password user --groups=wheel --name="{{ ardanauser }}" --password="{{ ardanauser_password | password_hash('sha512') }}" --homedir="{{ ardanauser_home }}" --iscrypted --gecos="{{ ardanauser }}" # System bootloader configuration bootloader --location=mbr --boot-drive={{ cobbler_root_device }} zerombr # TODO: Target only cobbler_root_device not all disks. # ignoredisk --only-use={{ cobbler_root_device }} # Blow away without prejudice what was there previously - same as we do on hLinux clearpart --all --initlabel # Disk partitioning information #part biosboot --fstype="biosboot" --size=1 part /boot --fstype="ext3" --ondisk={{ cobbler_root_device }} --size=512 part /boot/efi --fstype="efi" --ondisk={{ cobbler_root_device }} --size=512 part pv.275 --fstype="lvmpv" --ondisk={{ cobbler_root_device }} --size=1 --grow volgroup ardana-vg --pesize=4096 pv.275 logvol / --fstype="ext4" --name=root --vgname=ardana-vg --size=32000 %packages @^minimal @core kexec-tools dbus eject openssh-server rsync python gdisk wget %end %pre --log=/var/log/anaconda-pre.log --erroronfail # Qlogic-FCOE: Uncomment the below lines if using qlogic fcoe boot from san # Modify the interface names (ens1f2, ens1f3) if appropriate # cat /proc/partitions # ip link set ens1f2 up # ip link set ens1f3 up # modprobe 8021q # modprobe fcoe # fipvlan -c -s ens1f2 # fipvlan -c -s ens1f3 # cat /proc/partitions # sleep 240 # cat /proc/partitions set -eux set -o pipefail date df -h cat /proc/partitions if which multipath ; then multipath -ll fi # record the "before" picture in the log file. vgs lvs pvs lsblk if vgs | grep -w ardana-vg ; then # This is an old volume group that we inherited from a previous # install of the node. Wipe the filesystems on it and then remove. # It's important to remove the filesystems because otherwise they # will be rediscovered by lvcreate in osconfig and it'll ask if you # want to keep them - and hang because you can't answer. DEBUG 3431. vgreduce --debug --yes -ff --removemissing ardana-vg luns="`ls -l /dev/ardana-vg/ | awk 'NR > 1 {print $NF}' | tr '\n' ' '`" for lun in $luns do wipefs -af /dev/ardana-vg/$lun # belt and braces as wipefs is unreliable. use +e in case the # device is so small that we overrun the end. set +e dd if=/dev/zero of=/dev/ardana-vg/$lun bs=1048576 count=1000 oflag=direct dsize=`blockdev --getsz /dev/ardana-vg/$lun` (( seek_value = dsize*512/1048576 - 1000 )) dd if=/dev/zero of=/dev/ardana-vg/$lun bs=1048576 count=1000 seek=$seek_value oflag=direct set -e done devs="`pvs | awk '$2 == \"ardana-vg\" { print $1 }' | tr '\n' ' '`" lvremove --debug --yes -ff ardana-vg vgremove --debug --yes -ff ardana-vg for d in $devs do pvremove --debug --yes -ff $d done # record the "after" picture in the log file. vgs lvs pvs lsblk fi date %end # Instead of this we use the ip addr script below # network --device=eth2 --bootproto=static --ip=192.168.10.8 --netmask=255.255.255.0 %post --log=/var/log/anaconda-post.log --erroronfail set -eux set -o pipefail # Allow ssh from deployer mkdir --mode=0700 {{ ardanauser_home }}/.ssh chown {{ ardanauser }}:{{ ardanauser }} {{ ardanauser_home }}/.ssh deployer_ssh_pub_key="{{ deployer_ssh_pub_key }}" echo "$deployer_ssh_pub_key" > {{ ardanauser_home }}/.ssh/authorized_keys chown {{ ardanauser }}:{{ ardanauser }} {{ ardanauser_home }}/.ssh/authorized_keys chmod 0600 {{ ardanauser_home }}/.ssh/authorized_keys systemctl disable NetworkManager # Configure sudo to not require tty sed -r -i "s,^(Defaults\s+requiretty),# \0," /etc/sudoers sed -r -i "s,^(Defaults\s+\!visiblepw),# \0," /etc/sudoers # In a nutshell we copy this from configure_network.sh.j2 but during RHEL kickstart # all devices are marked as UP but have only the one configured by cobbler has an ip. # So we have to do things slightly differently here. ip addr intf=`ip addr | grep -v inet6 | awk '/scope global/ { print $NF }'` cidr=`ip addr | grep -v inet6 | awk '/scope global/ { print $2 }'` intf=`echo ${intf} | cut -d' ' -f1` cidr=`echo ${cidr} | cut -d' ' -f1` ipaddr=`echo $cidr | awk -F/ '{ print $1 }'` ipprefix=`echo $cidr | awk -F/ '{ print $2 }'` gateway=`ip route | awk '/default/ { print $3 }'` cat <<EOF | tee /etc/sysconfig/network-scripts/ifcfg-$intf # Kickstart $intf initialization TYPE=Ethernet DEVICE=$intf BOOTPROTO=none IPADDR=$ipaddr PREFIX=$ipprefix ONBOOT=yes EOF # Enable passwordless sudo access for ardanauser echo "{{ ardanauser }} ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/{{ ardanauser }} chmod 0440 /etc/sudoers.d/{{ ardanauser }} {% if disable_pwd_auth == true %} sed -i "s/^PasswordAuthentication yes/PasswordAuthentication no/g" /etc/ssh/sshd_config {% endif %} if [ -e /etc/yum/pluginconf.d/subscription-manager.conf ] ; then sed -i "s/enabled=1/enabled=0/g" /etc/yum/pluginconf.d/subscription-manager.conf fi # remove external yum repo definitions, if any rm -f /etc/yum.repos.d/*.repo $yum_config_stanza # Anaconda will have configured the node to use the deployer as a gateway # which is wrong. A correct version will be written later, in osconfig. rm /etc/resolv.conf # Configure bnx2x driver module options curl http://$http_server/preseed/bnx2x.conf > /etc/modprobe.d/bnx2x.conf chmod 0644 /etc/modprobe.d/bnx2x.conf # Let Ardana know that we completed successfully. curl http://$http_server/preseed/timestamp > /etc/cobbler_ardana_installed # Let Cobbler know curl http://$http_server/cblr/svc/op/nopxe/system/$name > /dev/null %end %addon com_redhat_kdump --enable --reserve-mb='auto' %end 0707010000005D000081A400000000000000000000000162FD641A00004D49000000000000000000000000000000000000004E00000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/templates/settings.j2{# # # (c) Copyright 2015-2017 Hewlett Packard Enterprise Development LP # (c) Copyright 2017-2018 SUSE LLC # #} # --- # cobbler settings file # restart cobblerd and run "cobbler sync" after making changes # This config file is in YAML 1.0 format # see http://yaml.org # ========================================================== # if 1, cobbler will allow insertions of system records that duplicate # the --dns-name information of other system records. In general, # this is undesirable and should be left 0. allow_duplicate_hostnames: 0 # if 1, cobbler will allow insertions of system records that duplicate # the ip address information of other system records. In general, # this is undesirable and should be left 0. allow_duplicate_ips: 0 # if 1, cobbler will allow insertions of system records that duplicate # the mac address information of other system records. In general, # this is undesirable. allow_duplicate_macs: 0 # if 1, cobbler will allow settings to be changed dynamically without # a restart of the cobblerd daemon. You can only change this variable # by manually editing the settings file, and you MUST restart cobblerd # after changing it. allow_dynamic_settings: 0 # by default, installs are *not* set to send installation logs to the cobbler # # # server. With 'anamon_enabled', kickstart templates may use the pre_anamon # # # snippet to allow remote live monitoring of their installations from the # # # cobbler server. Installation logs will be stored under # # # /var/log/cobbler/anamon/. NOTE: This does allow an xmlrpc call to send logs # # # to this directory, without authentication, so enable only if you are # # # ok with this limitation. anamon_enabled: 0 # If using authn_pam in the modules.conf, this can be configured # to change the PAM service authentication will be tested against. # The default value is "login". authn_pam_service: "login" # How long the authentication token is valid for, in seconds auth_token_expiration: 3600 # Email out a report when cobbler finishes installing a system. # enabled: set to 1 to turn this feature on # sender: optional # email: which addresses to email # smtp_server: used to specify another server for an MTA # subject: use the default subject unless overridden build_reporting_enabled: 0 build_reporting_sender: "" build_reporting_email: [ 'root@localhost' ] build_reporting_smtp_server: "localhost" build_reporting_subject: "" build_reporting_ignorelist: [ "" ] # Cheetah-language kickstart templates can import Python modules. # while this is a useful feature, it is not safe to allow them to # import anything they want. This whitelists which modules can be # imported through Cheetah. Users can expand this as needed but # should never allow modules such as subprocess or those that # allow access to the filesystem as Cheetah templates are evaluated # by cobblerd as code. cheetah_import_whitelist: - "random" - "re" - "time" # Default createrepo_flags to use for new repositories. If you have # createrepo >= 0.4.10, consider "-c cache --update -C", which can # dramatically improve your "cobbler reposync" time. "-s sha" # enables working with Fedora repos from F11/F12 from EL-4 or # EL-5 without python-hashlib installed (which is not available # on EL-4) createrepo_flags: "-c cache -s sha" # if no kickstart is specified to profile add, use this template default_kickstart: /var/lib/cobbler/kickstarts/default.ks # configure all installed systems to use these nameservers by default # unless defined differently in the profile. For DHCP configurations # you probably do /not/ want to supply this. default_name_servers: [] # if using the authz_ownership module (see the Wiki), objects # created without specifying an owner are assigned to this # owner and/or group. Can be a comma seperated list. default_ownership: - "admin" # cobbler has various sample kickstart templates stored # in /var/lib/cobbler/kickstarts/. This controls # what install (root) password is set up for those # systems that reference this variable. The factory # default is "cobbler" and cobbler check will warn if # this is not changed. # The simplest way to change the password is to run # openssl passwd -1 # and put the output between the "" below. default_password_crypted: "{{ cobbler_default_passwd }}" # the default template type to use in the absence of any # other detected template. If you do not specify the template # with '#template=<template_type>' on the first line of your # templates/snippets, cobbler will assume try to use the # following template engine to parse the templates. # # Current valid values are: cheetah, jinja2 default_template_type: "cheetah" # for libvirt based installs in koan, if no virt bridge # is specified, which bridge do we try? For EL 4/5 hosts # this should be xenbr0, for all versions of Fedora, try # "virbr0". This can be overriden on a per-profile # basis or at the koan command line though this saves # typing to just set it here to the most common option. default_virt_bridge: xenbr0 # use this as the default disk size for virt guests (GB) default_virt_file_size: 5 # use this as the default memory size for virt guests (MB) default_virt_ram: 512 # if koan is invoked without --virt-type and no virt-type # is set on the profile/system, what virtualization type # should be assumed? Values: xenpv, xenfv, qemu, vmware # (NOTE: this does not change what virt_type is chosen by import) default_virt_type: xenpv # enable gPXE booting? Enabling this option will cause cobbler # to copy the undionly.kpxe file to the tftp root directory, # and if a profile/system is configured to boot via gpxe it will # chain load off pxelinux.0. # Default: 0 enable_gpxe: 0 # controls whether cobbler will add each new profile entry to the default # PXE boot menu. This can be over-ridden on a per-profile # basis when adding/editing profiles with --enable-menu=0/1. Users # should ordinarily leave this setting enabled unless they are concerned # with accidental reinstalls from users who select an entry at the PXE # boot menu. Adding a password to the boot menus templates # may also be a good solution to prevent unwanted reinstallations enable_menu: 1 # enable Func-integration? This makes sure each installed machine is set up # to use func out of the box, which is a powerful way to script and control # remote machines. # Func lives at http://fedorahosted.org/func # read more at https://github.com/cobbler/cobbler/wiki/Func-integration # you will need to mirror Fedora/EPEL packages for this feature, so see # https://github.com/cobbler/cobbler/wiki/Manage-yum-repos if you want cobbler # to help you with this func_auto_setup: 0 func_master: overlord.example.org # change this port if Apache is not running plaintext on port # 80. Most people can leave this alone. http_port: {{ deployer_server_port }} # kernel options that should be present in every cobbler installation. # kernel options can also be applied at the distro/profile/system # level. kernel_options: ksdevice: bootif lang: 'en_US' text: ~ # s390 systems require additional kernel options in addition to the # above defaults kernel_options_s390x: RUNKS: 1 ramdisk_size: 40000 root: /dev/ram0 ro: ~ ip: off vnc: ~ # configuration options if using the authn_ldap module. See the # the Wiki for details. This can be ignored if you are not using # LDAP for WebUI/XMLRPC authentication. ldap_server: "ldap.example.com" ldap_base_dn: "DC=example,DC=com" ldap_port: 389 ldap_tls: 1 ldap_anonymous_bind: 1 ldap_search_bind_dn: '' ldap_search_passwd: '' ldap_search_prefix: 'uid=' ldap_tls_cacertfile: '' ldap_tls_keyfile: '' ldap_tls_certfile: '' # cobbler has a feature that allows for integration with config management # systems such as Puppet. The following parameters work in conjunction with # --mgmt-classes and are described in furhter detail at: # https://github.com/cobbler/cobbler/wiki/Using-cobbler-with-a-configuration-management-system mgmt_classes: [] mgmt_parameters: from_cobbler: 1 # if enabled, this setting ensures that puppet is installed during # machine provision, a client certificate is generated and a # certificate signing request is made with the puppet master server puppet_auto_setup: 0 # when puppet starts on a system after installation it needs to have # its certificate signed by the puppet master server. Enabling the # following feature will ensure that the puppet server signs the # certificate after installation if the puppet master server is # running on the same machine as cobbler. This requires # puppet_auto_setup above to be enabled sign_puppet_certs_automatically: 0 # location of the puppet executable, used for revoking certificates puppetca_path: "/usr/bin/puppet" # when a puppet managed machine is reinstalled it is necessary to # remove the puppet certificate from the puppet master server before a # new certificate is signed (see above). Enabling the following # feature will ensure that the certificate for the machine to be # installed is removed from the puppet master server if the puppet # master server is running on the same machine as cobbler. This # requires puppet_auto_setup above to be enabled remove_old_puppet_certs_automatically: 0 # choose a --server argument when running puppetd/puppet agent during kickstart #puppet_server: 'puppet' # let cobbler know that you're using a newer version of puppet # choose version 3 to use: 'puppet agent'; version 2 uses status quo: 'puppetd' #puppet_version: 2 # choose whether to enable puppet parameterized classes or not. # puppet versions prior to 2.6.5 do not support parameters #puppet_parameterized_classes: 1 # set to 1 to enable Cobbler's DHCP management features. # the choice of DHCP management engine is in /etc/cobbler/modules.conf manage_dhcp: 1 # set to 1 to enable Cobbler's DNS management features. # the choice of DNS mangement engine is in /etc/cobbler/modules.conf manage_dns: 0 # set to path of bind chroot to create bind-chroot compatible bind # configuration files. This should be automatically detected. bind_chroot_path: "" # set to the ip address of the master bind DNS server for creating secondary # bind configuration files bind_master: 127.0.0.1 # set to 1 to enable Cobbler's TFTP management features. # the choice of TFTP mangement engine is in /etc/cobbler/modules.conf manage_tftpd: 1 # set to 1 to enable Cobbler's RSYNC management features. manage_rsync: 0 # if using BIND (named) for DNS management in /etc/cobbler/modules.conf # and manage_dns is enabled (above), this lists which zones are managed # See the Wiki (https://github.com/cobbler/cobbler/wiki/Dns-management) for more info manage_forward_zones: [] manage_reverse_zones: [] # if using cobbler with manage_dhcp, put the IP address # of the cobbler server here so that PXE booting guests can find it # if you do not set this correctly, this will be manifested in TFTP open timeouts. next_server: {{ cobbler_server_ip_addr }} # settings for power management features. optional. # see https://github.com/cobbler/cobbler/wiki/Power-management to learn more # choices (refer to codes.py): # apc_snmp bladecenter bullpap drac ether_wake ilo integrity # ipmilan ipmitool lpar rsa virsh wti power_management_default_type: 'ipmitool' # the commands used by the power management module are sourced # from what directory? power_template_dir: "/etc/cobbler/power" # if this setting is set to 1, cobbler systems that pxe boot # will request at the end of their installation to toggle the # --netboot-enabled record in the cobbler system record. This eliminates # the potential for a PXE boot loop if the system is set to PXE # first in it's BIOS order. Enable this if PXE is first in your BIOS # boot order, otherwise leave this disabled. See the manpage # for --netboot-enabled. pxe_just_once: 1 # the templates used for PXE config generation are sourced # from what directory? pxe_template_dir: "/etc/cobbler/pxe" # Path to where system consoles are consoles: "/var/consoles" # Are you using a Red Hat management platform in addition to Cobbler? # Cobbler can help you register to it. Choose one of the following: # "off" : I'm not using Red Hat Network, Satellite, or Spacewalk # "hosted" : I'm using Red Hat Network # "site" : I'm using Red Hat Satellite Server or Spacewalk # You will also want to read: https://github.com/cobbler/cobbler/wiki/Tips-for-RHN redhat_management_type: "off" # if redhat_management_type is enabled, choose your server # "management.example.org" : For Satellite or Spacewalk # "xmlrpc.rhn.redhat.com" : For Red Hat Network # This setting is also used by the code that supports using Spacewalk/Satellite users/passwords # within Cobbler Web and Cobbler XMLRPC. Using RHN Hosted for this is not supported. # This feature can be used even if redhat_management_type is off, you just have # to have authn_spacewalk selected in modules.conf redhat_management_server: "xmlrpc.rhn.redhat.com" # specify the default Red Hat authorization key to use to register # system. If left blank, no registration will be attempted. Similarly # you can set the --redhat-management-key to blank on any system to # keep it from trying to register. redhat_management_key: "" # if using authn_spacewalk in modules.conf to let cobbler authenticate # against Satellite/Spacewalk's auth system, by default it will not allow per user # access into Cobbler Web and Cobbler XMLRPC. # in order to permit this, the following setting must be enabled HOWEVER # doing so will permit all Spacewalk/Satellite users of certain types to edit all # of cobbler's configuration. # these roles are: config_admin and org_admin # users should turn this on only if they want this behavior and # do not have a cross-multi-org seperation concern. If you have # a single org in your satellite, it's probably safe to turn this # on and then you can use CobblerWeb alongside a Satellite install. redhat_management_permissive: 0 # if set to 1, allows /usr/bin/cobbler-register (part of the koan package) # to be used to remotely add new cobbler system records to cobbler. # this effectively allows for registration of new hardware from system # records. register_new_installs: 0 # Flags to use for yum's reposync. If your version of yum reposync # does not support -l, you may need to remove that option. reposync_flags: "-l -n -d" # when DHCP and DNS management are enabled, cobbler sync can automatically # restart those services to apply changes. The exception for this is # if using ISC for DHCP, then omapi eliminates the need for a restart. # omapi, however, is experimental and not recommended for most configurations. # If DHCP and DNS are going to be managed, but hosted on a box that # is not on this server, disable restarts here and write some other # script to ensure that the config files get copied/rsynced to the destination # box. This can be done by modifying the restart services trigger. # Note that if manage_dhcp and manage_dns are disabled, the respective # parameter will have no effect. Most users should not need to change # this. restart_dns: 1 restart_dhcp: 1 # install triggers are scripts in /var/lib/cobbler/triggers/install # that are triggered in kickstart pre and post sections. Any # executable script in those directories is run. They can be used # to send email or perform other actions. They are currently # run as root so if you do not need this functionality you can # disable it, though this will also disable "cobbler status" which # uses a logging trigger to audit install progress. run_install_triggers: 1 # enables a trigger which version controls all changes to /var/lib/cobbler # when add, edit, or sync events are performed. This can be used # to revert to previous database versions, generate RSS feeds, or for # other auditing or backup purposes. "git" and "hg" are currently suported, # but git is the recommend SCM for use with this feature. scm_track_enabled: 0 scm_track_mode: "git" # this is the address of the cobbler server -- as it is used # by systems during the install process, it must be the address # or hostname of the system as those systems can see the server. # if you have a server that appears differently to different subnets # (dual homed, etc), you need to read the --server-override section # of the manpage for how that works. server: {{ cobbler_server_ip_addr }} # If set to 1, all commands will be forced to use the localhost address # instead of using the above value which can force commands like # cobbler sync to open a connection to a remote address if one is in the # configuration and would traceback. client_use_localhost: 0 # If set to 1, all commands to the API (not directly to the XMLRPC # server) will go over HTTPS instead of plaintext. Be sure to change # the http_port setting to the correct value for the web server client_use_https: 0 # this is a directory of files that cobbler uses to make # templating easier. See the Wiki for more information. Changing # this directory should not be required. snippetsdir: /var/lib/cobbler/snippets # Normally if a kickstart is specified at a remote location, this # URL will be passed directly to the kickstarting system, thus bypassing # the usual snippet templating Cobbler does for local kickstart files. If # this option is enabled, Cobbler will fetch the file contents internally # and serve a templated version of the file to the client. template_remote_kickstarts: 0 # should new profiles for virtual machines default to auto booting with the physical host when the physical host reboots? # this can be overridden on each profile or system object. virt_auto_boot: 1 # cobbler's web directory. Don't change this setting -- see the # Wiki on "relocating your cobbler install" if your /var partition # is not large enough. webdir: /srv/www/cobbler # cobbler's public XMLRPC listens on this port. Change this only # if absolutely needed, as you'll have to start supplying a new # port option to koan if it is not the default. xmlrpc_port: 25151 # "cobbler repo add" commands set cobbler up with repository # information that can be used during kickstart and is automatically # set up in the cobbler kickstart templates. By default, these # are only available at install time. To make these repositories # usable on installed systems (since cobbler makes a very convient) # mirror, set this to 1. Most users can safely set this to 1. Users # who have a dual homed cobbler server, or are installing laptops that # will not always have access to the cobbler server may wish to leave # this as 0. In that case, the cobbler mirrored yum repos are still # accessable at http://cobbler.example.org/cblr/repo_mirror and yum # configuration can still be done manually. This is just a shortcut. yum_post_install_mirror: 1 # the default yum priority for all the distros. This is only used # if yum-priorities plugin is used. 1=maximum. Tweak with caution. yum_distro_priority: 1 # Flags to use for yumdownloader. Not all versions may support # --resolve. yumdownloader_flags: "--resolve" # sort and indent JSON output to make it more human-readable serializer_pretty_json: 0 # replication rsync options for distros, kickstarts, snippets set to override default value of "-avzH" replicate_rsync_options: "-avzH" # replication rsync options for repos set to override default value of "-avzH" replicate_repo_rsync_options: "-avzH" # always write DHCP entries, regardless if netboot is enabled always_write_dhcp_entries: 0 # external proxy - used by: get-loaders, reposync, signature update # eg: proxy_url_ext: "http://192.168.1.1:8080" # internal proxy - used by systems to reach cobbler for kickstarts # eg: proxy_url_int: "http://10.0.0.1:8080" proxy_url_int: 0707010000005E000081A400000000000000000000000162FD641A000001A1000000000000000000000000000000000000005000000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/templates/sles.grub2.j2{# # # (c) Copyright 2017,2018 SUSE LLC # #} set timeout=5 menuentry 'SLES 12 SP3 Cobbler install' { linuxefi images/{{ sles_profile_name }}-x86_64/linux ifcfg={{ item.stdout }}=dhcp install=http://{{ cobbler_server_ip_addr }}:79/cblr/ks_mirror/{{ sles_profile_name }} AutoYaST2=http://{{ cobbler_server_ip_addr }}:79/cblr/svc/op/ks/system/{{ item.item }} initrdefi images/{{ sles_profile_name }}-x86_64/initrd } 0707010000005F000081A400000000000000000000000162FD641A00001CDF000000000000000000000000000000000000005C00000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/templates/sles12sp3-autoyast.xml.j2{# # (c) Copyright 2017 Hewlett Packard Enterprise Development LP # (c) Copyright 2017-2018 SUSE LLC #} <?xml version="1.0"?> <!DOCTYPE profile> <profile xmlns="http://www.suse.com/1.0/yast2ns" xmlns:config="http://www.suse.com/1.0/configns"> <deploy_image> <image_installation config:type="boolean">false</image_installation> </deploy_image> <language> <language>en_US</language> <languages>en_GB,de_DE</languages> </language> <general> <mode> <confirm config:type="boolean">false</confirm> <final_halt config:type="boolean">false</final_halt> <final_reboot config:type="boolean">false</final_reboot> <halt config:type="boolean">true</halt> <second_stage config:type="boolean">false</second_stage> </mode> <signature-handling> <accept_file_without_checksum config:type="boolean">false</accept_file_without_checksum> <accept_non_trusted_gpg_key config:type="boolean">false</accept_non_trusted_gpg_key> <accept_unknown_gpg_key config:type="boolean">false</accept_unknown_gpg_key> <accept_unsigned_file config:type="boolean">false</accept_unsigned_file> <accept_verification_failed config:type="boolean">false</accept_verification_failed> <import_gpg_key config:type="boolean">false</import_gpg_key> </signature-handling> <storage/> </general> {% if sles_configured_media_repos | length > 0 %} <add-on> <add_on_products config:type="list"> {% for m_repo in sles_configured_media_repos %} <listentry> <name>{{ m_repo.name }}</name> <product>{{ m_repo.name }}</product> <media_url>{{ deployer_server }}/SUSE-12-3/{{ ansible_architecture }}/repos/{{ m_repo.alias }}</media_url> <priority>{{ m_repo.priority | default('99', true) | int }}</priority> <ask_on_error config:type="boolean">{{ m_repo.ask_on_error | default('False', true) | bool }}</ask_on_error> <alias>{{ m_repo.alias }}</alias> </listentry> {% endfor %} </add_on_products> </add-on> {% endif %} <software> <install_recommended config:type="boolean">true</install_recommended> <packages config:type="list"> <package>cron</package> <package>dracut</package> <package>gcc</package> <package>gptfdisk</package> <package>iputils</package> <package>kdump</package> <package>kernel-firmware</package> <package>kexec-tools</package> <package>man</package> <package>openssh</package> <package>python</package> <package>python-xml</package> <package>rsync</package> <package>rsyslog</package> <package>sudo</package> <package>util-linux</package> </packages> </software> <kdump> <add_crash_kernel config:type="boolean">true</add_crash_kernel> <crash_kernel config:type="list"> <listentry>128M,low</listentry> <listentry>768M,high</listentry> </crash_kernel> </kdump> <networking> <interfaces config:type="list"> <interface> <bootproto>dhcp</bootproto> <device>eth0</device> <dhclient_set_default_route>no</dhclient_set_default_route> <dhclient_set_hostname>no</dhclient_set_hostname> <startmode>auto</startmode> </interface> </interfaces> <ipv6 config:type="boolean">true</ipv6> <keep_install_network config:type="boolean">true</keep_install_network> <managed config:type="boolean">false</managed> <routing> <ipv4_forward config:type="boolean">false</ipv4_forward> <ipv6_forward config:type="boolean">false</ipv6_forward> </routing> </networking> <partitioning config:type="list"> <drive> <device>{{ cobbler_root_device }}</device> <disklabel>gpt</disklabel> <initialize config:type="boolean">true</initialize> <partitions config:type="list"> <partition> <create config:type="boolean">true</create> <format config:type="boolean">true</format> <filesystem config:type="symbol">ext4</filesystem> <mount>/boot</mount> <size>250M</size> </partition> <partition> <create config:type="boolean">true</create> <format config:type="boolean">true</format> <filesystem config:type="symbol">vfat</filesystem> <mount>/boot/efi</mount> <size>250M</size> </partition> <partition> <lvm_group>ardana-vg</lvm_group> </partition> </partitions> <type config:type="symbol">CT_DISK</type> <use>all</use> </drive> <drive> <device>/dev/ardana-vg</device> <partitions config:type="list"> <partition> <create config:type="boolean">true</create> <format config:type="boolean">true</format> <filesystem config:type="symbol">ext4</filesystem> <lv_name>root</lv_name> <mount>/</mount> <size>30G</size> </partition> </partitions> <type config:type="symbol">CT_LVM</type> <use>all</use> </drive> </partitioning> <scripts> <init-scripts config:type="list"> <script> <filename>autoyast-init-scripts-0.sh</filename> <source><![CDATA[ systemctl enable sshd kdump rsyslog systemctl start sshd ]]></source> </script> <script> <filename>autoyast-init-scripts-1.sh</filename> <source><![CDATA[ # check network IP=`echo "$http_server" | sed 's/:.*//'` COUNTER=60 until ping -c1 "$IP" 2>&1 >/dev/null || [ $COUNTER -lt 1 ]; do sleep 1; let COUNTER-=1; done # set flag wget http://$http_server/preseed/timestamp -O /etc/cobbler_ardana_installed # ardanauser access mkdir -p {{ ardanauser_home }}/.ssh echo "{{ deployer_ssh_pub_key }}" > {{ ardanauser_home }}/.ssh/authorized_keys chown -R {{ ardanauser }}:{{ ardanauser }} {{ ardanauser_home }}/.ssh chmod 0700 {{ ardanauser_home }}/.ssh chmod 0600 {{ ardanauser_home }}/.ssh/authorized_keys # sudo dest=/etc/sudoers sed -i "s,sudo[\t]ALL=(ALL:ALL) ALL,sudo ALL = (ALL) NOPASSWD: ALL,g" $dest line="%sudo ALL = (ALL) NOPASSWD: ALL" r=`grep "$line" $dest` if [ -z "$r" ]; then echo >> $dest echo "# Allow members of group sudo to execute any command" >> $dest echo $line >> $dest fi {% if disable_pwd_auth == true %} # SSH sed -i "s,#PasswordAuthentication yes,PasswordAuthentication no,g" /etc/ssh/sshd_config {% endif %} rm /etc/resolv.conf wget http://$http_server/preseed/bnx2x.conf -O /etc/modprobe.d/bnx2x.conf chmod 644 /etc/modprobe.d/bnx2x.conf wget http://$http_server/preseed/configure_network.sh -O /tmp/configure_network.sh bash /tmp/configure_network.sh rm /tmp/configure_network.sh ]]></source> </script> </init-scripts> </scripts> <groups config:type="list"> <group> <groupname>sudo</groupname> <gid>1000</gid> <userlist>{{ ardanauser }}</userlist> </group> <group> <groupname>{{ ardanauser }}</groupname> <gid>1001</gid> <userlist>{{ ardanauser }}</userlist> </group> </groups> <users config:type="list"> <user> <username>{{ ardanauser }}</username> <gid>1001</gid> <user_password>{{ ardanauser_password | password_hash('sha512') }}</user_password><encrypted config:type="boolean">true</encrypted> <home>{{ ardanauser_home }}</home> </user> </users> </profile> 07070100000060000081A400000000000000000000000162FD641A00000332000000000000000000000000000000000000004E00000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/templates/srv.conf.j2{# # # (c) Copyright 2017 Hewlett Packard Enterprise Development LP # (c) Copyright 2017-2018 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # #} <Directory /srv/www/cobbler> Require all granted </Directory> Alias /preseed /srv/www/preseed <Directory "/srv/www/preseed"> Require all granted </Directory> 07070100000061000041ED00000000000000000000000262FD641A00000000000000000000000000000000000000000000003D00000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/vars07070100000062000081A400000000000000000000000162FD641A0000075E000000000000000000000000000000000000004800000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/vars/debian.yml# # (c) Copyright 2015-2018 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # # This task uses the bminfo struct from get-baremetal-info.yml to derive a # bunch of convenience variables that are used in various other plays. It then # goes further and figures out the name of the network interface that Cobbler # is using, by comparing the baremetal CIDR specified in the model with the # actual values in "ip a" on localhost. cobbler_is_sles: False cobbler_remove_packages: - atftpd cobbler_install_packages: - python-jsonschema - python-yaml - cobbler - syslinux-common - debian-installer-8-netboot-amd64 - tftpd-hpa - xinetd - fence-agents - ipmitool - shim-signed - grub-efi-amd64-signed cobbler_tftp_service_name: tftpd-hpa cobbler_dhcp_package_name: isc-dhcp-server cobbler_dhcp_service_name: isc-dhcp-server cobbler_dhcp_config_file: /etc/dhcp/dhcpd.conf cobbler_bootloader_sources: - { src: "/usr/lib/syslinux/modules/bios/menu.c32", filename: "menu.c32" } - { src: "/usr/lib/debian-installer/images/8/amd64/gtk/pxelinux.0", filename: "pxelinux.0" } - { src: "/usr/lib/debian-installer/images/8/amd64/gtk/ldlinux.c32", filename: "ldlinux.c32" } - { src: "/usr/lib/shim/shim.efi.signed", filename: "shim.efi.signed" } - { src: "/usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed", filename: "grubx64.efi" } cobbler_tftp_dir: /srv/tftp 07070100000063000081A400000000000000000000000162FD641A00000780000000000000000000000000000000000000004600000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/vars/main.yml# # (c) Copyright 2015-2017 Hewlett Packard Enterprise Development LP # (c) Copyright 2017-2018 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # # Specify variables for the cobbler environment # User to create on managed node ardanauser: "{{ ansible_env['USER'] }}" # User home folder on managed node ardanauser_home: "{{ ansible_env['HOME'] }}" # Local folder on deployer, where RHEL and SLES artifacts are expected to be ardanauser_deployer_home: "{{ ansible_env['HOME'] }}" # The new default is to expect baremetal information inline in servers.yml baremetal_config: "{{ playbook_dir }}/../../my_cloud/definition/data/servers.yml" ansible_setup_bin_dir: "{{ 'ansible'|bin_dir if deployer_media_legacy_layout|bool else '/usr/bin/' }}" bm_schema_base_dir: "{{ 'config-processor' | share_dir }}" bm_schema_path: "/ardana-config-processor/Data/Site/Schema/2.0/server.yml" iso_dir: /srv/www/cobbler/iso cobbler_root_device: /dev/sda boot_from_san_root_device: /dev/mapper/mpatha disable_pwd_auth: true off_poll_seconds: 15 off_poll_retries: 150 ssh_wait_seconds: 1500 hlinux_server_port: 79 deployer_server_port: "{{ hlinux_server_port }}" hlinux_path: "ardana/hlinux" suse_path: "ardana/suse" hlinux_url: "{{ deployer_server }}/{{ hlinux_path }}" suse_url: "{{ deployer_server }}/{{ suse_path }}" dhcp_timeout: 240 local_timestamp_file: "/srv/www/preseed/timestamp" set_bootdev: true enable_gateway: false 07070100000064000081A400000000000000000000000162FD641A00000615000000000000000000000000000000000000004600000000ardana-cobbler-8.0+git.1660773402.d845a45/roles/cobbler/vars/suse.yml# # (c) Copyright 2015-2018 SUSE LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # # This task uses the bminfo struct from get-baremetal-info.yml to derive a # bunch of convenience variables that are used in various other plays. It then # goes further and figures out the name of the network interface that Cobbler # is using, by comparing the baremetal CIDR specified in the model with the # actual values in "ip a" on localhost. cobbler_is_sles: True cobbler_remove_packages: - atftp cobbler_install_packages: - tftp - cobbler - xinetd - dhcp-server - syslinux - shim - python-jsonschema - python-passlib - python-pexpect cobbler_tftp_service_name: tftp cobbler_dhcp_package_name: dhcp-server cobbler_dhcp_service_name: dhcpd cobbler_dhcp_config_file: /etc/dhcpd.conf cobbler_bootloader_sources: - { src: "/usr/share/syslinux/menu.c32", filename: "menu.c32" } - { src: "/usr/share/syslinux/pxelinux.0", filename: "pxelinux.0" } - { src: "/usr/lib64/efi/shim.efi", filename: "shim.efi.signed" } cobbler_tftp_dir: /srv/tftpboot 07070100000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000B00000000TRAILER!!!568 blocks
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor