From 057693fe37d21826a697f59ac4f1be09f763245a Mon Sep 17 00:00:00 2001
From: Saul Wold <sgw@linux.intel.com>
Date: Thu, 29 Aug 2019 14:38:30 -0700
Subject: [PATCH] Add Ansible Playbook to build specfiles via Zuul

This initial playbook and roles builds both CentOS and openSUSE
specfiles. The build occurs on OBS and is currently done in a
sandbox area in my home project [0]. The job currently just
starts the OBS job, it does not currently check the build
results, this will come later.

This has been tested with fault so far. The zuul template will
be added to each repo as specfiles are updated.

Added support to automagically build _service files.

[0] https://build.opensuse.org/project/subprojects/home:saulwold

zuul.d/projects needs to use the stx-zuul-jobs-linters to set
ANSIBLE_ROLES_PATH correctly

Change-Id: I6490030894b5887f33a55b1e66e374bcd50960d5
Signed-off-by: Saul Wold <sgw@linux.intel.com>
---
 playbooks/buildproject.yaml              | 234 +++++++++++++++++++++++
 roles/osc/README.rst                     |   2 +
 roles/osc/defaults/main.yml              |   2 +
 roles/osc/handlers/main.yml              |   2 +
 roles/osc/meta/main.yml                  |  60 ++++++
 roles/osc/tasks/commit.yaml              |  29 +++
 roles/osc/tasks/create_meta.yaml         |  20 ++
 roles/osc/tasks/create_oscrc.yaml        |  27 +++
 roles/osc/tasks/create_prjconf.yaml      |  18 ++
 roles/osc/tasks/create_service.yaml      |  10 +
 roles/osc/tasks/detachbranch.yaml        |  51 +++++
 roles/osc/tasks/freeze.yaml              |   8 +
 roles/osc/tasks/install_osc.yaml         |  64 +++++++
 roles/osc/tasks/main.yaml                |   8 +
 roles/osc/tasks/mkpac.yaml               |  10 +
 roles/osc/templates/_prj-centos.j2       |  23 +++
 roles/osc/templates/_prj-opensuse.j2     |  17 ++
 roles/osc/templates/_prjconf-centos.j2   |   4 +
 roles/osc/templates/_prjconf-opensuse.j2 |   0
 roles/osc/templates/_service.j2          |  16 ++
 roles/osc/templates/oscrc.j2             |  12 ++
 roles/osc/tests/inventory                |   2 +
 roles/osc/tests/test.yml                 |   5 +
 roles/osc/vars/main.yml                  |   2 +
 zuul.d/jobs.yaml                         |  11 ++
 zuul.d/project-templates.yaml            |  11 ++
 zuul.d/project.yaml                      |   6 +-
 27 files changed, 650 insertions(+), 4 deletions(-)
 create mode 100644 playbooks/buildproject.yaml
 create mode 100644 roles/osc/README.rst
 create mode 100644 roles/osc/defaults/main.yml
 create mode 100644 roles/osc/handlers/main.yml
 create mode 100644 roles/osc/meta/main.yml
 create mode 100644 roles/osc/tasks/commit.yaml
 create mode 100644 roles/osc/tasks/create_meta.yaml
 create mode 100644 roles/osc/tasks/create_oscrc.yaml
 create mode 100644 roles/osc/tasks/create_prjconf.yaml
 create mode 100644 roles/osc/tasks/create_service.yaml
 create mode 100644 roles/osc/tasks/detachbranch.yaml
 create mode 100644 roles/osc/tasks/freeze.yaml
 create mode 100644 roles/osc/tasks/install_osc.yaml
 create mode 100644 roles/osc/tasks/main.yaml
 create mode 100644 roles/osc/tasks/mkpac.yaml
 create mode 100644 roles/osc/templates/_prj-centos.j2
 create mode 100644 roles/osc/templates/_prj-opensuse.j2
 create mode 100644 roles/osc/templates/_prjconf-centos.j2
 create mode 100644 roles/osc/templates/_prjconf-opensuse.j2
 create mode 100644 roles/osc/templates/_service.j2
 create mode 100644 roles/osc/templates/oscrc.j2
 create mode 100644 roles/osc/tests/inventory
 create mode 100644 roles/osc/tests/test.yml
 create mode 100644 roles/osc/vars/main.yml

diff --git a/playbooks/buildproject.yaml b/playbooks/buildproject.yaml
new file mode 100644
index 0000000..237ac85
--- /dev/null
+++ b/playbooks/buildproject.yaml
@@ -0,0 +1,234 @@
+- hosts: all
+  vars:
+    project_ver: 1.0
+    src_project: "Cloud:StarlingX:2.0"
+    target_project: "home:saulwold:sandbox-{{ target_distro }}"
+    test_project: "{{ target_project }}-{{ project_ver }}"
+    stx_project_desc: ""
+    stx_url: ""
+    osc_user: "saulwold"
+    osc_register: osc_result
+    obs_projects: []
+    spec_dirs: []
+    sorted_dirs: []
+    osc_key_key: "@ub@FB7OZxs391wt"
+  tasks:
+    - name: Print OS Family
+      debug:
+       msg: "OS distribution: {{ ansible_distribution }}"
+
+    - name: Setup local distro flag CentOS
+      set_fact:
+        target_distro: centos
+      when: ansible_distribution == "CentOS"
+
+    - name: Setup local distro flag openSUSE
+      set_fact:
+        target_distro: opensuse
+      when: ansible_distribution == "openSUSE Leap"
+
+    - name: Setup local directories when not using zuul
+      set_fact:
+        top_dir: /test
+        src_dir: /test
+      when: zuul is not defined
+
+    - name: Setup local directories from zuul data
+      set_fact:
+        top_dir: "{{ zuul.executor.src_root }}"
+        src_dir: "{{ zuul.project.src_dir }}"
+      when: zuul is defined
+
+    - name: Print OS Family
+      debug:
+       msg: "OS distribution: {{ ansible_distribution }} {{ target_distro }}"
+
+    - name: Get OSC Command
+      import_role:
+        name: osc
+        tasks_from: install_osc
+
+    - name: Create temporary directory
+      tempfile:
+        state: directory
+        prefix: stx.
+      register: stx_pkg_tmpdir
+
+    - name: Setup oscrc file
+      import_role:
+        name: osc
+        tasks_from: create_oscrc
+
+    - name: OSC Version
+      import_role:
+        name: osc
+      vars:
+        osc_options: "--version"
+      register: osc_version
+
+    - name: Clean OSC Project
+      import_role:
+        name: osc
+      vars:
+        osc_options: rdelete -r -m 'rpm-packing CI Cleanup' {{ test_project }}
+      ignore_errors: yes
+
+    - name: Create Project
+      import_role:
+        name: osc
+        tasks_from: create_meta
+
+    - name: Freeze Project
+      import_role:
+        name: osc
+        tasks_from: freeze
+
+    - name: Init Project
+      import_role:
+        name: osc
+      vars:
+        osc_options: init {{ test_project }}
+
+    - name: Add prjconf
+      import_role:
+        name: osc
+        tasks_from: create_prjconf
+      when: target_distro == "centos"
+
+    - name: Find local directories with spec files
+      find:
+        paths: "{{ src_dir }}"
+        hidden: false
+        file_type: directory
+        patterns: "{{ target_distro }}"
+        recurse: yes
+      register: specfiles
+
+    - name: Generate Repo name
+      set_fact:
+        repo_name: "{{ specfiles.files.0.path.split('/')[-3] }}"
+
+    - name: Generate Repo Dir
+      set_fact:
+        repo_dir: "{{ src_dir}}/{{ repo_name }}"
+
+    - debug:
+        msg: "{{ repo_name }}: {{ repo_dir }} "
+
+    - meta: end_play
+
+    - name: List spec files
+      debug:
+        msg: "Specfile List: {{ specfiles }}"
+
+    - name: Create Project list
+      set_fact:
+        spec_dirs: "{{ spec_dirs }} + [ '{{ item.path.split('/')[-2] }}' ]"
+      with_items: "{{ specfiles.files }}"
+
+    - name: Sort directories
+      set_fact:
+        sorted_dirs: "{{ spec_dirs | sort | unique }}"
+
+    - name: "list Sorted Directories"
+      debug:
+        msg: "Sorted Directories: {{ item }}"
+      with_items: "{{ sorted_dirs }}"
+
+    - name: OSC mkpac
+      import_role:
+        name: osc
+        tasks_from: mkpac
+
+    - name: OSC detachbranch
+      import_role:
+        name: osc
+        tasks_from: detachbranch
+
+    - name: Create Service file
+      include_role:
+        name: osc
+        tasks_from: create_service
+      vars:
+        package_dir_orig: "{{ package_name }}/{{ lookup('ini', 'SRC_DIR type=properties file=/fault/' + package_name + '/centos/build_srpm.data') | regex_replace('\"', '') | regex_replace('\\/\\.', '') }}"
+      with_items: "{{ sorted_dirs }}"
+      loop_control:
+        loop_var: package_name
+
+    - name: OSC commit
+      import_role:
+        name: osc
+        tasks_from: commit
+
+#        pushd ./out
+#        sleep 5
+#        # Check if there is no change, then pretent success
+#        if [ $($osc_timed ls ${{OBS_TEST_PROJECT}} | wc -l) -lt 1 ]; then
+#            echo "Apparently there is no change... claiming SUCCESS"
+#            exit 0
+#        fi
+#
+#        while true; do
+#            unset pending
+#            unset failed
+#            unset kickscheduler
+#            unset succeeded
+#            res=`osc results --csv -r standard`
+#            if [ $? -ne 0 ]; then
+#                sleep 5
+#                continue
+#            fi
+#            echo "... $(date): "
+#            for r in $res; do
+#                # some failures?
+#                if [[ $r =~ broken$ ]]; then
+#                    echo "ignoring OBS broken state"
+#                    echo $r
+#                    continue
+#                fi
+#                # some failures?
+#                if [[ $r =~ (failed$|unresolvable$) ]]; then
+#                    echo $r
+#                    failed=1
+#                fi
+#                # still pending builds?
+#                if [[ $r =~ (blocked$|scheduled$|dispatching$|building$|signing$) ]]; then
+#                    pending=1
+#                fi
+#                # scheduler stuck?
+#                if [[ $r =~ (finished$|unknown$|outdated$) ]]; then
+#                    kickscheduler=1
+#                fi
+#                # found something?
+#                if [[ $r =~ succeeded$ ]]; then
+#                    succeeded=1
+#                fi
+#            done
+#
+#            if [ -n "$kickscheduler" ]; then
+#                echo "# $(date)" | osc meta prjconf -F - ${{OBS_TEST_PROJECT}}
+#                sleep $((RANDOM%60+30))
+#                echo "kicking scheduler"
+#                continue
+#            fi
+#
+#            if [ -n "$pending" ]; then
+#                sleep $((RANDOM%50+30))
+#                echo ""
+#                continue
+#            fi
+#
+#            if [ -n "$failed" ]; then
+#                echo "Build failed :-("
+#                exit 1
+#            elif [ -n "$succeeded" ];
+#                break
+#            fi
+#        done
+#
+
+        #    - name: Clean-up tmp directory
+        #      file:
+        #        path: "{{ stx_pkg_tmpdir.path }}"
+        #        state: absent
+        #      when: stx_pkg_tmpdir.path is defined
diff --git a/roles/osc/README.rst b/roles/osc/README.rst
new file mode 100644
index 0000000..7c9951b
--- /dev/null
+++ b/roles/osc/README.rst
@@ -0,0 +1,2 @@
+Ansible tasks and templates for working with the openSUSE Build System (OBS)
+via the command line tool called osc.
diff --git a/roles/osc/defaults/main.yml b/roles/osc/defaults/main.yml
new file mode 100644
index 0000000..302aefa
--- /dev/null
+++ b/roles/osc/defaults/main.yml
@@ -0,0 +1,2 @@
+---
+# defaults file for osc
\ No newline at end of file
diff --git a/roles/osc/handlers/main.yml b/roles/osc/handlers/main.yml
new file mode 100644
index 0000000..1f3485f
--- /dev/null
+++ b/roles/osc/handlers/main.yml
@@ -0,0 +1,2 @@
+---
+# handlers file for osc
\ No newline at end of file
diff --git a/roles/osc/meta/main.yml b/roles/osc/meta/main.yml
new file mode 100644
index 0000000..5d50bf4
--- /dev/null
+++ b/roles/osc/meta/main.yml
@@ -0,0 +1,60 @@
+galaxy_info:
+  author: your name
+  description: your description
+  company: your company (optional)
+
+  # If the issue tracker for your role is not on github, uncomment the
+  # next line and provide a value
+  # issue_tracker_url: http://example.com/issue/tracker
+
+  # Some suggested licenses:
+  # - BSD (default)
+  # - MIT
+  # - GPLv2
+  # - GPLv3
+  # - Apache
+  # - CC-BY
+  license: license (GPLv2, CC-BY, etc)
+
+  min_ansible_version: 2.4
+
+  # If this a Container Enabled role, provide the minimum Ansible Container version.
+  # min_ansible_container_version:
+
+  # Optionally specify the branch Galaxy will use when accessing the GitHub
+  # repo for this role. During role install, if no tags are available,
+  # Galaxy will use this branch. During import Galaxy will access files on
+  # this branch. If Travis integration is configured, only notifications for this
+  # branch will be accepted. Otherwise, in all cases, the repo's default branch
+  # (usually master) will be used.
+  #github_branch:
+
+  #
+  # Provide a list of supported platforms, and for each platform a list of versions.
+  # If you don't wish to enumerate all versions for a particular platform, use 'all'.
+  # To view available platforms and versions (or releases), visit:
+  # https://galaxy.ansible.com/api/v1/platforms/
+  #
+  # platforms:
+  # - name: Fedora
+  #   versions:
+  #   - all
+  #   - 25
+  # - name: SomePlatform
+  #   versions:
+  #   - all
+  #   - 1.0
+  #   - 7
+  #   - 99.99
+
+  galaxy_tags: []
+    # List tags for your role here, one per line. A tag is a keyword that describes
+    # and categorizes the role. Users find roles by searching for tags. Be sure to
+    # remove the '[]' above, if you add tags to this list.
+    #
+    # NOTE: A tag is limited to a single word comprised of alphanumeric characters.
+    #       Maximum 20 tags per role.
+
+dependencies: []
+  # List your role dependencies here, one per line. Be sure to remove the '[]' above,
+  # if you add dependencies to this list.
\ No newline at end of file
diff --git a/roles/osc/tasks/commit.yaml b/roles/osc/tasks/commit.yaml
new file mode 100644
index 0000000..35fe2e8
--- /dev/null
+++ b/roles/osc/tasks/commit.yaml
@@ -0,0 +1,29 @@
+---
+# Create the _meta template file
+- name: OSC Service
+  command: "osc service run"
+  args:
+    chdir: "{{ stx_pkg_tmpdir.path }}/{{ item }}"
+  with_items: "{{ sorted_dirs }}"
+- name: OSC Addremove
+  command: "osc addremove"
+  args:
+    chdir: "{{ stx_pkg_tmpdir.path }}/{{ item }}"
+  with_items: "{{ sorted_dirs }}"
+- name: OSC Commit
+  command: "osc commit -m CI-Build"
+  args:
+    chdir: "{{ stx_pkg_tmpdir.path }}"
+  ignore_errors: yes
+
+  # def osc_commit_all(workdir, packagename):
+  #    olddir = os.getcwd()
+  #  try:
+  #      os.chdir(os.path.join(workdir, packagename))
+  #      sh.osc('addremove')
+  #      for o in sh.osc('service', 'localrun', 'source_validator'):
+  #          if o.startswith('###ASK'):
+  #              sh.osc('rm', o.strip().split()[1])
+  #      sh.osc('commit', '--noservice', '-n')
+  #  finally:
+  #      os.chdir(olddir)
diff --git a/roles/osc/tasks/create_meta.yaml b/roles/osc/tasks/create_meta.yaml
new file mode 100644
index 0000000..38f39e8
--- /dev/null
+++ b/roles/osc/tasks/create_meta.yaml
@@ -0,0 +1,20 @@
+---
+# Create the _meta template file
+- name: Create temporary _meta file
+  tempfile:
+    state: file
+    prefix: stx_meta.
+  register: stx_meta_file
+- name: Print Debug output
+  debug:
+    msg:
+      - "{{ stx_meta_file.path }}"
+- name: Template _prj
+  template:
+    src: _prj-{{ target_distro }}.j2
+    dest: "{{ stx_meta_file.path }}"
+- name: Create OSC Repo
+  import_role:
+    name: osc
+  vars:
+    osc_options: api -T {{ stx_meta_file.path }} /source/{{ test_project }}/_meta
diff --git a/roles/osc/tasks/create_oscrc.yaml b/roles/osc/tasks/create_oscrc.yaml
new file mode 100644
index 0000000..aa2d7c8
--- /dev/null
+++ b/roles/osc/tasks/create_oscrc.yaml
@@ -0,0 +1,27 @@
+---
+# Create the _meta template file
+- name: oscrc - Zuul Block
+  block:
+  - name: Create osc config directory
+    file:
+      path: "/home/zuul/.config/osc"
+      state: directory
+      mode: 0755
+  - name: Template .oscrc
+    template:
+      src: oscrc.j2
+      dest: "/home/zuul/.config/osc/oscrc"
+  when: zuul is defined
+
+- name: oscrc - Non-Zuul Block
+  block:
+  - name: Create osc config directory
+    file:
+      path: "/root/.config/osc"
+      state: directory
+      mode: 0755
+  - name: Template .oscrc
+    template:
+      src: oscrc.j2
+      dest: "/root/.config/osc/oscrc"
+  when: zuul is not defined
diff --git a/roles/osc/tasks/create_prjconf.yaml b/roles/osc/tasks/create_prjconf.yaml
new file mode 100644
index 0000000..7b1e80d
--- /dev/null
+++ b/roles/osc/tasks/create_prjconf.yaml
@@ -0,0 +1,18 @@
+---
+# Create the _meta template file
+- name: Create temporary _prjconf file
+  tempfile:
+    state: file
+    prefix: stx_prjconf.
+  register: stx_prjconf_file
+
+- name: Template _prjconf
+  template:
+    src: _prjconf-{{ target_distro }}.j2
+    dest: "{{ stx_prjconf_file.path }}"
+
+- name: Create prjconf via meta command
+  import_role:
+    name: osc
+  vars:
+    osc_options: meta prjconf -F {{ stx_prjconf_file.path }}
diff --git a/roles/osc/tasks/create_service.yaml b/roles/osc/tasks/create_service.yaml
new file mode 100644
index 0000000..4c61815
--- /dev/null
+++ b/roles/osc/tasks/create_service.yaml
@@ -0,0 +1,10 @@
+---
+- name: Fix up package_dir variable
+  set_fact:
+    package_dir: "{{ package_dir_orig | regex_replace('\\/\\.', '') }}"
+
+- name: Template _service
+  template:
+    src: _service.j2
+    dest: "{{ stx_pkg_tmpdir.path }}/{{ package_name }}/_service"
+
diff --git a/roles/osc/tasks/detachbranch.yaml b/roles/osc/tasks/detachbranch.yaml
new file mode 100644
index 0000000..5fb27d8
--- /dev/null
+++ b/roles/osc/tasks/detachbranch.yaml
@@ -0,0 +1,51 @@
+---
+# Create the _meta template file
+#- name: OSC detachbranch
+#  command: "osc detachbranch {{ test_project }} {{ item }}"
+#  args:
+#    chdir: "{{ stx_pkg_tmpdir.path }}"
+#  with_items: "{{ sorted_dirs }}"
+#- name: Remove directory
+#  file:
+#    path: "{{ stx_pkg_tmpdir.path }}/{{ item }}"
+#    state: absent
+#  with_items: "{{ sorted_dirs }}"
+#- name: OSC Checkout
+#  command: "osc checkout {{ item }}"
+#  args:
+#    chdir: "{{ stx_pkg_tmpdir.path }}"
+#  with_items: "{{ sorted_dirs }}"
+- name: Restore meta-data
+  shell: cp {{ src_dir }}/{{ item }}/{{ target_distro }}/*[.cpst]* {{ stx_pkg_tmpdir.path }}/{{ item }}
+  with_items: "{{ sorted_dirs }}"
+#- name: OSC AddRemove
+#  command: "osc addremove"
+#  args:
+#    chdir: "{{ stx_pkg_tmpdir.path }}/{{ item }}"
+#  with_items: "{{ sorted_dirs }}"
+#- name: OSC Commit
+#  command: "osc commit"
+#  args:
+#    chdir: "{{ stx_pkg_tmpdir.path }}/{{ item }}"
+#  with_items: "{{ sorted_dirs }}"
+  #
+  #def osc_detachbranch(workdir, project, pkgname):
+  #    olddir = os.getcwd()
+  #  try:
+  #      os.chdir(os.path.join(workdir))
+  #      sh.osc('detachbranch', project, pkgname)
+  #      os.mkdir(pkgname + '.b')
+  #      for f in glob.glob(os.path.join(pkgname, '*')):
+  #          os.rename(f, os.path.join(pkgname + '.b', os.path.basename(f)))
+  #      sh.rm('-rf', pkgname)
+  #      sh.osc('co', pkgname)
+  #      for f in glob.glob(os.path.join(pkgname + '.b', '*')):
+  #          dst = os.path.basename(f)
+  #          try:
+  #              os.unlink(os.path.join(pkgname, dst))
+  #          except OSError:
+  #              pass
+  #          os.rename(f, os.path.join(pkgname, dst))
+  #      os.rmdir(pkgname + '.b')
+  #  finally:
+  #      os.chdir(olddir)
diff --git a/roles/osc/tasks/freeze.yaml b/roles/osc/tasks/freeze.yaml
new file mode 100644
index 0000000..6746ecf
--- /dev/null
+++ b/roles/osc/tasks/freeze.yaml
@@ -0,0 +1,8 @@
+---
+# Run OSC Command
+- name: Create OSC Freeze Link
+  import_role:
+    name: osc
+  vars:
+    osc_options: api -X POST /source/{{ test_project }}?cmd=freezelink
+  until: osc_result.stdout.find("status code=ok") != -1
diff --git a/roles/osc/tasks/install_osc.yaml b/roles/osc/tasks/install_osc.yaml
new file mode 100644
index 0000000..37b3571
--- /dev/null
+++ b/roles/osc/tasks/install_osc.yaml
@@ -0,0 +1,64 @@
+- name: Install Centos OSC Command
+  block:
+  - name: Add OSC Repo
+    yum_repository:
+      name: opensuse_tools
+      description: openSUSE Tools for OSC and OBS
+      baseurl: http://download.opensuse.org/repositories/openSUSE:/Tools/CentOS_7
+      gpgcheck: no
+
+  - name: Install OSC
+    yum:
+      name:
+       - build
+       - obs-service-obs_scm
+       - obs-service-recompress
+       - obs-service-tar
+       - obs-service-tar_scm
+       - osc
+      state: present
+  when: target_distro == 'centos'
+  become: yes
+
+- name: Install openSUSE OSC
+  block:
+  - name: Install OSC
+    zypper:
+      name:
+       - build
+       - obs-service-obs_scm
+       - obs-service-recompress
+       - obs-service-tar
+       - obs-service-tar_scm
+       - osc
+      state: present
+      disable_recommends: no
+  when: target_distro == 'opensuse'
+  become: yes
+
+- name: Install Ubuntu OSC Command
+  block:
+  - name: Add Ubuntu Tools repository key
+    apt_key:
+      url: "http://download.opensuse.org/repositories/openSUSE:/Tools/xUbuntu_18.10/Release.key"
+
+  - name: Add Ubuntu Tools repo
+    apt_repository:
+      repo: "deb http://download.opensuse.org/repositories/openSUSE:/Tools/xUbuntu_18.10 bionic main"
+      state: present
+      update_cache: yes
+    ignore_errors: yes
+
+  - name: Update apt cache
+    apt:
+      update_cache: yes
+    ignore_errors: yes
+
+  - name: Install required software
+    package:
+      name:
+       - software-properties-common
+       - osc
+      state: present
+  when: target_distro == "ubuntu"
+  become: yes
diff --git a/roles/osc/tasks/main.yaml b/roles/osc/tasks/main.yaml
new file mode 100644
index 0000000..2f5a822
--- /dev/null
+++ b/roles/osc/tasks/main.yaml
@@ -0,0 +1,8 @@
+---
+# Run OSC Command
+- name: Run OSC with options
+  command: osc {{ osc_options }}
+  args:
+    chdir: "{{ stx_pkg_tmpdir.path }}"
+  register: osc_result
+  #  register: "{{ osc_register }}"
diff --git a/roles/osc/tasks/mkpac.yaml b/roles/osc/tasks/mkpac.yaml
new file mode 100644
index 0000000..d98c371
--- /dev/null
+++ b/roles/osc/tasks/mkpac.yaml
@@ -0,0 +1,10 @@
+---
+# Create the _meta template file
+- name: OSC Makepackages
+  command: "osc mkpac {{ item }}"
+  args:
+    chdir: "{{ stx_pkg_tmpdir.path }}"
+  with_items: "{{ sorted_dirs }}"
+  #- name: Copy meta-data
+  #shell: ls -la {{ top_dir }}/save/{{ item }}/*.[cstp]* {{ stx_pkg_tmpdir.path }}/{{ item }} >> /tmp/list; cp  {{ top_dir }}/save/{{ item }}/*.[cstp]* {{ stx_pkg_tmpdir.path }}/{{ item }}
+  #with_items: "{{ sorted_dirs }}"
diff --git a/roles/osc/templates/_prj-centos.j2 b/roles/osc/templates/_prj-centos.j2
new file mode 100644
index 0000000..86a6e9c
--- /dev/null
+++ b/roles/osc/templates/_prj-centos.j2
@@ -0,0 +1,23 @@
+<project name="{{ test_project }}">
+  <title>Autogenerated CI project</title>
+  <description>
+{{ stx_project_desc }}
+  </description>
+  <url>
+{{ stx_url }}
+  </url>
+  <person userid="{{ osc_user }}" role="maintainer"/>
+  <publish>
+    <disable/>
+  </publish>
+  <repository name="CentOS_7">
+    <path project="home:saulwold:mytest" repository="CentOS_7"/>
+    <path project="home:gassyfeve:lico-dep" repository="CentOS_7"/>
+    <path project="home:lenovo-lico:lico-dep:5.1:el7" repository="el7"/>
+    <path project="CentOS:CentOS-7" repository="openstack-stein"/>
+    <path project="Fedora:EPEL:7" repository="CentOS"/>
+    <path project="CentOS:CentOS-7" repository="standard"/>
+    <arch>x86_64</arch>
+  </repository>
+</project>
+
diff --git a/roles/osc/templates/_prj-opensuse.j2 b/roles/osc/templates/_prj-opensuse.j2
new file mode 100644
index 0000000..c260825
--- /dev/null
+++ b/roles/osc/templates/_prj-opensuse.j2
@@ -0,0 +1,17 @@
+<project name="{{ test_project }}">
+  <title>Autogenerated CI project</title>
+  <description>
+{{ stx_project_desc }}
+  </description>
+  <url>
+{{ stx_url }}
+  </url>
+  <person userid="{{ osc_user }}" role="maintainer"/>
+  <publish>
+    <disable/>
+  </publish>
+  <repository name="openSUSE_Leap_15.1" rebuild="direct" block="local" linkedbuild="localdep">
+    <path project="{{ src_project }}" repository="openSUSE_Leap_15.1"/>
+    <arch>x86_64</arch>
+  </repository>
+</project>
diff --git a/roles/osc/templates/_prjconf-centos.j2 b/roles/osc/templates/_prjconf-centos.j2
new file mode 100644
index 0000000..89ab932
--- /dev/null
+++ b/roles/osc/templates/_prjconf-centos.j2
@@ -0,0 +1,4 @@
+Preinstall: python-backport-macros
+
+Prefer: python2-ipaddress python2-pyparsing python2-pyyaml
+
diff --git a/roles/osc/templates/_prjconf-opensuse.j2 b/roles/osc/templates/_prjconf-opensuse.j2
new file mode 100644
index 0000000..e69de29
diff --git a/roles/osc/templates/_service.j2 b/roles/osc/templates/_service.j2
new file mode 100644
index 0000000..cf90b38
--- /dev/null
+++ b/roles/osc/templates/_service.j2
@@ -0,0 +1,16 @@
+<services>
+  <service name="tar_scm">
+    <param name="scm">git</param>
+    <param name="url">https://opendev.org/starlingx/fault</param>
+    <param name="version">1.0</param>
+    <param name="subdir">{{  package_dir }}</param>
+    <param name="filename">{{  package_name }}</param>
+    <param name="changesgenerate">disable</param>
+  </service>
+  <service name="recompress">
+    <param name="compression">gz</param>
+    <param name="file">*.tar</param>
+  </service>
+  <service name="set_version" mode="disabled"/>
+</services>
+
diff --git a/roles/osc/templates/oscrc.j2 b/roles/osc/templates/oscrc.j2
new file mode 100644
index 0000000..94ae0a3
--- /dev/null
+++ b/roles/osc/templates/oscrc.j2
@@ -0,0 +1,12 @@
+[general]
+apiurl = https://api.opensuse.org
+
+[api]
+email = sgw@linux.intel.com
+
+[https://api.opensuse.org]
+user = saulwold
+pass = {{ osc_key_key }}
+email = sgw@linux.intel.com
+trusted_prj=openSUSE:Leap:15.0 SUSE:SLE-12-SP4:GA Cloud:OpenStack:Stein devel:kubic openSUSE:Leap:15.1
+
diff --git a/roles/osc/tests/inventory b/roles/osc/tests/inventory
new file mode 100644
index 0000000..878877b
--- /dev/null
+++ b/roles/osc/tests/inventory
@@ -0,0 +1,2 @@
+localhost
+
diff --git a/roles/osc/tests/test.yml b/roles/osc/tests/test.yml
new file mode 100644
index 0000000..857566d
--- /dev/null
+++ b/roles/osc/tests/test.yml
@@ -0,0 +1,5 @@
+---
+- hosts: localhost
+  remote_user: root
+  roles:
+    - osc
\ No newline at end of file
diff --git a/roles/osc/vars/main.yml b/roles/osc/vars/main.yml
new file mode 100644
index 0000000..c267f83
--- /dev/null
+++ b/roles/osc/vars/main.yml
@@ -0,0 +1,2 @@
+---
+# vars file for osc
\ No newline at end of file
diff --git a/zuul.d/jobs.yaml b/zuul.d/jobs.yaml
index 0f33d96..c96b093 100644
--- a/zuul.d/jobs.yaml
+++ b/zuul.d/jobs.yaml
@@ -23,3 +23,14 @@
     vars:
       tox_envlist: rpm-packaging-lint
     files: .*\.spec
+
+- job:
+    name: stx-obs-build-opensuse
+    nodeset: opensuse-150
+    run: playbooks/buildproject.yaml
+
+- job:
+    name: stx-obs-build-centos
+    nodeset: centos-7
+    run: playbooks/buildproject.yaml
+
diff --git a/zuul.d/project-templates.yaml b/zuul.d/project-templates.yaml
index df2f2e3..73dbfcc 100644
--- a/zuul.d/project-templates.yaml
+++ b/zuul.d/project-templates.yaml
@@ -58,3 +58,14 @@
       jobs:
         - stx-check-specfile:
             voting: false
+
+- project-template:
+    name: stx-build-rpms
+    description: |
+      Buiild RPMs via Ansible Playbook and OBS
+    check:
+      jobs:
+        - stx-obs-build-centos:
+            voting: false
+        - stx-obs-build-opensuse:
+            voting: false
diff --git a/zuul.d/project.yaml b/zuul.d/project.yaml
index b9bd864..1cd8b00 100644
--- a/zuul.d/project.yaml
+++ b/zuul.d/project.yaml
@@ -3,9 +3,7 @@
       - build-openstack-docs-pti
     check:
       jobs:
-        - openstack-tox-linters
-        - openstack-tox-pep8
+        - stx-zuul-jobs-linters
     gate:
       jobs:
-        - openstack-tox-linters
-        - openstack-tox-pep8
+        - stx-zuul-jobs-linters