Skip to content

Instantly share code, notes, and snippets.

@toabctl
Created November 22, 2016 12:38
Show Gist options
  • Save toabctl/7c03e4d5331dd18d350023797d91d450 to your computer and use it in GitHub Desktop.
Save toabctl/7c03e4d5331dd18d350023797d91d450 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# Copyright (c) 2016 SUSE Linux GmbH
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import print_function
import argparse
import getpass
import os
import re
import sys
from six.moves import configparser
from six.moves import input
import jenkinsapi
from jenkinsapi.jenkins import Jenkins
import paramiko
# path to the user configuration file
USER_CONFIG_PATH = os.path.expanduser('~/.soc-ci.ini')
# possible mkcX hosts
CI_WORKERS = list('abcdefghijklmn')
def _config_credentials_get():
"""get username, password and url"""
user = input("username:")
password = getpass.getpass()
url = input("url:")
nick = input("nick (used for CI reservations, eg 'tbechtold'):")
return user, password, url, nick
def _config_get():
"""get the configuration"""
conf = configparser.RawConfigParser()
conf.read([USER_CONFIG_PATH])
section_name = "defaults"
if not conf.has_section(section_name):
user, password, url, nick = _config_credentials_get()
conf.add_section(section_name)
conf.set(section_name, "user", user)
conf.set(section_name, "password", password)
conf.set(section_name, "url", url)
conf.set(section_name, "nick", nick)
with os.fdopen(os.open(
USER_CONFIG_PATH, os.O_WRONLY | os.O_CREAT, 0o600), 'w') as f:
conf.write(f)
return dict(conf.items(section_name))
###############################################################################
def _ssh_get_client():
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
return client
def _os_mkcloud_where(job_id):
conf = _config_get()
server = Jenkins(conf['url'],
username=conf['user'],
password=conf['password'])
job = server['openstack-mkcloud']
build = job.get_build(job_id)
console = build.get_console()
m = re.search(r'.*access from outside via http://(.*)/ and .*', console)
if m:
return m.group(1)
return None
def os_mkcloud_where(args):
where = _os_mkcloud_where(args.job_id)
if where:
print(where)
sys.exit(0)
sys.exit('no idea where openstack-mkcloud job %s runs' % args.job_id)
def os_mkcloud_console_log(args):
conf = _config_get()
server = Jenkins(conf['url'],
username=conf['user'],
password=conf['password'])
job = server['openstack-mkcloud']
build = job.get_build(args.job_id)
print(build.get_console())
sys.exit(0)
def os_mkcloud_available(args):
crowbar_node = _os_mkcloud_where(args.job_id)
if crowbar_node:
client = _ssh_get_client()
client.connect(crowbar_node, username='root', password='linux')
stdin, stdout, stderr = client.exec_command('cat /etc/motd')
m = re.search(r'\s*created by the job:\s*https://ci.suse.de/job/openstack-mkcloud/(.*)/.*',
stdout.read())
if m:
found_job = int(m.group(1))
if args.job_id == found_job:
print('job env for %s still available on "%s"' % (
args.job_id, crowbar_node))
sys.exit(0)
else:
sys.exit('job env no longer available')
else:
sys.exit('no idea where openstack-mkcloud job %s runs' % args.job_id)
def ci_worker_pool_list(args):
client = _ssh_get_client()
client.connect('mkch%s.cloud.suse.de' % args.worker,
username='root', password='linux')
stdin, stdout, stderr = client.exec_command('ls /root/pool/')
print(stdout.read())
sys.exit(stdout.channel.recv_exit_status())
def ci_worker_pool_reserve(args):
conf = _config_get()
client = _ssh_get_client()
client.connect('mkch%s.cloud.suse.de' % args.worker,
username='root', password='linux')
stdin, stdout, stderr = client.exec_command(
'mv /root/pool/%s /root/pool/%s.%s' % (args.slot,
args.slot, conf['nick']))
print(stdout.read())
sys.exit(stdout.channel.recv_exit_status())
def ci_worker_pool_release(args):
conf = _config_get()
client = _ssh_get_client()
client.connect('mkch%s.cloud.suse.de' % args.worker,
username='root', password='linux')
stdin, stdout, stderr = client.exec_command(
'mv /root/pool/%s.%s /root/pool/%s' % (args.slot, conf['nick'],
args.slot))
print(stdout.read())
sys.exit(stdout.channel.recv_exit_status())
def parse_args():
parser = argparse.ArgumentParser(description='Useful commands for the CI')
subparsers = parser.add_subparsers(help='sub-command help')
# where runs a openstack-mkcloud job
parser_os_mkcloud_where = subparsers.add_parser(
'os-mkcloud-where', help='openstack-mkcloud: where run the job?')
parser_os_mkcloud_where.add_argument('job_id', metavar='ID', type=int)
parser_os_mkcloud_where.set_defaults(func=os_mkcloud_where)
# a openstack-mkcloud job console log
parser_os_mkcloud_console_log = subparsers.add_parser(
'os-mkcloud-console-log', help='openstack-mkcloud: print console log')
parser_os_mkcloud_console_log.add_argument('job_id', metavar='ID', type=int)
parser_os_mkcloud_console_log.set_defaults(func=os_mkcloud_console_log)
# is a openstack-mkcloud job still available in the CI?
parser_os_mkcloud_available = subparsers.add_parser(
'os-mkcloud-available', help='openstack-mkcloud: job env still available?')
parser_os_mkcloud_available.add_argument('job_id', metavar='ID', type=int)
parser_os_mkcloud_available.set_defaults(func=os_mkcloud_available)
# worker pool list
parser_worker_pool_list = subparsers.add_parser(
'worker-pool-list', help='List CI worker pool')
parser_worker_pool_list.add_argument('worker', type=str,
choices=CI_WORKERS)
parser_worker_pool_list.set_defaults(func=ci_worker_pool_list)
# worker pool reserve
parser_worker_pool_reserve = subparsers.add_parser(
'worker-pool-reserve', help='Reserve a pool from a CI worker')
parser_worker_pool_reserve.add_argument('worker', type=str,
choices=CI_WORKERS)
parser_worker_pool_reserve.add_argument('slot', type=int)
parser_worker_pool_reserve.set_defaults(func=ci_worker_pool_reserve)
# worker pool release
parser_worker_pool_release = subparsers.add_parser(
'worker-pool-release', help='Release a pool from a CI worker')
parser_worker_pool_release.add_argument('worker', type=str,
choices=CI_WORKERS)
parser_worker_pool_release.add_argument('slot', type=int)
parser_worker_pool_release.set_defaults(func=ci_worker_pool_release)
return parser.parse_args()
def main():
args = parse_args()
args.func(args)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment