Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge in changes from version 1.7.3 #174

Merged
merged 20 commits into from
Mar 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions Dockerfile-centos-7
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@ FROM centos/systemd
ARG FPM_VERSION=1.11.0
ARG PYTHON_VERSION=3
ARG DOCKER_WORKDIR=/usr/share/pdagent
ARG SKIP_SYSTEMD=false
ENV PYTHON_VERSION ${PYTHON_VERSION}
ENV container docker
ENV DOCKER_WORKDIR ${DOCKER_WORKDIR}

# There is known issues with Docker + systemd
ENV SKIP_SYSTEMD ${SKIP_SYSTEMD}

RUN yum install -y -q centos-release-scl
RUN yum install -y -q createrepo
RUN yum install -y -q gcc
Expand All @@ -21,6 +25,15 @@ RUN yum install -y -q rh-ruby23
RUN yum install -y -q rh-ruby23-ruby-devel
RUN yum install -y -q sudo
RUN yum install -y -q which
RUN yum install -y -q initscripts

# Lock dotenv version to prevent ruby 3.0 requirement
RUN source /opt/rh/rh-ruby23/enable && \
/opt/rh/rh-ruby23/root/usr/bin/gem install -q --no-ri --no-rdoc -v 2.8.1 dotenv

# Lock ffi version to prevent ruby 2.5 requirement
RUN source /opt/rh/rh-ruby23/enable && \
/opt/rh/rh-ruby23/root/usr/bin/gem install -q --no-ri --no-rdoc -v 1.15.5 ffi

RUN source /opt/rh/rh-ruby23/enable && \
/opt/rh/rh-ruby23/root/usr/bin/gem install -q --no-ri --no-rdoc -v $FPM_VERSION fpm
Expand Down
12 changes: 12 additions & 0 deletions Dockerfile-ubuntu
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@ FROM ubuntu:${UBUNTU_VERSION}
ARG FPM_VERSION=1.11.0
ARG PYTHON_VERSION=3
ARG DOCKER_WORKDIR=/usr/share/pdagent
ARG SKIP_SYSTEMD=false

ENV PYTHON_VERSION ${PYTHON_VERSION}
ENV container docker
ENV DEBIAN_FRONTEND noninteractive
ENV DOCKER_WORKDIR ${DOCKER_WORKDIR}

# There is known issues with Docker + systemd
ENV SKIP_SYSTEMD ${SKIP_SYSTEMD}

RUN apt-get update -y -qq
RUN apt-get install -y -q apt-utils
RUN apt-get install -y -q build-essential
Expand All @@ -25,6 +30,13 @@ RUN rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

RUN update-ca-certificates


# Lock dotenv version to prevent ruby 3.0 requirement
RUN gem install -q --no-ri --no-rdoc -v 2.8.1 dotenv

# Lock ffi version to prevent ruby 2.5 requirement
RUN gem install -q --no-ri --no-rdoc -v 1.15.5 ffi

RUN gem install -q --no-ri --no-rdoc -v ${FPM_VERSION} fpm
RUN apt-get install -y -q python${PYTHON_VERSION}
RUN cd /lib/systemd/system/sysinit.target.wants/ \
Expand Down
3 changes: 1 addition & 2 deletions LICENSE.TXT
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
This project includes files that have a different license than the one below.
See each individual file for the license for that file.

Specifically, the folder `pdagent/thirdparty/` contains third-party code and
the file `pdagent/root_certs/ca_certs.pem` is derived from third-party code.
Specifically, the folder `pdagent/thirdparty/` contains third-party code.

All other files and any file that does not mention a license are licensed under
the terms below.
Expand Down
6 changes: 4 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ build-ubuntu:
--build-arg FPM_VERSION="${FPM_VERSION}" \
--build-arg PYTHON_VERSION="${PYTHON_VERSION}" \
--build-arg UBUNTU_VERSION="${UBUNTU_VERSION}" \
--build-arg DOCKER_WORKDIR="${DOCKER_WORKDIR}"
--build-arg DOCKER_WORKDIR="${DOCKER_WORKDIR}" \
--build-arg SKIP_SYSTEMD="${SKIP_SYSTEMD}"

.PHONY: build-centos
build-centos:
Expand All @@ -28,7 +29,8 @@ build-centos:
--build-arg FPM_VERSION="${FPM_VERSION}" \
--build-arg PYTHON_VERSION="${PYTHON_VERSION}" \
--build-arg CENTOS_VERSION="${CENTOS_VERSION}" \
--build-arg DOCKER_WORKDIR="${DOCKER_WORKDIR}"
--build-arg DOCKER_WORKDIR="${DOCKER_WORKDIR}" \
--build-arg SKIP_SYSTEMD="${SKIP_SYSTEMD}"

target/deb: build-ubuntu
docker run \
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ on a Mac.
You can run the Agent in development without any setup. Start the Agent daemon
as follows:

`bin/pdagentd.py`
`bin/pdagentd`

When run in development the daemon automatically creates a `tmp` directory
inside the project where it stores its various work files.
Expand All @@ -57,7 +57,9 @@ You can stop the daemon as follows:

#### With Docker

To run the Agent in a production-like environment, use Docker. We currently have two supported operating systems: Ubuntu 16.04 and CentOS 7. With Docker installed, run `./scripts/run-console.sh <ubuntu>` or `./scripts/run-console.sh <centos>` to spin up the Docker container, run the Agent, and drop into a console.
To run the Agent in a production-like environment, use Docker. A known issue with Docker is that it has trouble interacting with systemd. To run the agent in Docker, update `SKIP_SYSTEMD` to `true` in `./build-linux/make_common.env`.

We currently have two supported operating systems: Ubuntu 16.04 and CentOS 7. With Docker installed, run `./scripts/run-console.sh <ubuntu>` or `./scripts/run-console.sh <centos>` to spin up the Docker container, run the Agent, and drop into a console.

Once in the console, you can send events via `pd-send`.

Expand Down
157 changes: 8 additions & 149 deletions bin/pd-queue
Original file line number Diff line number Diff line change
@@ -1,151 +1,10 @@
#!/usr/bin/env python
#
# Python script to work on the local queue maintained by PagerDuty Agent.
#
# Copyright (c) 2013-2014, PagerDuty, Inc. <[email protected]>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the copyright holder nor the
# names of its contributors may be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
#!/bin/bash

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"

def build_queue_arg_parser(description):
from pdagent.thirdparty.argparse import ArgumentParser

parser = ArgumentParser(description=description)
subparsers = parser.add_subparsers(title="sub-commands")
retry_parser_desc = "set up 'dead' PagerDuty events for retry."
status_parser_desc = "print out status of local event queue."

retry_parser = subparsers.add_parser(
"retry",
description=retry_parser_desc.capitalize(), # printed as title
help=retry_parser_desc # printed in 'options' part of main cmd
)
retry_parser.add_argument(
"-k", "--service-key", dest="service_key",
help="retry events in given Service API Key (not to be used with -a)"
)
retry_parser.add_argument(
"-a", "--all-keys", action="store_true",
dest="all_keys",
help="retry events in all Service API Keys (not to be used with -k)"
)
retry_parser.set_defaults(func=_retry)

status_parser = subparsers.add_parser(
"status",
description=status_parser_desc.capitalize(), # printed as title
help=status_parser_desc # printed in 'options' part of main cmd
)
status_parser.add_argument(
"-k", "--service-key", dest="service_key",
help="print status of events in given Service API Key"
)
status_parser.set_defaults(func=_status)

return parser


def _retry(agent_config, parser, args):
from pdagent.pdagentutil import resurrect_events

# We explicitly require either a specific service key, or an indication that
# events of all service keys can be resurrected. We don't want to assume
# anything here.
if not args.service_key and not args.all_keys:
parser.error("A specific service key or a flag for all keys required")
elif args.service_key and args.all_keys:
parser.error(
"Only one of specific service key or flag for all keys required")
else:
count = resurrect_events(
agent_config.get_queue(),
args.service_key # 'None' for all keys.
)
print("%d event(s) set up for retry." % count)


def _status(agent_config, _, args):
# prints queue snapshot stats in this format:
# Service Key Pending Success In Error
# =================================================================
# key1 1 0 0
# key2 1 0 1

from pdagent.thirdparty.six.moves import zip_longest
from pdagent.pdagentutil import get_stats

status = get_stats(
agent_config.get_queue(),
service_key=args.service_key # 'None' for all-keys.
)

snapshot = status.get("snapshot")
if not snapshot:
print("Nothing to report.")
else:
# left-aligned service key, right-aligned counts.
flags = ["-", "", "", "", ""]
widths = [35, 10, 10, 10, 10]
types = ["s", "s", "s", "s", "s"]
column_fmts = [
"%" + "".join(e)
for e in zip_longest(flags, map(str, widths), types)
]
fmt = "".join(column_fmts)
print(fmt % ("Service Key", "Pending", "Success", "In Error"))
print("=" * sum(widths))
empty_dict = dict()
for (svc_key, state) in sorted(snapshot.iteritems()):
print(fmt % (
svc_key,
state.get("pending_events", empty_dict).get("count", 0),
state.get("succeeded_events", empty_dict).get("count", 0),
state.get("failed_events", empty_dict).get("count", 0)
(1 if state.get("throttled", False) else 0)
))


def main():
from pdagent.config import load_agent_config

description = "Access local queue of PagerDuty Agent."
parser = build_queue_arg_parser(description)
args = parser.parse_args()
args.func(load_agent_config(), parser, args)


if __name__ == "__main__":
try:
import pdagent.config
except ImportError:
# Fix up for dev layout
import sys
from os.path import realpath, dirname

sys.path.append(dirname(dirname(realpath(__file__))))
import pdagent.config
main()
if [ -x "$(command -v python3)" ];
then
python3 $DIR/pd-queue.py "$@"
else
python $DIR/pd-queue.py "$@"
fi
Loading