Skip to content

Instantly share code, notes, and snippets.

@leifmadsen
Last active November 7, 2022 14:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save leifmadsen/93b9283d10dfddba096e32fb172cf569 to your computer and use it in GitHub Desktop.
Save leifmadsen/93b9283d10dfddba096e32fb172cf569 to your computer and use it in GitHub Desktop.
Zuul From Scratch

Login to your environment

We're going to be using Fedora 26 for this installation. Since we'll be using a cloud image for Fedora 26, our login user will be fedora which will also be the staging user for installation of Zuul and Nodepool.

To get started, ssh to your machine as the fedora user:

ssh fedora@<floating_ip>

Environment Setup

sudo dnf update -y
sudo systemctl reboot
sudo dnf install git redhat-lsb-core -y

Python Dependencies

sudo yum install python3 python3-pip python3-devel -y
sudo yum install make gcc openssl-devel -y
pip3 install --user bindep

Installation

Zookeeper Install

sudo dnf install zookeeper -y

Nodepool install

sudo adduser nodepool
git clone https://git.openstack.org/openstack-infra/nodepool
cd nodepool/
git checkout feature/zuulv3   # TODO: delete this step after merge back to master
sudo dnf -y install $(bindep -b)    
sudo pip3 install .

Zuul Installation

sudo adduser zuul
git clone https://git.openstack.org/openstack-infra/zuul
cd zuul/
git checkout feature/zuulv3    # TODO: delete this upon merge to master
sudo dnf install $(bindep -b) -y
sudo pip3 install git+https://github.com/sigmavirus24/github3.py.git@develop#egg=Github3.py
sudo pip3 install .

Setup

Zookeeper Setup

sudo bash -c 'echo "1" > /etc/zookeeper/myid'
sudo bash -c 'echo "tickTime=2000
dataDir=/var/lib/zookeeper
clientPort=2181" > /etc/zookeeper/zoo.cfg'

Nodepool Setup

sudo mkdir /etc/nodepool/

sudo touch /etc/nodepool/secure.conf
sudo chown nodepool.nodepool /etc/nodepool/secure.conf

# Inputs needed for this file:
    # cloud name / region name - from clouds.yaml
    # flavor-name
    # image-name - from your cloud
sudo bash -c "cat >/etc/nodepool/nodepool.yaml <<EOF
zookeeper-servers:
  - host: localhost
    port: 2181

providers:
  - name: myprovider # this is a nodepool identifier for this cloud provider (cloud+region combo)
    region-name: regionOne  # this needs to match the region name in clouds.yaml but is only needed if there is more than one region
    cloud: mycloud  # This needs to match the name in clouds.yaml
    cloud-images:
      - name: centos-7   # Defines a cloud-image for nodepool
        image-name: CentOS-7-x86_64-GenericCloud-1706  # name of image from cloud
    pools:
      - name: main
        max-servers: 4  # quota - nodepool will never create more than this many
        labels:
          - name: centos-7-small  # defines label that will be used to get one of these in a job
            flavor-name: 'm1.small'  # name of flavor from cloud
            cloud-image: centos-7  # matches name from cloud-images
            key-name: nodepool # name of the keypair to use for authentication

labels:
  - name: centos-7-small # defines label that will be used in jobs
    min-ready: 2  # nodepool will always keep this many booted and ready to go
EOF"

WARNING!!! min-ready:2 may incur costs in your cloud provider

Nodepool logging

sudo mkdir /var/log/nodepool
sudo chgrp -R nodepool /var/log/nodepool/
sudo chmod 775 /var/log/nodepool/
sudo bash -c "cat > /etc/nodepool/logging.conf <<EOF
[loggers]
keys=root,nodepool,requests

[handlers]
keys=console,debug,normal

[formatters]
keys=simple

[logger_root]
level=WARNING
handlers=console

[logger_requests]
level=WARNING
handlers=debug,normal
qualname=requests

[logger_nodepool]
level=DEBUG
handlers=debug,normal
qualname=nodepool

[handler_console]
level=WARNING
class=StreamHandler
formatter=simple
args=(sys.stdout,)

[handler_debug]
level=DEBUG
class=logging.handlers.TimedRotatingFileHandler
formatter=simple
args=('/var/log/nodepool/debug.log', 'H', 8, 30,)

[handler_normal]
level=INFO
class=logging.handlers.TimedRotatingFileHandler
formatter=simple
args=('/var/log/nodepool/nodepool.log', 'H', 8, 30,)

[formatter_simple]
format=%(asctime)s %(levelname)s %(name)s: %(message)s
datefmt=
EOF"

clouds.yaml configuration and setup

Before starting on this, you need to download your openrc configuration from your OpenStack cloud.

cd ~
source <username>-openrc.sh # this will prompt for password - enter it
sudo mkdir -p /home/nodepool/.config/openstack
cat > /tmp/clouds.yaml <<EOF
clouds:
  mycloud:
      auth:
        username: $OS_USERNAME
        password: $OS_PASSSWORD
        project_name: $OS_PROJECT_NAME
        auth_url: $OS_AUTH_URL
      region_name: $OS_REGION_NAME
EOF
sudo mv /tmp/clouds.yaml /home/nodepool/.config/openstack/
sudo chown -R nodepool.nodepool /home/nodepool/.config

Once you've written out the file, double check all the required fields have been filled out.

Zuul Setup

sudo mkdir /etc/zuul/
sudo mkdir /var/lib/zuul/
sudo chown -R zuul.zuul /var/lib/zuul
sudo mkdir /var/log/zuul/
sudo chown zuul.zuul /var/log/zuul/

Zuul Configuration

sudo bash -c "cat > /etc/zuul/zuul.conf <<EOF
[gearman]
server=127.0.0.1

[gearman_server]
start=true

[executor]
private_key_file=/home/zuul/.ssh/nodepool.key
default_username=centos
log_config=/etc/zuul/logging.conf
finger_port=17979

[scheduler]
tenant_config=/etc/zuul/main.yaml
log_config=/etc/zuul/logging.conf
EOF"

sudo bash -c "cat > /etc/zuul/main.yaml <<EOF
- tenant:
    name: quickstart
EOF"

Zuul Logging

sudo bash -c "cat > /etc/zuul/logging.conf <<EOF
[loggers]
keys=root,zuul,gerrit

[handlers]
keys=console,debug,normal

[formatters]
keys=simple

[logger_root]
level=WARNING
handlers=console

[logger_zuul]
level=DEBUG
handlers=debug,normal
qualname=zuul

[logger_gerrit]
level=DEBUG
handlers=debug,normal
qualname=gerrit

[handler_console]
level=WARNING
class=StreamHandler
formatter=simple
args=(sys.stdout,)

[handler_debug]
level=DEBUG
class=logging.handlers.TimedRotatingFileHandler
formatter=simple
args=('/var/log/zuul/debug.log', 'midnight', 1, 30,)

[handler_normal]
level=INFO
class=logging.handlers.TimedRotatingFileHandler
formatter=simple
args=('/var/log/zuul/zuul.log', 'midnight', 1, 30,)

[formatter_simple]
format=%(asctime)s %(levelname)s %(name)s: %(message)s
datefmt=
EOF"

Service Management

Zookeeper Service Management

sudo systemctl start zookeeper.service

sudo systemctl status zookeeper.service
● zookeeper.service - Apache ZooKeeper
   Loaded: loaded (/usr/lib/systemd/system/zookeeper.service; disabled; vendor preset: disabled)
   Active: active (running) since Wed 2018-01-03 14:53:47 UTC; 5s ago
  Process: 4153 ExecStart=/usr/bin/zkServer.sh start zoo.cfg (code=exited, status=0/SUCCESS)
 Main PID: 4160 (java)
    Tasks: 17 (limit: 4915)
   CGroup: /system.slice/zookeeper.service
           └─4160 java -Dzookeeper.log.dir=/var/log/zookeeper -Dzookeeper.root.logger=INFO,CONSOLE -cp /usr/share/java/

Jan 03 14:53:46 zuul-qs-docs.rdocloud systemd[1]: Starting Apache ZooKeeper...
Jan 03 14:53:46 zuul-qs-docs.rdocloud zookeeper[4153]: ZooKeeper JMX enabled by default
Jan 03 14:53:46 zuul-qs-docs.rdocloud zookeeper[4153]: Using config: /etc/zookeeper/zoo.cfg
Jan 03 14:53:47 zuul-qs-docs.rdocloud zookeeper[4153]: Starting zookeeper ... STARTED
Jan 03 14:53:47 zuul-qs-docs.rdocloud systemd[1]: Started Apache ZooKeeper.
sudo systemctl enable zookeeper.service

Nodepool Service Management

sudo bash -c "cat > /etc/systemd/system/nodepool-launcher.service <<EOF
[Unit]
Description=Nodepool Launcher Service
After=syslog.target network.target

[Service]
Type=simple
# Options to pass to nodepool-launcher.
Group=nodepool
User=nodepool
RuntimeDirectory=nodepool
ExecStart=/usr/bin/nodepool-launcher -l /etc/nodepool/logging.conf

[Install]
WantedBy=multi-user.target
EOF"

sudo chmod 0644 /etc/systemd/system/nodepool-launcher.service
sudo systemctl daemon-reload
sudo systemctl start nodepool-launcher.service
sudo systemctl status nodepool-launcher.service
sudo systemctl enable nodepool-launcher.service

Zuul Service Management

sudo bash -c "cat > /etc/systemd/system/zuul-scheduler.service <<EOF
[Unit]
Description=Zuul Scheduler Service
After=syslog.target network.target

[Service]
Type=simple
Group=zuul
User=zuul
RuntimeDirectory=zuul
ExecStart=/usr/bin/zuul-scheduler
ExecStop=/usr/bin/zuul-scheduler stop

[Install]
WantedBy=multi-user.target
EOF"
sudo bash -c "cat > /etc/systemd/system/zuul-executor.service <<EOF
[Unit]
Description=Zuul Executor Service
After=syslog.target network.target

[Service]
Type=simple
Group=zuul
User=zuul
RuntimeDirectory=zuul
ExecStart=/usr/bin/zuul-executor
ExecStop=/usr/bin/zuul-executor stop

[Install]
WantedBy=multi-user.target
EOF"

sudo systemctl daemon-reload
sudo systemctl start zuul-scheduler.service
sudo systemctl status zuul-scheduler.service
sudo systemctl enable zuul-scheduler.service
sudo systemctl start zuul-executor.service
sudo systemctl status zuul-executor.service
sudo systemctl enable zuul-executor.service

Create Keypair

In your OpenStack instance, create a new keypair that can be used for instantiating the servers. You can do this in Horizon and then simply download the key onto your Zuul instance. In our nodepool.yaml configuration, we set the key-name value to nodepool. When creating your keypair, name them the same.

Once the keypair is created, you'll need to keep the private key safe. We'll eventually upload it to the Zuul instance, placing it in the /home/zuul/.ssh/nodepool.key location on the server.

TODO install shade and do this all from the console instead of telling someone to go to the web interface

Setup NoOp Job

TODO here is where we'll setup a base configuration using the gtest-org setup to pull in an example Zuul project configuration, that allows us to instantiate a job from the console. We'll also use the keep configuration so that we don't need to setup a full logging server at this time.

Firewall Setup

sudo firewall-cmd --permanent --add-port=80/tcp
sudo firewall-cmd --permanent --add-port=9000/tcp
sudo firewall-cmd --permanent --add-port=8001/tcp
sudo firewall-cmd --reload

Other

Github stuff

setup an app: https://developer.github.com/apps/building-integrations/setting-up-and-registering-github-apps/registering-github-apps/

homepage url: doesn't matter

user auth callback url http://IPADDR:8001/

http://IPADDR:8001/connection/github/payload

https://screenshots.firefox.com/FkHTNZFbA784ukSa/github.com https://screenshots.firefox.com/isar1xCFXNmlc0uR/github.com

[zuul@nfvpe-zuulv3 ~]$ ssh-keygen  

sudo bash -c "cat >> /etc/zuul/zuul.conf <<EOF
[connection github]
driver=github
app_id=<app_id>
app_key=/etc/zuul/github.key
webhook_token=<webhook_token>
EOF"

Phase 1: Zuul Pipeline Configuration

2 kinds of repos:

  • config projects
    • ones that are treated special, expected to be dedicated to zuul configuration
    • allowed to do things that would otherwise be insecure in other contexts
  • untrusted projects
    • anything else; real dev project; zuul jobs repo (for example)
  • zuul-qs-config/zuul.d/pipeline.yaml

Changes to main.yaml

- tenant:
    name: quickstart
    exclude-unprotected-branches: true
    source:
      github:
        config-projects:
          - leifmadsen/zuul-qs-config
        untrusted-projects:
          - leifmadsen/dummy-commits
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment