|
Server : Apache System : Linux server.mata-lashes.com 3.10.0-1160.90.1.el7.x86_64 #1 SMP Thu May 4 15:21:22 UTC 2023 x86_64 User : matalashes ( 1004) PHP Version : 8.1.29 Disable Function : NONE Directory : /usr/src/cloud-init/tests/integration_tests/modules/ |
Upload File : |
import pytest
from tests.integration_tests.integration_settings import PLATFORM
from tests.integration_tests.releases import CURRENT_RELEASE, FOCAL
from tests.integration_tests.util import verify_clean_log
# This works by setting up a local repository and web server
# daemon on the first boot. Second boot should succeed
# with the running web service and git repo configured.
# This instrumentation allows the test to run self-contained
# without network access or external git repos.
REPO_D = "/root/playbooks"
USER_DATA = """\
#cloud-config
version: v1
package_update: true
package_upgrade: true
packages:
- git
- python3-pip
write_files:
- path: /etc/systemd/system/repo_server.service
content: |
[Unit]
Description=Serve a local git repo
Wants=repo_waiter.service
After=cloud-init-local.service
Before=cloud-config.service
Before=cloud-final.service
[Install]
WantedBy=cloud-init-local.service
[Service]
WorkingDirectory=/root/playbooks/.git
ExecStart=/usr/bin/env python3 -m http.server --bind 0.0.0.0 8000
- path: /etc/systemd/system/repo_waiter.service
content: |
[Unit]
Description=Block boot until repo is available
After=repo_server.service
Before=cloud-final.service
[Install]
WantedBy=cloud-init-local.service
# clone into temp directory to test that server is running
# sdnotify would be an alternative way to verify that the server is
# running and continue once it is up, but this is simple and works
[Service]
Type=oneshot
ExecStart=/bin/sh -c "while \
! git clone http://0.0.0.0:8000/ $(mktemp -d); do sleep 0.1; done"
- path: /root/playbooks/ubuntu.yml
content: |
---
- hosts: 127.0.0.1
connection: local
become: true
vars:
packages:
- git
- python3-pip
roles:
- apt
- path: /root/playbooks/roles/apt/tasks/main.yml
content: |
---
- name: "install packages"
apt:
name: "*"
update_cache: yes
cache_valid_time: 3600
- name: "install packages"
apt:
name:
- "{{ item }}"
state: latest
loop: "{{ packages }}"
runcmd:
- [systemctl, enable, repo_server.service]
- [systemctl, enable, repo_waiter.service]
"""
INSTALL_METHOD = """
ansible:
ansible_config: /etc/ansible/ansible.cfg
install_method: {method}
package_name: {package}
galaxy:
actions:
- ["ansible-galaxy", "collection", "install", "community.grafana"]
pull:
url: "http://0.0.0.0:8000/"
playbook_name: ubuntu.yml
full: true
"""
SETUP_REPO = f"cd {REPO_D} &&\
git config --global user.name auto &&\
git config --global user.email autom@tic.io &&\
git config --global init.defaultBranch main &&\
git init {REPO_D} &&\
git add {REPO_D}/roles/apt/tasks/main.yml {REPO_D}/ubuntu.yml &&\
git commit -m auto &&\
(cd {REPO_D}/.git; git update-server-info)"
ANSIBLE_CONTROL = """\
#cloud-config
#
# Demonstrate setting up an ansible controller host on boot.
# This example installs a playbook repository from a remote private repository
# and then runs two of the plays.
package_update: true
package_upgrade: true
packages:
- git
- python3-pip
# Set up an ansible user
# ----------------------
# In this case I give the local ansible user passwordless sudo so that ansible
# may write to a local root-only file.
users:
- name: ansible
gecos: Ansible User
shell: /bin/bash
groups: users,admin,wheel,lxd
sudo: ALL=(ALL) NOPASSWD:ALL
# Initialize lxd using cloud-init.
# --------------------------------
# In this example, a lxd container is
# started using ansible on boot, so having lxd initialized is required.
lxd:
init:
storage_backend: dir
# Configure and run ansible on boot
# ---------------------------------
# Install ansible using pip, ensure that community.general collection is
# installed [1].
# Use a deploy key to clone a remote private repository then run two playbooks.
# The first playbook starts a lxd container and creates a new inventory file.
# The second playbook connects to and configures the container using ansible.
# The public version of the playbooks can be inspected here [2]
#
# [1] community.general is likely already installed by pip
# [2] https://github.com/holmanb/ansible-lxd-public
#
ansible:
install_method: pip
package_name: ansible
run_user: ansible
galaxy:
actions:
- ["ansible-galaxy", "collection", "install", "community.general"]
setup_controller:
repositories:
- path: /home/ansible/my-repo/
source: git@github.com:holmanb/ansible-lxd-private.git
run_ansible:
- playbook_dir: /home/ansible/my-repo
playbook_name: start-lxd.yml
timeout: 120
forks: 1
private_key: /home/ansible/.ssh/id_rsa
- playbook_dir: /home/ansible/my-repo
playbook_name: configure-lxd.yml
become_user: ansible
timeout: 120
forks: 1
private_key: /home/ansible/.ssh/id_rsa
inventory: new_ansible_hosts
# Write a deploy key to the filesystem for ansible.
# -------------------------------------------------
# This deploy key is tied to a private github repository [1]
# This key exists to demonstrate deploy key usage in ansible
# a duplicate public copy of the repository exists here[2]
#
# [1] https://github.com/holmanb/ansible-lxd-private
# [2] https://github.com/holmanb/ansible-lxd-public
#
write_files:
- path: /home/ansible/.ssh/known_hosts
owner: ansible:ansible
permissions: 0o600
defer: true
content: |
|1|YJEFAk6JjnXpUjUSLFiBQS55W9E=|OLNePOn3eBa1PWhBBmt5kXsbGM4= ssh-ed2551\
9 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl
- path: /home/ansible/.ssh/id_rsa
owner: ansible:ansible
permissions: 0o600
defer: true
encoding: base64
content: |
LS0tLS1CRUdJTiBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0KYjNCbGJuTnphQzFyWlhrdGRqRUFB
QUFBQkc1dmJtVUFBQUFFYm05dVpRQUFBQUFBQUFBQkFBQUJsd0FBQUFkemMyZ3RjbgpOaEFBQUFB
d0VBQVFBQUFZRUEwUWlRa05WQS9VTEpWZzBzT1Q4TEwyMnRGckg5YVR1SWFNT1FiVFdtWjlNUzJh
VTZ0cDZoClJDYklWSkhmOHdsaGV3MXNvWmphWVVQSFBsUHNISm5UVlhJTnFTTlpEOGF0Rldjd1gy
ZTNBOElZNEhpN0NMMDE3MVBoMVUKYmJGNGVIT1JaVkY2VVkzLzhmbXQ3NmhVYnpiRVhkUXhQdVdh
a0IyemxXNTdFclpOejJhYVdnY2pJUGdHV1RNZWVqbEpOcQpXUW9MNlFzSStpeUlzYXNMc1RTajha
aVgrT1VjanJEMUY4QXNKS3ZWQStKbnVZNUxFeno1TGQ2SGxGc05XVWtoZkJmOWVOClpxRnJCc1Vw
M2VUY1FtejFGaHFFWDJIQjNQT3VSTzlKemVGcTJaRE8wUlNQN09acjBMYm8vSFVTK3V5VkJNTDNi
eEF6dEIKQWM5dFJWZjRqcTJuRjNkcUpwVTFFaXZzR0sxaHJZc0VNQklLK0srVzRwc1F5c3ZTL0ZK
V2lXZmpqWVMwei9IbkV4MkpHbApOUXUrYkMxL1dXSGVXTGFvNGpSckRSZnNIVnVscTE2MElsbnNx
eGl1MmNHd081V29Fc1NHdThucXB5ZzQzWkhDYjBGd21CCml6UFFEQVNsbmlXanFjS21mblRycHpB
eTNlVldhd3dsTnBhUWtpZFRBQUFGZ0dLU2o4ZGlrby9IQUFBQUIzTnphQzF5YzIKRUFBQUdCQU5F
SWtKRFZRUDFDeVZZTkxEay9DeTl0clJheC9XazdpR2pEa0cwMXBtZlRFdG1sT3JhZW9VUW15RlNS
My9NSgpZWHNOYktHWTJtRkR4ejVUN0J5WjAxVnlEYWtqV1EvR3JSVm5NRjludHdQQ0dPQjR1d2k5
TmU5VDRkVkcyeGVIaHprV1ZSCmVsR04vL0g1cmUrb1ZHODJ4RjNVTVQ3bG1wQWRzNVZ1ZXhLMlRj
OW1tbG9ISXlENEJsa3pIbm81U1RhbGtLQytrTENQb3MKaUxHckM3RTBvL0dZbC9qbEhJNnc5UmZB
TENTcjFRUGlaN21PU3hNOCtTM2VoNVJiRFZsSklYd1gvWGpXYWhhd2JGS2QzawozRUpzOVJZYWhG
OWh3ZHp6cmtUdlNjM2hhdG1RenRFVWorem1hOUMyNlB4MUV2cnNsUVRDOTI4UU03UVFIUGJVVlgr
STZ0CnB4ZDNhaWFWTlJJcjdCaXRZYTJMQkRBU0N2aXZsdUtiRU1yTDB2eFNWb2xuNDQyRXRNL3g1
eE1kaVJwVFVMdm13dGYxbGgKM2xpMnFPSTBhdzBYN0IxYnBhdGV0Q0paN0tzWXJ0bkJzRHVWcUJM
RWhydko2cWNvT04yUndtOUJjSmdZc3owQXdFcFo0bApvNm5DcG41MDY2Y3dNdDNsVm1zTUpUYVdr
SkluVXdBQUFBTUJBQUVBQUFHQUV1ejc3SHU5RUVaeXVqTE9kVG5BVzlhZlJ2ClhET1pBNnBTN3lX
RXVmanc1Q1NsTUx3aXNSODN5d3cwOXQxUVd5dmhScUV5WW12T0JlY3NYZ2FTVXRuWWZmdFd6NDRh
cHkKL2dRWXZNVkVMR0thSkFDL3E3dmpNcEd5cnhVUGt5TE1oY2tBTFUyS1lnVisvcmovajZwQk1l
VmxjaG1rM3Bpa1lyZmZVWApKRFk5OTBXVk8xOTREbTBidUxSekp2Zk1LWUYyQmNmRjRUdmFyak9Y
V0F4U3VSOHd3dzA1MG9KOEhkS2FoVzdDbTVTMHBvCkZSbk5YRkdNbkxBNjJ2TjAwdkpXOFY3ajd2
dWk5dWtCYmhqUldhSnVZNXJkRy9VWW16QWU0d3ZkSUVucGs5eEluNkpHQ3AKRlJZVFJuN2xUaDUr
L1FsUTZGWFJQOElyMXZYWkZuaEt6bDBLOFZxaDJzZjRNNzlNc0lVR0FxR3hnOXhkaGpJYTVkbWdw
OApOMThJRURvTkVWS1ViS3VLZS9aNXlmOFo5dG1leGZIMVl0dGptWE1Pb2pCdlVISWpSUzVoZEk5
TnhuUEdSTFkya2pBemNtCmdWOVJ2M3Z0ZEYvK3phbGszZkFWTGVLOGhYSytkaS83WFR2WXBmSjJF
WkJXaU5yVGVhZ2ZOTkdpWXlkc1F5M3pqWkFBQUEKd0JOUmFrN1VycW5JSE1abjdwa0NUZ2NlYjFN
ZkJ5YUZ0bE56ZCtPYmFoNTRIWUlRajVXZFpUQkFJVFJlTVpOdDlTNU5BUgpNOHNRQjhVb1pQYVZT
QzNwcElMSU9mTGhzNktZajZSckdkaVl3eUloTVBKNWtSV0Y4eEdDTFVYNUNqd0gyRU9xN1hoSVd0
Ck13RUZ0ZC9nRjJEdTdIVU5GUHNaR256SjNlN3BES0RuRTd3MmtoWjhDSXBURmdENzY5dUJZR0F0
azQ1UVlURG81SnJvVk0KWlBEcTA4R2IvUmhJZ0pMbUlwTXd5cmVWcExMTGU4U3dvTUpKK3JpaG1u
Slp4TzhnQUFBTUVBMGxoaUtlemVUc2hodDR4dQpyV2MwTnh4RDg0YTI5Z1NHZlRwaERQT3JsS1NF
WWJrU1hoanFDc0FaSGQ4UzhrTXIzaUY2cG9PazNJV1N2Rko2bWJkM2llCnFkUlRnWEg5VGh3azRL
Z3BqVWhOc1F1WVJIQmJJNTlNbytCeFNJMUIxcXptSlNHZG1DQkw1NHd3elptRktEUVBRS1B4aUwK
bjBNbGM3R29vaURNalQxdGJ1Vy9PMUVMNUVxVFJxd2dXUFRLaEJBNnI0UG5HRjE1MGhaUklNb29a
a0Qyelg2YjFzR29qawpRcHZLa0V5a1R3bktDekY1VFhPOCt3SjNxYmNFbzlBQUFBd1FEK1owcjY4
YzJZTU5wc215ajNaS3RaTlBTdkpOY0xteUQvCmxXb05KcTNkakpONHMySmJLOGw1QVJVZFczeFNG
RURJOXl4L3dwZnNYb2FxV255Z1AzUG9GdzJDTTRpMEVpSml5dnJMRlUKcjNKTGZEVUZSeTNFSjI0
UnNxYmlnbUVzZ1FPelRsM3hmemVGUGZ4Rm9PaG9rU3ZURzg4UFFqaTFBWUh6NWtBN3A2WmZhegpP
azExckpZSWU3K2U5QjBsaGt1MEFGd0d5cWxXUW1TL01oSXBuakhJazV0UDRoZUhHU216S1FXSkRi
VHNrTldkNmFxMUc3CjZIV2ZEcFg0SGdvTThBQUFBTGFHOXNiV0Z1WWtCaGNtTT0KLS0tLS1FTkQg
T1BFTlNTSCBQUklWQVRFIEtFWS0tLS0tCg==
# Work around this bug [1] by dropping the second interface after it is no
# longer required
# [1] https://github.com/canonical/pycloudlib/issues/220
runcmd:
- [ip, link, delete, lxdbr0]
"""
def _test_ansible_pull_from_local_server(my_client):
setup = my_client.execute(SETUP_REPO)
assert not setup.stderr
assert not setup.return_code
my_client.execute("cloud-init clean --logs")
my_client.restart()
log = my_client.read_from_file("/var/log/cloud-init.log")
verify_clean_log(log)
output_log = my_client.read_from_file("/var/log/cloud-init-output.log")
assert "ok=3" in output_log
assert "SUCCESS: config-ansible ran successfully" in log
# binary location is dependent on install-type, check the filepath
# to ensure that the installed collection directory exists
output = my_client.execute(
"ls /root/.ansible/collections/ansible_collections/community/grafana"
)
assert not output.stderr.strip() and output.ok
# temporarily disable this test on jenkins until firewall rules are in place
@pytest.mark.adhoc
@pytest.mark.user_data(
USER_DATA + INSTALL_METHOD.format(package="ansible-core", method="pip")
)
def test_ansible_pull_pip(client):
_test_ansible_pull_from_local_server(client)
# temporarily disable this test on jenkins until firewall rules are in place
@pytest.mark.adhoc
# Ansible packaged in bionic is 2.5.1. This test relies on ansible collections,
# which requires Ansible 2.9+, so no bionic. The functionality is covered
# in `test_ansible_pull_pip` using pip rather than the bionic package.
@pytest.mark.skipif(
CURRENT_RELEASE < FOCAL, reason="Test requires Ansible 2.9+"
)
@pytest.mark.user_data(
USER_DATA + INSTALL_METHOD.format(package="ansible", method="distro")
)
def test_ansible_pull_distro(client):
_test_ansible_pull_from_local_server(client)
@pytest.mark.user_data(ANSIBLE_CONTROL)
@pytest.mark.skipif(
PLATFORM != "lxd_vm",
reason="Test requires starting LXD containers",
)
@pytest.mark.skipif(
CURRENT_RELEASE < FOCAL,
reason="Pip install is not supported for Ansible on release",
)
def test_ansible_controller(client):
log = client.read_from_file("/var/log/cloud-init.log")
verify_clean_log(log)
content_ansible = client.execute(
"lxc exec lxd-container-00 -- cat /home/ansible/ansible.txt"
)
content_root = client.execute(
"lxc exec lxd-container-00 -- cat /root/root.txt"
)
assert content_ansible == "hello as ansible"
assert content_root == "hello as root"