├── files └── .gitkeep ├── .gitignore ├── tasks ├── kvm_host │ ├── mk_files-dir.yml │ ├── approve-csr.yml │ ├── install-pkg.yml │ ├── setup-selinux.yml │ ├── setup-firewalld.yml │ ├── setup-dnsmasq.yml │ ├── setup-libvirtd.yml │ ├── setup-openshift-install-config.yml │ ├── install-bootstrap.yml │ ├── install-master.yml │ ├── install-worker.yml │ ├── setup-nginx.yml │ ├── wait-for-complete.yml │ └── cleanup-all.yaml └── base │ ├── mk_nginx-conf.yml │ ├── mk_libvirtd-conf.yml │ ├── mk_openshift-install-config.yml │ ├── mk_dnsmasq-conf.yml │ ├── mk_files-dir.yml │ ├── mk_boot-ipxe-cfg.yml │ └── get_materials.yml ├── docs └── assets │ └── openshift-ansible-kvm-architecture.png ├── 03_cleanup.yml ├── inventory └── hosts.sample ├── templates ├── dnsmasq │ ├── dnsmasq_conf.j2 │ └── hosts_openshift.j2 ├── bare-metal │ └── install-config-yaml.j2 ├── ipxe │ ├── boot-ipxe-cfg.j2 │ └── boot-ipxe-cfg-rootfs.j2 ├── libvirtd │ └── nat-openshift.j2 └── nginx │ └── nginx_conf.j2 ├── 01_base.yml ├── ansible.cfg ├── 02_kvm.yml ├── main.yml ├── main-minimal.yml ├── vars ├── vm_setting.yml ├── config.yml.sample └── download.yml ├── README.md └── LICENSE /files/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .ansible 2 | inventory/hosts 3 | vars/config.yml 4 | files/* 5 | -------------------------------------------------------------------------------- /tasks/kvm_host/mk_files-dir.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: make working dir 3 | file: 4 | path: "{{ files.kvm }}" 5 | state: directory 6 | -------------------------------------------------------------------------------- /docs/assets/openshift-ansible-kvm-architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kazuhisya/openshift-ansible-kvm/HEAD/docs/assets/openshift-ansible-kvm-architecture.png -------------------------------------------------------------------------------- /tasks/base/mk_nginx-conf.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: make nginx/nginx.conf 3 | template: 4 | src: templates/nginx/nginx_conf.j2 5 | dest: "{{ files.base }}/conf/nginx.conf" 6 | -------------------------------------------------------------------------------- /tasks/base/mk_libvirtd-conf.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: make libvirtd/nat-openshift.conf 3 | template: 4 | src: templates/libvirtd/nat-openshift.j2 5 | dest: "{{ files.base }}/conf/libvirtd.nat-openshift.xml" 6 | -------------------------------------------------------------------------------- /03_cleanup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: kvm_host 3 | vars_files: 4 | - vars/config.yml 5 | - vars/vm_setting.yml 6 | - vars/download.yml 7 | 8 | tasks: 9 | - include_tasks: tasks/kvm_host/cleanup-all.yaml 10 | -------------------------------------------------------------------------------- /tasks/base/mk_openshift-install-config.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: make bare-metal/install-config.yaml 3 | template: 4 | src: templates/bare-metal/install-config-yaml.j2 5 | dest: "{{ files.base }}/conf/install-config.yaml" 6 | -------------------------------------------------------------------------------- /inventory/hosts.sample: -------------------------------------------------------------------------------- 1 | [base] 2 | 127.0.0.1 ansible_connection=local 3 | 4 | [kvm_host] 5 | # Input IP addr 6 | # remote kvm host: 7 | # 192.168.0.100 8 | # local kvm: 9 | # 127.0.0.1 ansible_connection=local 10 | 11 | 12 | [kvm_host:vars] 13 | ansible_user=root 14 | -------------------------------------------------------------------------------- /tasks/base/mk_dnsmasq-conf.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: make dnsmasq/openshift.conf 3 | template: 4 | src: templates/dnsmasq/dnsmasq_conf.j2 5 | dest: "{{ files.base }}/conf/dnsmasq.openshift.conf" 6 | 7 | - name: make dnsmasq/hosts.openshift 8 | template: 9 | src: templates/dnsmasq/hosts_openshift.j2 10 | dest: "{{ files.base }}/conf/dnsmasq.hosts.openshift" 11 | -------------------------------------------------------------------------------- /templates/dnsmasq/dnsmasq_conf.j2: -------------------------------------------------------------------------------- 1 | bind-interfaces 2 | listen-address={{ kvm_host.ip }} 3 | local=/{{ net.domain }}/ 4 | address=/apps.{{ net.subdomain }}.{{ net.domain }}/{{ kvm_host.ip }} 5 | {% for m in master %} 6 | srv-host=_etcd-server-ssl._tcp.{{ net.subdomain }}.{{ net.domain }},{{ m.name }}.{{ net.subdomain }}.{{ net.domain }},2380,0,10 7 | {% endfor %} 8 | addn-hosts=/etc/hosts.openshift 9 | -------------------------------------------------------------------------------- /tasks/base/mk_files-dir.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: make files dir 3 | file: 4 | path: "{{ files.base }}" 5 | state: directory 6 | 7 | - name: make files/clients dir 8 | file: 9 | path: "{{ files.base }}/clients" 10 | state: directory 11 | 12 | - name: make files/dependencies dir 13 | file: 14 | path: "{{ files.base }}/dependencies" 15 | state: directory 16 | 17 | - name: make files/conf dir 18 | file: 19 | path: "{{ files.base }}/conf" 20 | state: directory 21 | -------------------------------------------------------------------------------- /tasks/kvm_host/approve-csr.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: check csr status 3 | shell: >- 4 | /root/bin/oc get csr | grep Pending |awk '{ print $1 }' 5 | environment: 6 | KUBECONFIG: "{{ files.kvm }}/bare-metal/auth/kubeconfig" 7 | register: result 8 | ignore_errors: yes 9 | 10 | - name: approve csr 11 | command: "/root/bin/oc adm certificate approve {{ item }}" 12 | environment: 13 | KUBECONFIG: "{{ files.kvm }}/bare-metal/auth/kubeconfig" 14 | with_items: "{{ result.stdout_lines }}" 15 | -------------------------------------------------------------------------------- /01_base.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: base 3 | vars_files: 4 | - vars/config.yml 5 | - vars/vm_setting.yml 6 | - vars/download.yml 7 | 8 | tasks: 9 | - include_tasks: tasks/base/mk_files-dir.yml 10 | - include_tasks: tasks/base/mk_dnsmasq-conf.yml 11 | - include_tasks: tasks/base/mk_libvirtd-conf.yml 12 | - include_tasks: tasks/base/mk_nginx-conf.yml 13 | - include_tasks: tasks/base/mk_boot-ipxe-cfg.yml 14 | - include_tasks: tasks/base/mk_openshift-install-config.yml 15 | - include_tasks: tasks/base/get_materials.yml 16 | 17 | -------------------------------------------------------------------------------- /templates/dnsmasq/hosts_openshift.j2: -------------------------------------------------------------------------------- 1 | {{ kvm_host.ip }} api.{{ net.subdomain }}.{{ net.domain }} {{ net.domain }} api-int.{{ net.subdomain }}.{{ net.domain }} 2 | {{ bootstrap.0.ip }} {{ bootstrap.0.name }} {{ bootstrap.0.name }}.{{ net.subdomain }}.{{ net.domain }} 3 | {% for m in master %} 4 | {{ m.ip }} {{ m.name }} {{ m.name }}.{{ net.subdomain }}.{{ net.domain }} etcd-{{ m.etcd_id }}.{{ net.subdomain }}.{{ net.domain }} 5 | {% endfor %} 6 | {% for w in worker %} 7 | {{ w.ip }} {{ w.name }} {{ w.name }}.{{ net.subdomain }}.{{ net.domain }} 8 | {% endfor %} 9 | -------------------------------------------------------------------------------- /tasks/base/mk_boot-ipxe-cfg.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: make ipxe/boot.ipxe.ROLE 3 | template: 4 | src: templates/ipxe/boot-ipxe-cfg.j2 5 | dest: "{{ files.base }}/conf/boot.ipxe.{{ item }}" 6 | with_items: 7 | - bootstrap 8 | - master 9 | - worker 10 | 11 | - name: make ipxe/boot.ipxe.ROLE for rootfs 12 | template: 13 | src: templates/ipxe/boot-ipxe-cfg-rootfs.j2 14 | dest: "{{ files.base }}/conf/boot.ipxe.{{ item }}" 15 | with_items: 16 | - bootstrap 17 | - master 18 | - worker 19 | when: 20 | - openshift.use_rootfs == true 21 | 22 | -------------------------------------------------------------------------------- /tasks/kvm_host/install-pkg.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: install libvirt, dnsmasq, nginx and related packages 3 | dnf: 4 | name: 5 | - libvirt-client 6 | - libvirt 7 | - qemu-kvm 8 | - virt-install 9 | - dnsmasq 10 | - nginx 11 | - python3-lxml 12 | - python3-libselinux 13 | - python3-policycoreutils 14 | - tar 15 | - unzip 16 | state: latest 17 | 18 | - name: install ngxinx-mod-stream for RHEL9.0+ 19 | dnf: 20 | name: 21 | - nginx-mod-stream 22 | state: latest 23 | when: ansible_distribution == "RedHat" and ansible_distribution_major_version | int >= 9 24 | -------------------------------------------------------------------------------- /tasks/kvm_host/setup-selinux.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: allow nginx(http_port_t) to listen on extra tcp ports 3 | seport: 4 | ports: "{{ item }}" 5 | proto: tcp 6 | setype: http_port_t 7 | state: present 8 | with_items: 9 | - "6443" 10 | - "8000" 11 | - "22623" 12 | 13 | - name: set seboolean flag on and keep it persistent across reboots 14 | seboolean: 15 | name: "{{ item }}" 16 | state: yes 17 | persistent: yes 18 | ignore_selinux_state: yes 19 | with_items: 20 | - "httpd_can_network_connect" 21 | - "httpd_graceful_shutdown" 22 | - "httpd_can_network_relay" 23 | - "nis_enabled" 24 | - "daemons_dump_core" 25 | -------------------------------------------------------------------------------- /templates/bare-metal/install-config-yaml.j2: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | baseDomain: {{ net.domain }} 3 | compute: 4 | - hyperthreading: Enabled 5 | name: worker 6 | replicas: {{ spec_worker.num_worker }} 7 | controlPlane: 8 | hyperthreading: Enabled 9 | name: master 10 | replicas: {{ spec_master.num_master }} 11 | metadata: 12 | name: {{ net.subdomain }} 13 | networking: 14 | clusterNetwork: 15 | {% for n in cluster_net %} 16 | - cidr: {{ n.cluster_cidr }} 17 | hostPrefix: {{ n.cluster_prefx }} 18 | {% endfor %} 19 | networkType: {{ net.cluster_net_type }} 20 | serviceNetwork: 21 | - {{ net.service }} 22 | platform: 23 | none: {} 24 | pullSecret: '{{ key.pullsecret }}' 25 | sshKey: '{{ key.sshkey}}' 26 | -------------------------------------------------------------------------------- /templates/ipxe/boot-ipxe-cfg.j2: -------------------------------------------------------------------------------- 1 | #!ipxe 2 | 3 | # Variables are specified in boot.ipxe.cfg 4 | 5 | # Figure out if client is 64-bit capable 6 | cpuid --ext 29 && set arch x64 || set arch x86 7 | cpuid --ext 29 && set archl amd64 || set archl i386 8 | 9 | kernel http://{{ libvirt_nat.router }}:8000/ipxe/{{ config.coreos_kernel }} ip=dhcp rd.neednet=1 initrd=http://{{ libvirt_nat.router }}:8000/ipxe/{{ config.coreos_initramfs }} console=tty0 console=ttyS0 coreos.inst=yes coreos.inst.install_dev=vda coreos.inst.image_url=http://{{ libvirt_nat.router }}:8000/ipxe/{{ config.coreos_bios }} coreos.inst.ignition_url=http://{{ libvirt_nat.router }}:8000/openshift/coreos/ignitions/{{ item }}.ign 10 | initrd http://{{ libvirt_nat.router }}:8000/ipxe/{{ config.coreos_initramfs }} 11 | boot 12 | EOF 13 | -------------------------------------------------------------------------------- /tasks/kvm_host/setup-firewalld.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: (re)start firewalld daemon 3 | service: 4 | name: firewalld 5 | state: restarted 6 | 7 | - name: firewalld open ports for public 8 | firewalld: 9 | zone: public 10 | port: "{{ item }}" 11 | state: enabled 12 | permanent: yes 13 | immediate: yes 14 | with_items: 15 | - 5900-5910/tcp 16 | - 6443/tcp 17 | - 22623/tcp 18 | - 80/tcp 19 | - 443/tcp 20 | - 53/tcp 21 | - 53/udp 22 | 23 | - name: firewalld open ports for libvirt 24 | firewalld: 25 | zone: libvirt 26 | port: "{{ item }}" 27 | state: enabled 28 | permanent: yes 29 | immediate: yes 30 | with_items: 31 | - 8000/tcp 32 | - 6443/tcp 33 | - 22623/tcp 34 | - 80/tcp 35 | - 443/tcp 36 | - 53/tcp 37 | - 53/udp 38 | -------------------------------------------------------------------------------- /ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | # Set tmp path 3 | local_tmp = ./.ansible/tmp 4 | 5 | # Set the log_path 6 | log_path = ./.ansible/ansible.log 7 | 8 | # Additional default options for OpenShift Ansible 9 | forks = 20 10 | host_key_checking = False 11 | retry_files_enabled = False 12 | retry_files_save_path = ./.ansible/retries 13 | remote_user = root 14 | gathering = smart 15 | fact_caching = jsonfile 16 | fact_caching_connection = ./.ansible/facts 17 | fact_caching_timeout = 600 18 | timeout = 30 19 | # show running time 20 | callbacks_enabled=profile_tasks 21 | 22 | inventory = inventory/hosts 23 | 24 | [inventory] 25 | unparsed_is_failed=true 26 | 27 | # Additional ssh options 28 | [ssh_connection] 29 | retries = 15 30 | pipelining = True 31 | ssh_args = -o ControlMaster=auto -o ControlPersist=600s 32 | timeout = 10 33 | control_path = %(directory)s/%%h-%%r 34 | 35 | -------------------------------------------------------------------------------- /02_kvm.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: kvm_host 3 | vars_files: 4 | - vars/config.yml 5 | - vars/vm_setting.yml 6 | - vars/download.yml 7 | 8 | tasks: 9 | - include_tasks: tasks/kvm_host/mk_files-dir.yml 10 | - include_tasks: tasks/kvm_host/install-pkg.yml 11 | - include_tasks: tasks/kvm_host/setup-selinux.yml 12 | - include_tasks: tasks/kvm_host/setup-firewalld.yml 13 | - include_tasks: tasks/kvm_host/setup-dnsmasq.yml 14 | - include_tasks: tasks/kvm_host/setup-libvirtd.yml 15 | - include_tasks: tasks/kvm_host/setup-nginx.yml 16 | - include_tasks: tasks/kvm_host/setup-openshift-install-config.yml 17 | - include_tasks: tasks/kvm_host/install-bootstrap.yml 18 | - include_tasks: tasks/kvm_host/install-master.yml 19 | - include_tasks: tasks/kvm_host/install-worker.yml 20 | - include_tasks: tasks/kvm_host/wait-for-complete.yml 21 | -------------------------------------------------------------------------------- /tasks/kvm_host/setup-dnsmasq.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: send dnsmasq config to kvm host 3 | copy: 4 | src: "{{ files.base }}/conf/dnsmasq.openshift.conf" 5 | dest: /etc/dnsmasq.d/openshift.conf 6 | selevel: s0 7 | serole: object_r 8 | setype: dnsmasq_etc_t 9 | seuser: system_u 10 | 11 | - name: send dnsmasq hosts to kvm host 12 | copy: 13 | src: "{{ files.base }}/conf/dnsmasq.hosts.openshift" 14 | dest: /etc/hosts.openshift 15 | selevel: s0 16 | serole: object_r 17 | setype: net_conf_t 18 | seuser: system_u 19 | 20 | - name: add a new line to /etc/resolv.conf 21 | lineinfile: 22 | path: /etc/resolv.conf 23 | firstmatch: yes 24 | insertbefore: '^nameserver' 25 | line: "nameserver {{ kvm_host.ip }}" 26 | 27 | - name: (re)start dnsmasq daemon 28 | service: 29 | name: dnsmasq 30 | state: restarted 31 | 32 | -------------------------------------------------------------------------------- /tasks/kvm_host/setup-libvirtd.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: (re)start libvirt daemon 3 | service: 4 | name: libvirtd 5 | state: restarted 6 | 7 | - name: check if openshift nat already exists 8 | virt_net: 9 | command: list_nets 10 | register: all_nets 11 | 12 | - name: destroy old openshift nat 13 | virt_net: 14 | command: destroy 15 | name: openshift 16 | when: "'openshift' in all_nets.list_nets" 17 | 18 | - name: undefine old openshift nat 19 | virt_net: 20 | command: undefine 21 | name: openshift 22 | when: "'openshift' in all_nets.list_nets" 23 | 24 | - name: define openshift nat 25 | virt_net: 26 | command: define 27 | name: openshift 28 | xml: "{{lookup('file', '{{ files.base }}/conf/libvirtd.nat-openshift.xml')}}" 29 | 30 | - name: start openshift nat 31 | virt_net: 32 | command: create 33 | name: openshift 34 | state: active 35 | -------------------------------------------------------------------------------- /templates/ipxe/boot-ipxe-cfg-rootfs.j2: -------------------------------------------------------------------------------- 1 | #!ipxe 2 | 3 | # Variables are specified in boot.ipxe.cfg 4 | 5 | # Figure out if client is 64-bit capable 6 | cpuid --ext 29 && set arch x64 || set arch x86 7 | cpuid --ext 29 && set archl amd64 || set archl i386 8 | 9 | kernel http://{{ libvirt_nat.router }}:8000/ipxe/{{ config.coreos_kernel }} coreos.live.rootfs_url=http://{{ libvirt_nat.router }}:8000/ipxe/{{ config.coreos_rootfs }} ip=dhcp rd.neednet=1 initrd=http://{{ libvirt_nat.router }}:8000/ipxe/{{ config.coreos_initramfs }} console=tty0 console=ttyS0 coreos.inst=yes coreos.inst.install_dev=vda coreos.inst.image_url=http://{{ libvirt_nat.router }}:8000/ipxe/{{ config.coreos_bios }} coreos.inst.insecure=true coreos.inst.ignition_url=http://{{ libvirt_nat.router }}:8000/openshift/coreos/ignitions/{{ item }}.ign 10 | initrd http://{{ libvirt_nat.router }}:8000/ipxe/{{ config.coreos_initramfs }} 11 | boot 12 | EOF 13 | -------------------------------------------------------------------------------- /templates/libvirtd/nat-openshift.j2: -------------------------------------------------------------------------------- 1 | 2 | openshift 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | {% if use_ext_dns==true %} 11 | 12 | {% for dns in ext_dns %} 13 | 14 | {% endfor %} 15 | 16 | {% endif %} 17 | 18 | 19 | 20 | 21 | . 22 | {% for m in master %} 23 | . 24 | {% endfor %} 25 | {% for w in worker %} 26 | . 27 | {% endfor %} 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: base 3 | gather_facts: yes 4 | vars_files: 5 | - vars/config.yml 6 | - vars/vm_setting.yml 7 | - vars/download.yml 8 | 9 | tasks: 10 | - include_tasks: tasks/base/mk_files-dir.yml 11 | - include_tasks: tasks/base/mk_dnsmasq-conf.yml 12 | - include_tasks: tasks/base/mk_libvirtd-conf.yml 13 | - include_tasks: tasks/base/mk_nginx-conf.yml 14 | - include_tasks: tasks/base/mk_boot-ipxe-cfg.yml 15 | - include_tasks: tasks/base/mk_openshift-install-config.yml 16 | - include_tasks: tasks/base/get_materials.yml 17 | 18 | - hosts: kvm_host 19 | gather_facts: yes 20 | vars_files: 21 | - vars/config.yml 22 | - vars/vm_setting.yml 23 | - vars/download.yml 24 | 25 | tasks: 26 | - include_tasks: tasks/kvm_host/mk_files-dir.yml 27 | - include_tasks: tasks/kvm_host/install-pkg.yml 28 | - include_tasks: tasks/kvm_host/setup-selinux.yml 29 | - include_tasks: tasks/kvm_host/setup-firewalld.yml 30 | - include_tasks: tasks/kvm_host/setup-dnsmasq.yml 31 | - include_tasks: tasks/kvm_host/setup-libvirtd.yml 32 | - include_tasks: tasks/kvm_host/setup-nginx.yml 33 | - include_tasks: tasks/kvm_host/setup-openshift-install-config.yml 34 | - include_tasks: tasks/kvm_host/install-bootstrap.yml 35 | - include_tasks: tasks/kvm_host/install-master.yml 36 | - include_tasks: tasks/kvm_host/install-worker.yml 37 | - include_tasks: tasks/kvm_host/wait-for-complete.yml 38 | -------------------------------------------------------------------------------- /main-minimal.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: base 3 | gather_facts: yes 4 | vars_files: 5 | - vars/config.yml 6 | - vars/vm_setting.yml 7 | - vars/download.yml 8 | 9 | tasks: 10 | - include_tasks: tasks/base/mk_files-dir.yml 11 | - include_tasks: tasks/base/mk_dnsmasq-conf.yml 12 | - include_tasks: tasks/base/mk_libvirtd-conf.yml 13 | - include_tasks: tasks/base/mk_nginx-conf.yml 14 | - include_tasks: tasks/base/mk_boot-ipxe-cfg.yml 15 | - include_tasks: tasks/base/mk_openshift-install-config.yml 16 | - include_tasks: tasks/base/get_materials.yml 17 | 18 | - hosts: kvm_host 19 | gather_facts: yes 20 | vars_files: 21 | - vars/config.yml 22 | - vars/vm_setting.yml 23 | - vars/download.yml 24 | 25 | tasks: 26 | - include_tasks: tasks/kvm_host/mk_files-dir.yml 27 | - include_tasks: tasks/kvm_host/install-pkg.yml 28 | - include_tasks: tasks/kvm_host/setup-selinux.yml 29 | - include_tasks: tasks/kvm_host/setup-firewalld.yml 30 | - include_tasks: tasks/kvm_host/setup-dnsmasq.yml 31 | - include_tasks: tasks/kvm_host/setup-libvirtd.yml 32 | - include_tasks: tasks/kvm_host/setup-nginx.yml 33 | - include_tasks: tasks/kvm_host/setup-openshift-install-config.yml 34 | - include_tasks: tasks/kvm_host/install-bootstrap.yml 35 | - include_tasks: tasks/kvm_host/install-master.yml 36 | # - include_tasks: tasks/kvm_host/install-worker.yml 37 | - include_tasks: tasks/kvm_host/wait-for-complete.yml 38 | -------------------------------------------------------------------------------- /tasks/kvm_host/setup-openshift-install-config.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: make /root/bin dir 3 | file: 4 | path: /root/bin 5 | state: directory 6 | 7 | - name: check old bare-metal dir 8 | stat: 9 | path: "{{ files.kvm }}/bare-metal" 10 | register: chk_file 11 | 12 | - name: remove old bare-metal dir 13 | file: 14 | path: "{{ files.kvm }}/bare-metal" 15 | state: absent 16 | when: chk_file.stat.exists == true 17 | 18 | - name: make bare-metal dir 19 | file: 20 | path: "{{ files.kvm }}/bare-metal" 21 | state: directory 22 | 23 | - name: send install-config.yaml to kvm host 24 | copy: 25 | src: "{{ files.base }}/conf/install-config.yaml" 26 | dest: "{{ files.kvm }}/bare-metal" 27 | 28 | - name: send openshift installer 29 | unarchive: 30 | src: "{{ files.base }}/clients/{{ config.openshift_installer }}" 31 | dest: /root/bin 32 | exclude: README.md 33 | 34 | - name: send openshift clients 35 | unarchive: 36 | src: "{{ files.base }}/clients/{{ config.openshift_client }}" 37 | dest: /root/bin 38 | exclude: README.md 39 | 40 | - name: create ignition-configs 41 | command: "/root/bin/openshift-install create ignition-configs --dir={{ files.kvm }}/bare-metal" 42 | 43 | - name: copy ign files 44 | copy: 45 | src: "{{ files.kvm }}/bare-metal/{{ item }}" 46 | dest: /usr/share/nginx/html/openshift/coreos/ignitions 47 | selevel: s0 48 | serole: object_r 49 | setype: httpd_sys_content_t 50 | seuser: system_u 51 | mode: 0644 52 | remote_src: true 53 | with_items: 54 | - bootstrap.ign 55 | - master.ign 56 | - worker.ign 57 | 58 | -------------------------------------------------------------------------------- /tasks/kvm_host/install-bootstrap.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: prepare bootstrap ipxe files 3 | copy: 4 | src: /usr/share/nginx/html/ipxe/boot.ipxe.bootstrap 5 | dest: /usr/share/nginx/html/ipxe/boot.ipxe 6 | selevel: s0 7 | serole: object_r 8 | setype: httpd_sys_content_t 9 | seuser: system_u 10 | mode: 0644 11 | remote_src: true 12 | 13 | - name: check if bootstrap already exists 14 | virt: 15 | command: list_vms 16 | register: all_vms 17 | 18 | # want fix: move to using the virt module... 19 | - name: destroy old bootstrap 20 | shell: | 21 | virsh destroy {{ bootstrap.0.name }} 22 | virsh undefine --remove-all-storage {{ bootstrap.0.name }} 23 | when: 'bootstrap.0.name in all_vms.list_vms' 24 | 25 | # want fix: move to using the virt module... 26 | - name: install bootstrap node 27 | shell: >- 28 | virt-install 29 | --name {{bootstrap.0.name}} 30 | --hvm 31 | --virt-type kvm 32 | --pxe 33 | --arch x86_64 34 | --os-type linux 35 | --os-variant rhel8.0 36 | --network network=openshift,mac="52:54:00:00:01:{{bootstrap.0.mac}}" 37 | --vcpus {{spec_bootstrap.cpu}} 38 | --ram {{spec_bootstrap.ram}} 39 | --disk pool=default,size={{spec_bootstrap.disk}},format=qcow2,cache={{ spec_bootstrap.disk_cache }} 40 | --check disk_size=off 41 | --graphics vnc,listen=0.0.0.0 42 | --noautoconsole 43 | --boot menu=on,useserial=on 44 | 45 | - name: waiting for end of the initial installation of bootstrap 46 | virt: 47 | name: "{{ bootstrap.0.name }}" 48 | command: status 49 | register: result 50 | until: result.status == "shutdown" 51 | retries: 100 52 | delay: 10 53 | 54 | - name: restart bootstrap 55 | virt: 56 | name: "{{ bootstrap.0.name }}" 57 | state: running 58 | 59 | - name: waiting for sshd of bootstrap 60 | wait_for: 61 | host: "{{ bootstrap.0.ip }}" 62 | port: 22 63 | delay: 10 64 | search_regex: OpenSSH 65 | state: started 66 | timeout: 1200 67 | 68 | -------------------------------------------------------------------------------- /tasks/kvm_host/install-master.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: prepare master ipxe files 3 | copy: 4 | src: /usr/share/nginx/html/ipxe/boot.ipxe.master 5 | dest: /usr/share/nginx/html/ipxe/boot.ipxe 6 | selevel: s0 7 | serole: object_r 8 | setype: httpd_sys_content_t 9 | seuser: system_u 10 | mode: 0644 11 | remote_src: true 12 | 13 | - name: check if master already exists 14 | virt: 15 | command: list_vms 16 | register: all_vms 17 | 18 | # want fix: move to using the virt module... 19 | - name: destroy old master 20 | shell: | 21 | virsh destroy {{ item.name }} 22 | virsh undefine --remove-all-storage {{ item.name }} 23 | when: 'item.name in all_vms.list_vms' 24 | with_items: "{{ master }}" 25 | 26 | # want fix: move to using the virt module... 27 | - name: install master node 28 | shell: >- 29 | virt-install 30 | --name {{item.name}} 31 | --hvm 32 | --virt-type kvm 33 | --pxe 34 | --arch x86_64 35 | --os-type linux 36 | --os-variant rhel8.0 37 | --network network=openshift,mac="52:54:00:00:01:{{item.mac}}" 38 | --vcpus {{spec_master.cpu}} 39 | --ram {{spec_master.ram}} 40 | --disk pool=default,size={{spec_master.disk}},format=qcow2,cache={{ spec_master.disk_cache }} 41 | --check disk_size=off 42 | --graphics vnc,listen=0.0.0.0 43 | --noautoconsole 44 | --boot menu=on,useserial=on 45 | with_items: "{{ master }}" 46 | 47 | - name: waiting for end of the initial installation of master 48 | virt: 49 | name: "{{ item.name }}" 50 | command: status 51 | register: result 52 | until: result.status == "shutdown" 53 | retries: 100 54 | delay: 10 55 | with_items: "{{ master }}" 56 | 57 | - name: restart master 58 | virt: 59 | name: "{{ item.name }}" 60 | state: running 61 | with_items: "{{ master }}" 62 | delay: 3 63 | 64 | - name: waiting for sshd of master 65 | wait_for: 66 | host: "{{ item.ip }}" 67 | port: 22 68 | delay: 10 69 | search_regex: OpenSSH 70 | state: started 71 | with_items: "{{ master }}" 72 | 73 | -------------------------------------------------------------------------------- /tasks/kvm_host/install-worker.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: prepare worker ipxe files 3 | copy: 4 | src: /usr/share/nginx/html/ipxe/boot.ipxe.worker 5 | dest: /usr/share/nginx/html/ipxe/boot.ipxe 6 | selevel: s0 7 | serole: object_r 8 | setype: httpd_sys_content_t 9 | seuser: system_u 10 | mode: 0644 11 | remote_src: true 12 | 13 | - name: check if worker already exists 14 | virt: 15 | command: list_vms 16 | register: all_vms 17 | 18 | # want fix: move to using the virt module... 19 | - name: destroy old worker 20 | shell: | 21 | virsh destroy {{ item.name }} 22 | virsh undefine --remove-all-storage {{ item.name }} 23 | when: 'item.name in all_vms.list_vms' 24 | with_items: "{{ worker }}" 25 | 26 | # want fix: move to using the virt module... 27 | - name: install worker node 28 | shell: >- 29 | virt-install 30 | --name {{item.name}} 31 | --hvm 32 | --virt-type kvm 33 | --pxe 34 | --arch x86_64 35 | --os-type linux 36 | --os-variant rhel8.0 37 | --network network=openshift,mac="52:54:00:00:01:{{item.mac}}" 38 | --vcpus {{spec_worker.cpu}} 39 | --ram {{spec_worker.ram}} 40 | --disk pool=default,size={{spec_worker.disk}},format=qcow2,cache={{ spec_worker.disk_cache }} 41 | --check disk_size=off 42 | --graphics vnc,listen=0.0.0.0 43 | --noautoconsole 44 | --boot menu=on,useserial=on 45 | with_items: "{{ worker }}" 46 | 47 | - name: waiting for end of the initial installation of worker 48 | virt: 49 | name: "{{ item.name }}" 50 | command: status 51 | register: result 52 | until: result.status == "shutdown" 53 | retries: 100 54 | delay: 10 55 | with_items: "{{ worker }}" 56 | 57 | - name: restart worker 58 | virt: 59 | name: "{{ item.name }}" 60 | state: running 61 | with_items: "{{ worker }}" 62 | delay: 3 63 | 64 | # we don't wait for start up of worker(s) 65 | #- name: waiting for sshd of worker 66 | # wait_for: 67 | # host: "{{ item.ip }}" 68 | # port: 22 69 | # delay: 10 70 | # search_regex: OpenSSH 71 | # state: started 72 | # with_items: "{{ worker }}" 73 | 74 | -------------------------------------------------------------------------------- /tasks/kvm_host/setup-nginx.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: send nginx config to kvm host 3 | copy: 4 | src: "{{ files.base }}/conf/nginx.conf" 5 | dest: /etc/nginx/nginx.conf 6 | selevel: s0 7 | serole: object_r 8 | setype: httpd_config_t 9 | seuser: system_u 10 | 11 | - name: make nginx ipxe dir 12 | file: 13 | path: /usr/share/nginx/html/ipxe 14 | state: directory 15 | recurse: yes 16 | selevel: s0 17 | serole: object_r 18 | setype: httpd_sys_content_t 19 | seuser: system_u 20 | mode: 0755 21 | 22 | - name: make nginx ignitions dir 23 | file: 24 | path: /usr/share/nginx/html/openshift/coreos/ignitions 25 | state: directory 26 | recurse: yes 27 | selevel: s0 28 | serole: object_r 29 | setype: httpd_sys_content_t 30 | seuser: system_u 31 | mode: 0755 32 | 33 | - name: send coreos to kvm host 34 | copy: 35 | src: "{{ files.base }}/dependencies/{{ item }}" 36 | dest: /usr/share/nginx/html/ipxe/ 37 | selevel: s0 38 | serole: object_r 39 | setype: httpd_sys_content_t 40 | seuser: system_u 41 | mode: 0644 42 | with_items: 43 | - "{{ config.coreos_kernel }}" 44 | - "{{ config.coreos_initramfs }}" 45 | - "{{ config.coreos_bios }}" 46 | 47 | - name: send coreos to kvm host for rootfs 48 | copy: 49 | src: "{{ files.base }}/dependencies/{{ item }}" 50 | dest: /usr/share/nginx/html/ipxe/ 51 | selevel: s0 52 | serole: object_r 53 | setype: httpd_sys_content_t 54 | seuser: system_u 55 | mode: 0644 56 | with_items: 57 | - "{{ config.coreos_rootfs }}" 58 | when: 59 | - openshift.use_rootfs == true 60 | 61 | - name: send coreos signature to kvm host 62 | copy: 63 | src: "{{ files.base }}/dependencies/{{ config.coreos_bios }}.sig" 64 | dest: /usr/share/nginx/html/ipxe/ 65 | selevel: s0 66 | serole: object_r 67 | setype: httpd_sys_content_t 68 | seuser: system_u 69 | when: openshift.dist == "okd" 70 | 71 | - name: send boot.ipxe to kvm host 72 | copy: 73 | src: "{{ files.base }}/conf/{{ item }}" 74 | dest: /usr/share/nginx/html/ipxe/ 75 | selevel: s0 76 | serole: object_r 77 | setype: httpd_sys_content_t 78 | seuser: system_u 79 | mode: 0644 80 | with_items: 81 | - boot.ipxe.bootstrap 82 | - boot.ipxe.master 83 | - boot.ipxe.worker 84 | 85 | - name: (re)start nginx daemon 86 | service: 87 | name: nginx 88 | state: restarted 89 | 90 | -------------------------------------------------------------------------------- /vars/vm_setting.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # OpenShift Network 3 | net: 4 | domain: lab.local 5 | subdomain: test 6 | service: 172.30.0.0/16 7 | #cluster_net_type: OpenShiftSDN 8 | cluster_net_type: OVNKubernetes 9 | cluster_net: 10 | - cluster_cidr: 10.128.0.0/14 11 | cluster_prefx: 23 12 | # Multiple subnets can be mentioned only for clusterNetwork. 13 | # "OpenShiftSDN" and "OVNKubernetes", support multiple ClusterNetworks. 14 | # https://access.redhat.com/solutions/6015571 15 | # e.g. 16 | # cluster_net: 17 | # - cluster_cidr: 10.128.0.0/19 18 | # cluster_prefx: 23 19 | # - cluster_cidr: 10.128.32.0/19 20 | # cluster_prefx: 23 21 | 22 | # libviert NAT 23 | libvirt_nat: 24 | router: 172.16.0.1 25 | netmask: 255.255.255.0 26 | dhcp_start: 172.16.0.2 27 | dhcp_end: 172.16.0.254 28 | 29 | # Guet Settings 30 | # Bootstrap VM 31 | bootstrap: 32 | - name: bootstrap 33 | ip: 172.16.0.100 34 | mac: "01" 35 | # Master VMs 36 | master: 37 | - name: master-0 38 | ip: 172.16.0.101 39 | mac: "02" 40 | etcd_id: 0 41 | - name: master-1 42 | ip: 172.16.0.102 43 | mac: "03" 44 | etcd_id: 1 45 | - name: master-2 46 | ip: 172.16.0.103 47 | mac: "04" 48 | etcd_id: 2 49 | # Worker VMs 50 | worker: 51 | - name: worker-0 52 | ip: 172.16.0.104 53 | mac: "05" 54 | - name: worker-1 55 | ip: 172.16.0.105 56 | mac: "06" 57 | 58 | # Guest specs 59 | # disk_cache: This attribute controls the cache mechanism. 60 | # default, none, writethrough, writeback, directsync and unsafe. 61 | # The "unsafe" option may be useful when you don't have a fast disk. 62 | 63 | # Bootstrap VM 64 | spec_bootstrap: 65 | cpu: 4 66 | ram: 16384 67 | disk: 128 68 | disk_cache: unsafe 69 | 70 | # Master VMs 71 | spec_master: 72 | num_master: 3 73 | cpu: 4 74 | #ram: 18432 75 | ram: 20480 76 | disk: 128 77 | disk_cache: unsafe 78 | 79 | # Worker VMs 80 | # num_worker: You must set the value of the replicas parameter to 0. 81 | # see also: 1.1.7.1. Sample install-config.yaml file for bare metal 82 | # https://access.redhat.com/documentation/en-us/openshift_container_platform/4.5/html/installing_on_bare_metal/installing-on-bare-metal#installation-initializing-manual_installing-bare-metal 83 | spec_worker: 84 | num_worker: 0 85 | cpu: 2 86 | ram: 8192 87 | disk: 128 88 | disk_cache: unsafe 89 | 90 | # Remove the bootstrap node after the OCP installation is complete. 91 | # If this value is "true", the bootstrap node will be preserved. 92 | keep_bootstrap: false 93 | 94 | -------------------------------------------------------------------------------- /vars/config.yml.sample: -------------------------------------------------------------------------------- 1 | --- 2 | # KVM host IP and name of NIC 3 | # e.g. 192.168.0.100 (do not input 127.0.0.1), enp2s0f0 4 | kvm_host: 5 | ip: 6 | if: 7 | 8 | # OpenShift environment settings 9 | # dist: Select the distribution to deploy "ocp", "okd" or "pre-release"(pre-release of ocp). 10 | # install_version: openshift-install and openshift-client version. 11 | # ocp: https://mirror.openshift.com/pub/openshift-v4/clients/ocp/ 12 | # okd: https://github.com/openshift/okd/releases 13 | # coreos_version: CoreOS version 14 | # ocp: https://mirror.openshift.com/pub/openshift-v4/dependencies/rhcos/ 15 | # okd: https://getfedora.org/en/coreos/download?tab=metal_virtualized&stream=stable 16 | # --- e.g OCO 4.5 ------------- 17 | # install_version: 4.5.2 18 | # coreos_version: 4.5.2 19 | # --- e.g OKD 4 --------------- 20 | # * The sha256sum of OCP4, oc client and openshift-install is automatically detected 21 | # * by sha256sum.txt. but FOCS does not provide sha256sum.txt, so you have to 22 | # * check and input it yourself from the website. 23 | # * https://getfedora.org/en/coreos/download?tab=metal_virtualized&stream=stable 24 | # install_version: 4.5.0-0.okd-2020-07-14-153706-ga 25 | # coreos_version: 32.20200629.3.0 26 | # okd_kenrel_sha256: e58b29e5394b4167f0573c89c23b3b9bfe577c527ef160898cd6e0882a3ed8e8 27 | # okd_initramfs_sha256: 8384393ba7a53a301db9a6c3e2a7c0ca38fb23a2af428517af1e9deccc7d921e 28 | # okd_raw_sha256: 5718209c6c5ba019847184f5fad5964ac972524e9ffe8b00f653ad3e9c702de9 29 | # ----------------------------- 30 | # use_rootfs: RHCOS 4.6+ requires rootfs. (true|false) 31 | openshift: 32 | dist: ocp 33 | install_version: 4.7.1 34 | coreos_version: 4.7.0 35 | use_rootfs: true 36 | 37 | # dist: okd 38 | # install_version: 4.5.0-0.okd-2020-07-14-153706-ga 39 | # coreos_version: 32.20200629.3.0 40 | # okd_kenrel_sha256: e58b29e5394b4167f0573c89c23b3b9bfe577c527ef160898cd6e0882a3ed8e8 41 | # okd_initramfs_sha256: 8384393ba7a53a301db9a6c3e2a7c0ca38fb23a2af428517af1e9deccc7d921e 42 | # okd_raw_sha256: 5718209c6c5ba019847184f5fad5964ac972524e9ffe8b00f653ad3e9c702de9 43 | 44 | # pullsecret: '{"auths":{"cloud.openshift.com"......}}' 45 | # sshkey: 'ssh-rsa AAAABBB.....' 46 | key: 47 | pullsecret: '' 48 | sshkey: '' 49 | 50 | # You can stay the configurations and binaries on the kvm host when you run the cleanup. 51 | # conf: configuration files. e.g. dnsmasq, install-config.yaml, etc... 52 | # bin: binary files. e.g. initramfs, oc client, etc ... 53 | # true: remove old files 54 | # false: stay old files 55 | cleanup: 56 | conf: true 57 | bin: false 58 | 59 | # DNS hack for libvirt 60 | # Hack for internet connection issues with tricky DNS provided by libvirt+dnsmasq 61 | use_ext_dns: false 62 | -------------------------------------------------------------------------------- /tasks/base/get_materials.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # want fix: FCOS has a different checksum provision method 3 | # and cannot be handled by the same logic as RHCOS. 4 | - name: download coreos kernel 5 | get_url: 6 | url: "{{ url.coreos_kernel_url }}" 7 | dest: "{{ files.base }}/dependencies/{{ config.coreos_kernel }}" 8 | checksum: "sha256:{{ url.sha256_kernel_url }}" 9 | register: downloaded_kernel 10 | until: downloaded_kernel is succeeded 11 | retries: 3 12 | 13 | - name: download coreos initramfs 14 | get_url: 15 | url: "{{ url.coreos_initramfs_url }}" 16 | dest: "{{ files.base }}/dependencies/{{ config.coreos_initramfs }}" 17 | checksum: "sha256:{{ url.sha256_initramfs_url }}" 18 | register: downloaded_initramfs 19 | until: downloaded_initramfs is succeeded 20 | retries: 3 21 | 22 | - name: download coreos bios 23 | get_url: 24 | url: "{{ url.coreos_bios_url }}" 25 | dest: "{{ files.base }}/dependencies/{{ config.coreos_bios }}" 26 | checksum: "sha256:{{ url.sha256_bios_url }}" 27 | register: downloaded_bios 28 | until: downloaded_bios is succeeded 29 | retries: 3 30 | 31 | - name: download coreos bios signature 32 | get_url: 33 | url: "{{ url.coreos_bios_url }}.sig" 34 | dest: "{{ files.base }}/dependencies/{{ config.coreos_bios }}.sig" 35 | register: downloaded_bios_sig 36 | until: downloaded_bios_sig is succeeded 37 | retries: 3 38 | when: openshift.dist == "okd" 39 | 40 | - name: download coreos rootfs 41 | get_url: 42 | url: "{{ url.coreos_rootfs_url }}" 43 | dest: "{{ files.base }}/dependencies/{{ config.coreos_rootfs }}" 44 | checksum: "sha256:{{ url.sha256_rootfs_url }}" 45 | register: downloaded_rootfs 46 | until: downloaded_rootfs is succeeded 47 | retries: 3 48 | when: 49 | - openshift.use_rootfs == true 50 | 51 | - name: download coreos rootfs signature 52 | get_url: 53 | url: "{{ url.coreos_rootfs_url }}.sig" 54 | dest: "{{ files.base }}/dependencies/{{ config.coreos_rootfs }}.sig" 55 | register: downloaded_rootfs_sig 56 | until: downloaded_rootfs_sig is succeeded 57 | retries: 3 58 | when: 59 | - openshift.use_rootfs == true 60 | - openshift.dist == "okd" 61 | 62 | - name: download openshift installer 63 | get_url: 64 | url: "{{ url.openshift_installer_url }}" 65 | dest: "{{ files.base }}/clients/{{ config.openshift_installer }}" 66 | checksum: "sha256:{{ url.sha256_client_url }}" 67 | register: downloaded_installer 68 | until: downloaded_installer is succeeded 69 | retries: 3 70 | 71 | - name: download openshift client 72 | get_url: 73 | url: "{{ url.openshift_client_url }}" 74 | dest: "{{ files.base }}/clients/{{ config.openshift_client }}" 75 | checksum: "sha256:{{ url.sha256_client_url }}" 76 | register: downloaded_client 77 | until: downloaded_client is succeeded 78 | retries: 3 79 | 80 | -------------------------------------------------------------------------------- /tasks/kvm_host/wait-for-complete.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: fetch kubeadmin-password from kvm host 3 | fetch: 4 | src: "{{ files.kvm }}/bare-metal/auth/kubeadmin-password" 5 | dest: "{{ files.base }}/conf/" 6 | flat: yes 7 | 8 | - name: fetch kubeconfig from kvm host 9 | fetch: 10 | src: "{{ files.kvm }}/bare-metal/auth/kubeconfig" 11 | dest: "{{ files.base }}/conf/" 12 | flat: yes 13 | 14 | - name: wait-for bootstrap-complete 15 | command: "/root/bin/openshift-install --dir={{ files.kvm }}/bare-metal wait-for bootstrap-complete" 16 | async: 3600 17 | poll: 0 18 | register: bootstrap_complete_sleeper 19 | 20 | - name: 'bootstrap-complete - check on async task' 21 | async_status: 22 | jid: "{{ bootstrap_complete_sleeper.ansible_job_id }}" 23 | register: job_result 24 | until: job_result.finished 25 | retries: 1200 26 | delay: 30 27 | 28 | - name: oc whoami 29 | command: /root/bin/oc whoami 30 | environment: 31 | KUBECONFIG: "{{ files.kvm }}/bare-metal/auth/kubeconfig" 32 | retries: 100 33 | delay: 10 34 | register: result 35 | until: result is not failed 36 | 37 | - name: oc get nodes 38 | command: /root/bin/oc get nodes 39 | environment: 40 | KUBECONFIG: "{{ files.kvm }}/bare-metal/auth/kubeconfig" 41 | retries: 100 42 | delay: 10 43 | register: result 44 | until: result is not failed 45 | 46 | - name: oc get csr 47 | command: /root/bin/oc get csr 48 | environment: 49 | KUBECONFIG: "{{ files.kvm }}/bare-metal/auth/kubeconfig" 50 | retries: 100 51 | delay: 10 52 | register: result 53 | until: result is not failed 54 | 55 | - name: oc path to configs.imageregistry.operator.openshift.io/cluster 56 | command: /root/bin/oc patch configs.imageregistry.operator.openshift.io/cluster --type merge --patch '{"spec":{"storage":{"emptyDir":{}}}}' 57 | environment: 58 | KUBECONFIG: "{{ files.kvm }}/bare-metal/auth/kubeconfig" 59 | retries: 100 60 | delay: 10 61 | register: result 62 | until: result is not failed 63 | 64 | - name: wait-for install-complete 65 | command: "/root/bin/openshift-install --dir={{ files.kvm }}/bare-metal wait-for install-complete" 66 | async: 3600 67 | poll: 0 68 | register: install_complete_sleeper 69 | 70 | - name: 'install-complete - check on async task' 71 | async_status: 72 | jid: "{{ install_complete_sleeper.ansible_job_id }}" 73 | register: job_result 74 | until: job_result.finished 75 | retries: 1200 76 | delay: 30 77 | 78 | - name: remove bootstrap 79 | shell: | 80 | virsh destroy {{ item.name }} 81 | virsh undefine --remove-all-storage {{ item.name }} 82 | when: 83 | - keep_bootstrap == false 84 | with_items: "{{ bootstrap }}" 85 | 86 | - name: check kubeadmin-password 87 | slurp: 88 | src: "{{ files.kvm }}/bare-metal/auth/kubeadmin-password" 89 | register: kubeadmin_password 90 | 91 | - name: show kubeadmin-password 92 | debug: 93 | msg: "{{ kubeadmin_password.content | b64decode }}" 94 | -------------------------------------------------------------------------------- /tasks/kvm_host/cleanup-all.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: start libvirt daemon 3 | service: 4 | name: libvirtd 5 | state: started 6 | 7 | - name: check if openshift nat already exists 8 | virt_net: 9 | command: list_nets 10 | register: all_nets 11 | 12 | - name: destroy old openshift nat 13 | virt_net: 14 | command: destroy 15 | name: openshift 16 | when: "'openshift' in all_nets.list_nets" 17 | 18 | - name: undefine old openshift nat 19 | virt_net: 20 | command: undefine 21 | name: openshift 22 | when: "'openshift' in all_nets.list_nets" 23 | 24 | - name: check if vms already exists 25 | virt: 26 | command: list_vms 27 | register: all_vms 28 | 29 | - name: destroy old bootstrap 30 | shell: | 31 | virsh destroy {{ item.name }} 32 | virsh undefine --remove-all-storage {{ item.name }} 33 | when: 'item.name in all_vms.list_vms' 34 | with_items: "{{ bootstrap }}" 35 | 36 | - name: destroy old master 37 | shell: | 38 | virsh destroy {{ item.name }} 39 | virsh undefine --remove-all-storage {{ item.name }} 40 | when: 'item.name in all_vms.list_vms' 41 | with_items: "{{ master }}" 42 | 43 | - name: destroy old worker 44 | shell: | 45 | virsh destroy {{ item.name }} 46 | virsh undefine --remove-all-storage {{ item.name }} 47 | when: 'item.name in all_vms.list_vms' 48 | with_items: "{{ worker }}" 49 | 50 | - name: stop libvirt daemon 51 | service: 52 | name: libvirtd 53 | state: stopped 54 | 55 | - name: stop dnsmasq daemon 56 | service: 57 | name: dnsmasq 58 | state: stopped 59 | 60 | - name: stop nginx daemon 61 | service: 62 | name: nginx 63 | state: stopped 64 | 65 | - name: check old working dir 66 | stat: 67 | path: "{{ files.kvm }}" 68 | register: chk_file 69 | 70 | - name: remove old working dir 71 | file: 72 | path: "{{ files.kvm }}" 73 | state: absent 74 | when: 75 | - chk_file.stat.exists == true 76 | - cleanup.conf == true 77 | 78 | - name: check old hosts.openshift for dnsmasq 79 | stat: 80 | path: "/etc/hosts.openshift" 81 | register: chk_file 82 | 83 | - name: remove old /etc/hosts.openshift for dnsmasq 84 | file: 85 | path: /etc/hosts.openshift 86 | state: absent 87 | when: 88 | - chk_file.stat.exists == true 89 | - cleanup.conf == true 90 | 91 | - name: check old dnsmasq.d/openshift.conf 92 | stat: 93 | path: "/etc/dnsmasq.d/openshift.conf" 94 | register: chk_file 95 | 96 | - name: remove old dnsmasq.d/openshift.conf 97 | file: 98 | path: /etc/dnsmasq.d/openshift.conf 99 | state: absent 100 | when: 101 | - chk_file.stat.exists == true 102 | - cleanup.conf == true 103 | 104 | # want fix: maybe we need Implementation of file stat before deletion 105 | - name: remove old nginx dir 106 | file: 107 | path: "/usr/share/nginx/html/{{ item }}" 108 | state: absent 109 | with_items: 110 | - ipxe 111 | - openshift 112 | when: 113 | - cleanup.bin == true 114 | ignore_errors: yes 115 | 116 | # want fix: maybe we need Implementation of file stat before deletion 117 | - name: remove old clients 118 | file: 119 | path: "/root/bin/{{ item }}" 120 | state: absent 121 | with_items: 122 | - kubectl 123 | - oc 124 | - openshift-install 125 | when: 126 | - cleanup.bin == true 127 | ignore_errors: yes 128 | -------------------------------------------------------------------------------- /templates/nginx/nginx_conf.j2: -------------------------------------------------------------------------------- 1 | # nginx 2 | user nginx; 3 | worker_processes auto; 4 | error_log /var/log/nginx/error.log; 5 | pid /run/nginx.pid; 6 | 7 | include /usr/share/nginx/modules/*.conf; 8 | 9 | events { 10 | worker_connections 1024; 11 | } 12 | 13 | stream { 14 | log_format basic '$remote_addr [$time_local] ' 15 | '$protocol $status $bytes_sent $bytes_received ' 16 | '$session_time "$upstream_addr" ' 17 | '"$upstream_bytes_sent" "$upstream_bytes_received" "$upstream_connect_time"'; 18 | 19 | upstream apib { 20 | least_conn; 21 | server {{ bootstrap.0.name}}.{{ net.subdomain }}.{{ net.domain }}:6443; 22 | {% for m in master %} 23 | server {{ m.name}}.{{ net.subdomain }}.{{ net.domain }}:6443; 24 | {% endfor %} 25 | } 26 | 27 | server { 28 | listen 6443; 29 | proxy_pass apib; 30 | proxy_next_upstream on; 31 | proxy_timeout 30s; 32 | proxy_responses 1; 33 | error_log /var/log/nginx/stream_apib.log warn; 34 | } 35 | 36 | upstream configureb { 37 | least_conn; 38 | server {{ bootstrap.0.name}}.{{ net.subdomain }}.{{ net.domain }}:22623; 39 | {% for m in master %} 40 | server {{ m.name}}.{{ net.subdomain }}.{{ net.domain }}:22623; 41 | {% endfor %} 42 | } 43 | 44 | server { 45 | listen 22623; 46 | proxy_pass configureb; 47 | proxy_next_upstream on; 48 | error_log /var/log/nginx/stream_configureb.log warn; 49 | } 50 | upstream ingressnosslb { 51 | least_conn; 52 | {% for m in master %} 53 | server {{ m.name}}.{{ net.subdomain }}.{{ net.domain }}:80; 54 | {% endfor %} 55 | {% for w in worker %} 56 | server {{ w.name}}.{{ net.subdomain }}.{{ net.domain }}:80; 57 | {% endfor %} 58 | } 59 | 60 | server { 61 | listen 80; 62 | proxy_pass ingressnosslb; 63 | proxy_next_upstream on; 64 | proxy_timeout 30s; 65 | proxy_responses 1; 66 | error_log /var/log/nginx/stream_ingressnosslb.log warn; 67 | } 68 | 69 | upstream ingresssslb { 70 | least_conn; 71 | {% for m in master %} 72 | server {{ m.name}}.{{ net.subdomain }}.{{ net.domain }}:443; 73 | {% endfor %} 74 | {% for w in worker %} 75 | server {{ w.name}}.{{ net.subdomain }}.{{ net.domain }}:443; 76 | {% endfor %} 77 | } 78 | 79 | server { 80 | listen 443; 81 | proxy_pass ingresssslb; 82 | proxy_next_upstream on; 83 | proxy_timeout 30s; 84 | proxy_responses 1; 85 | error_log /var/log/nginx/stream_ingresssslb.log warn; 86 | } 87 | } 88 | 89 | http { 90 | log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 91 | '$status $body_bytes_sent "$http_referer" ' 92 | '"$http_user_agent" "$http_x_forwarded_for"'; 93 | 94 | access_log /var/log/nginx/access.log main; 95 | 96 | sendfile on; 97 | tcp_nopush on; 98 | tcp_nodelay on; 99 | keepalive_timeout 65; 100 | types_hash_max_size 2048; 101 | 102 | include /etc/nginx/mime.types; 103 | default_type application/octet-stream; 104 | 105 | include /etc/nginx/conf.d/*.conf; 106 | 107 | server { 108 | listen 8000 default_server; 109 | listen [::]:8000 default_server; 110 | server_name _; 111 | root /usr/share/nginx/html; 112 | 113 | include /etc/nginx/default.d/*.conf; 114 | 115 | location / { 116 | } 117 | 118 | error_page 404 /404.html; 119 | location = /40x.html { 120 | } 121 | 122 | error_page 500 502 503 504 /50x.html; 123 | location = /50x.html { 124 | } 125 | } 126 | } 127 | 128 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # openshift-ansible-kvm 2 | 3 | This repository contains Ansible playbooks for UPI installation of OpenShift 4 on KVM. 4 | 5 | It supports both [OpenShift Container Platform 4(OCP4)](https://www.openshift.com/) and [OKD 4](https://www.okd.io/) deployments. 6 | 7 | Note: This configuration is for disposable test and does not support production use. 8 | 9 | ## Requirements 10 | 11 | - Workstation (or call it base node, control node...), The machine that runs Ansible. It is typically your laptop. 12 | - Tested on Fedora 13 | - Ansible >= 2.11 14 | - This node **is not** mandatory. You can run the script on a single KVM host if you want. 15 | - KVM host 16 | - RHEL >= 8.2 17 | - CPU with at least 4 cores 18 | - Memory with at least 80 GB 19 | - It will work with about 64 GB with memory overcommit, but we don't recommend it. 20 | - Check [resource requirements](https://access.redhat.com/documentation/en-us/openshift_container_platform/4.5/html/installing_on_bare_metal/installing-on-bare-metal#installation-requirements-user-infra_installing-bare-metal) for more details. 21 | 22 | ## Architecture 23 | 24 | ![openshift-ansible-kvm-architecture](docs/assets/openshift-ansible-kvm-architecture.png) 25 | 26 | It can also be run with just the KVM host, without the workstation. (In that case, install Ansible on the KVM host) 27 | 28 | ## Quickstart 29 | 30 | ### Install ansible(and/or ansible-core) on your Workstation 31 | 32 | ```bash 33 | $ sudo dnf install -y ansible 34 | ``` 35 | 36 | ### Prepare KVM host 37 | 38 | - Just install RHEL8 39 | - Add ssh public key of the workstation to kvm host root user's `.ssh/authorized_keys` 40 | 41 | ### Make your settings 42 | 43 | Create your settings based on the samples. 44 | At least change the following settings are **required** . 45 | 46 | - `vars/config.yml` 47 | - `kvm_host:` 48 | - `ip:` Your KVM host IP 49 | - `if:` Your KVM host IF name (e.g. `enp2s0f0` ) 50 | - `openshift:` 51 | - `dist:` Select the distribution to deploy `ocp` or `okd` 52 | - `install_version:` openshift-install and openshift-client version 53 | - `coreos_version:` CoreOS version 54 | - `okd_*_sha256:` (okd only) FOCS does not provide sha256sum.txt, so you have to check and input it yourself from [the official website](https://getfedora.org/en/coreos/download?tab=metal_virtualized&stream=stable). 55 | - `key:` 56 | - `pullsecret` : Get form [cloud.redhat.com](https://cloud.redhat.com/openshift/install/metal/user-provisioned) 57 | - `sshkey` : Your ssh pub key 58 | - `inventory/hosts` 59 | - `[kvm_host]` : Your KVM host IP (or localhost) 60 | 61 | ```bash 62 | $ cp vars/config.yml.sample vars/config.yml 63 | $ cp inventory/hosts.sample inventory/hosts 64 | ``` 65 | 66 | ### Run 67 | 68 | ```bash 69 | $ ansible-playbook ./main.yml 70 | ``` 71 | 72 | ## FAQ 73 | 74 | ### How do I connect to the OCP web console from the workstation? 75 | 76 | You cannot access directly to NAT network of libvirtd from your workstation. 77 | But you can access it using ssh port forwarding and socks5, for example. 78 | 79 | ``` 80 | [user@workstation] $ ssh root@KVM-HOST -ND 127.0.0.1:8888 81 | ``` 82 | 83 | Then add `127.0.0.1:8888` (socks5) to your browser's Proxy and access `https://console-openshift-console.apps.test.lab.local`. 84 | Depending on your browser, you may need to enable the RemoteDNS option. 85 | 86 | Other ways, you can use [sshuttle](https://fedoramagazine.org/use-sshuttle-to-build-a-poor-mans-vpn/). 87 | 88 | ### Something is wrong? - clean up environment 89 | 90 | ```bash 91 | $ ansible-playbook ./03_cleanup.yml 92 | ``` 93 | 94 | ### Missing some Ansible modules 95 | 96 | If you use `ansible-core`, you may be missing some modules. In that case, please install the missing modules. 97 | 98 | ```bash 99 | $ ansible-galaxy collection install ansible.posix 100 | $ ansible-galaxy collection install community.general 101 | $ ansible-galaxy collection install community.libvirt 102 | ``` 103 | 104 | ## Special Thanks 105 | 106 | This project started with inspiration from openshift-fast-install. ( [the original version](https://github.com/konono/openshift-fast-install) and [the forked version](https://github.com/masaki-furuta/openshift-fast-install) ) 107 | -------------------------------------------------------------------------------- /vars/download.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # version e.g. 3 | # openshift.install_version = 4.4.11 4 | # openshift.coreos_version = 4.4.3 5 | # version.minor = 4.4 6 | version: 7 | minor: "{{ openshift.coreos_version | regex_replace('^(\\d*\\.\\d*)\\.\\d*','\\1') }}" 8 | 9 | # Download path 10 | files: 11 | base: "files/{{ openshift.dist }}/{{ openshift.install_version }}" 12 | kvm: "/root/openshift-ansible-kvm" 13 | 14 | # Download URLs 15 | # kernel 16 | # for 4.2: rhcos-{{ openshift.coreos_version }}-x86_64-installer-kernel 17 | # for 4.3-4.4.3: rhcos-{{ openshift.coreos_version }}-x86_64-installer-kernel-x86_64 18 | # for 4.4.17-4.5: rhcos-x86_64-installer-kernel-x86_64 19 | # for 4.6-4.18: rhcos-x86_64-live-kernel-x86_64 20 | # for 4.19: rhcos-x86_64-live-kernel.x86_64 21 | # for okd: fedora-coreos-{{ openshift.coreos_version }}-live-kernel-x86_64 22 | # initramfs 23 | # for 4.2: rhcos-{{ openshift.coreos_version }}-x86_64-installer-initramfs.img 24 | # for 4.3-4.4.3: rhcos-{{ openshift.coreos_version }}-x86_64-installer-initramfs.x86_64.img 25 | # for 4.4.17-4.5: rhcos-installer-initramfs.x86_64.img 26 | # for 4.6-4.19: rhcos-live-initramfs.x86_64.img 27 | # for okd: fedora-coreos-{{ openshift.coreos_version }}-live-initramfs.x86_64.img 28 | # bios 29 | # for 4.2: rhcos-{{ openshift.coreos_version }}-x86_64-metal-bios.raw.gz 30 | # for 4.3-4.4.3: rhcos-{{ openshift.coreos_version }}-x86_64-metal.x86_64.raw.gz 31 | # for 4.4.17-4.19: rhcos-metal.x86_64.raw.gz 32 | # for okd: fedora-coreos-{{ openshift.coreos_version }}-metal.x86_64.raw.xz 33 | config: 34 | coreos_kernel: >- 35 | {%- if openshift.dist == 'okd' -%} fedora-coreos-{{ openshift.coreos_version }}-live-kernel-x86_64 36 | {%- elif openshift.coreos_version | regex_search("^4\.19\.") -%} rhcos-live-kernel.x86_64 37 | {%- elif openshift.coreos_version | regex_search("^4\.1([0-8])\.") -%} rhcos-live-kernel-x86_64 38 | {%- elif openshift.coreos_version | regex_search("^4\.2\.") -%} rhcos-{{ openshift.coreos_version }}-x86_64-installer-kernel 39 | {%- elif openshift.coreos_version | regex_search("^4\.3\.") -%} rhcos-{{ openshift.coreos_version }}-x86_64-installer-kernel-x86_64 40 | {%- elif openshift.coreos_version | regex_search("^4\.4\.3") -%} rhcos-{{ openshift.coreos_version }}-x86_64-installer-kernel-x86_64 41 | {%- elif openshift.coreos_version | regex_search("^4\.+([4-5])\.") -%} rhcos-installer-kernel-x86_64 42 | {%- elif openshift.coreos_version | regex_search("^4\.+([6-9])\.") -%} rhcos-live-kernel-x86_64 43 | {%- else -%} rhcos-{{ openshift.coreos_version }}-x86_64-installer-kernel-x86_64 44 | {%- endif -%} 45 | coreos_initramfs: >- 46 | {%- if openshift.dist == 'okd' -%} fedora-coreos-{{ openshift.coreos_version }}-live-initramfs.x86_64.img 47 | {%- elif openshift.coreos_version | regex_search("^4\.1([0-9])\.") -%} rhcos-live-initramfs.x86_64.img 48 | {%- elif openshift.coreos_version | regex_search("^4\.2\.") -%} rhcos-{{ openshift.coreos_version }}-x86_64-installer-initramfs.img 49 | {%- elif openshift.coreos_version | regex_search("^4\.3\.") -%} rhcos-{{ openshift.coreos_version }}-x86_64-installer-initramfs.x86_64.img 50 | {%- elif openshift.coreos_version | regex_search("^4\.4\.3") -%} rhcos-{{ openshift.coreos_version }}-x86_64-installer-initramfs.x86_64.img 51 | {%- elif openshift.coreos_version | regex_search("^4\.+([4-5])\.") -%} rhcos-installer-initramfs.x86_64.img 52 | {%- elif openshift.coreos_version | regex_search("^4\.+([6-9])\.") -%} rhcos-live-initramfs.x86_64.img 53 | {%- else -%} rhcos-{{ openshift.coreos_version }}-x86_64-installer-initramfs.x86_64.img 54 | {%- endif -%} 55 | coreos_bios: >- 56 | {%- if openshift.dist == 'okd' -%} fedora-coreos-{{ openshift.coreos_version }}-metal.x86_64.raw.xz 57 | {%- elif openshift.coreos_version | regex_search("^4\.1([0-9])\.") -%} rhcos-metal.x86_64.raw.gz 58 | {%- elif openshift.coreos_version | regex_search("^4\.2\.") -%} rhcos-{{ openshift.coreos_version }}-x86_64-metal-bios.raw.gz 59 | {%- elif openshift.coreos_version | regex_search("^4\.3\.") -%} rhcos-{{ openshift.coreos_version }}-x86_64-metal.x86_64.raw.gz 60 | {%- elif openshift.coreos_version | regex_search("^4\.4\.3") -%} rhcos-{{ openshift.coreos_version }}-x86_64-metal.x86_64.raw.gz 61 | {%- elif openshift.coreos_version | regex_search("^4\.+([4-5])\.") -%} rhcos-metal.x86_64.raw.gz 62 | {%- elif openshift.coreos_version | regex_search("^4\.+([6-9])\.") -%} rhcos-metal.x86_64.raw.gz 63 | {%- else -%} rhcos-{{ openshift.coreos_version }}-x86_64-metal.x86_64.raw.gz 64 | {%- endif -%} 65 | coreos_rootfs: >- 66 | {%- if openshift.coreos_version | regex_search("^4\.1([0-9])\.") -%} rhcos-live-rootfs.x86_64.img 67 | {%- elif openshift.coreos_version | regex_search("^4\.+([6-9])\.") -%} rhcos-live-rootfs.x86_64.img 68 | {%- else -%} rhcos-{{ openshift.coreos_version }}-x86_64-live-rootfs.x86_64.img 69 | {%- endif -%} 70 | 71 | openshift_installer: "openshift-install-linux-{{ openshift.install_version }}.tar.gz" 72 | openshift_client: "openshift-client-linux-{{ openshift.install_version }}.tar.gz" 73 | 74 | static: 75 | coreos_base_url: >- 76 | {%- if openshift.dist == 'okd' -%} https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/{{ openshift.coreos_version }}/x86_64 77 | {%- elif openshift.dist == 'pre-release' -%} https://mirror.openshift.com/pub/openshift-v4/dependencies/rhcos/pre-release/{{ openshift.coreos_version }} 78 | {%- elif openshift.dist == 'ocp' -%} https://mirror.openshift.com/pub/openshift-v4/dependencies/rhcos/{{ version.minor }}/{{ openshift.coreos_version }} 79 | {%- else -%} https://mirror.openshift.com/pub/openshift-v4/dependencies/rhcos/{{ version.minor }}/{{ openshift.coreos_version }} 80 | {%- endif -%} 81 | clients_base_url: >- 82 | {%- if openshift.dist == 'okd' -%} https://github.com/openshift/okd/releases/download/{{ openshift.install_version }} 83 | {%- elif openshift.dist == 'ocp' -%} https://mirror.openshift.com/pub/openshift-v4/clients/ocp/{{ openshift.install_version }} 84 | {%- else -%} https://mirror.openshift.com/pub/openshift-v4/clients/ocp/{{ openshift.install_version }} 85 | {%- endif -%} 86 | 87 | url: 88 | coreos_kernel_url: "{{ static.coreos_base_url }}/{{ config.coreos_kernel }}" 89 | coreos_initramfs_url: "{{ static.coreos_base_url }}/{{ config.coreos_initramfs }}" 90 | coreos_bios_url: "{{ static.coreos_base_url }}/{{ config.coreos_bios }}" 91 | coreos_rootfs_url: "{{ static.coreos_base_url }}/{{ config.coreos_rootfs }}" 92 | openshift_installer_url: "{{ static.clients_base_url }}/{{ config.openshift_installer }}" 93 | openshift_client_url: "{{ static.clients_base_url }}/{{ config.openshift_client }}" 94 | sha256_kernel_url: >- 95 | {%- if openshift.dist == 'okd' -%} {{ openshift.okd_kenrel_sha256 }} 96 | {%- elif openshift.dist == 'ocp' -%} {{ static.coreos_base_url }}/sha256sum.txt 97 | {%- else -%} {{ static.coreos_base_url }}/sha256sum.txt 98 | {%- endif -%} 99 | sha256_initramfs_url: >- 100 | {%- if openshift.dist == 'okd' -%} {{ openshift.okd_initramfs_sha256 }} 101 | {%- elif openshift.dist == 'ocp' -%} {{ static.coreos_base_url }}/sha256sum.txt 102 | {%- else -%} {{ static.coreos_base_url }}/sha256sum.txt 103 | {%- endif -%} 104 | sha256_bios_url: >- 105 | {%- if openshift.dist == 'okd' -%} {{ openshift.okd_raw_sha256 }} 106 | {%- elif openshift.dist == 'ocp' -%} {{ static.coreos_base_url }}/sha256sum.txt 107 | {%- else -%} {{ static.coreos_base_url }}/sha256sum.txt 108 | {%- endif -%} 109 | sha256_rootfs_url: >- 110 | {%- if openshift.dist == 'okd' -%} {{ openshift.okd_rootfs_sha256 }} 111 | {%- elif openshift.dist == 'ocp' -%} {{ static.coreos_base_url }}/sha256sum.txt 112 | {%- else -%} {{ static.coreos_base_url }}/sha256sum.txt 113 | {%- endif -%} 114 | sha256_client_url: "{{ static.clients_base_url }}/sha256sum.txt" 115 | 116 | 117 | # DNS hack for libvirt 118 | # Hack for internet connection issues with tricky DNS provided by libvirt+dnsmasq 119 | ext_dns: 120 | - domain: "openshift.com" 121 | addr: "8.8.8.8" 122 | - domain: "quay.io" 123 | addr: "8.8.8.8" 124 | - domain: "redhat.com" 125 | addr: "8.8.8.8" 126 | - domain: "redhat.io" 127 | addr: "8.8.8.8" 128 | - domain: "amazonaws.com" 129 | addr: "8.8.8.8" 130 | - domain: "docker.io" 131 | addr: "8.8.8.8" 132 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2020 Kazuhisa Hara 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | --------------------------------------------------------------------------------