Simplest Enterprise Continuous Integration Solutions

Saturday, April 30, 2016

Software Development: Practice Jenkins Pipeline as Code

Practice Jenkins Pipeline as Code with Git flow, JFrog Artifactory, Azure Container Registry, GCP Container Registry.

RELEASE build (master, release branches)



PRIVATE build (feature, bugfix. hotfix branches)



Jenkinsfile (Jenkins Pipeline as Code) Development 


Saturday, October 3, 2015

Software Development: Git flow overview





Permanent branches

master - the integration branch used for development. Feature branches are merged back into this branch
production - support preparation of a new production release (allow for minor bug fixes)

Temporary branches

features - used for specific feature work. Typically, this branches from and merges back into the development branch
releases - used for release tasks and long-term maintenance. Typically, this branches from the development branch and changes are merged back into the development branch
hotfixes - typically used to quickly fix the production branch

Saturday, September 19, 2015

Salt REST API: Rest_cherrypy

Install Salt-API

[root@salt-master-server ~]# uname -a
Linux salt-master-server 2.6.32-504.16.2.el6.x86_64 #1 SMP Tue Apr 21 08:37:59 PDT 2015 x86_64 x86_64 x86_64 GNU/Linux
[root@salt-master-server ~]# yum install salt-api
Loaded plugins: security
Setting up Install Process
epel/metalink                                                                                                             |  12 kB     00:00
epel                                                                                                                      | 4.3 kB     00:00
epel/primary_db                                                                                                           | 5.7 MB     00:16
public_ol6_latest                                                                                                         | 1.4 kB     00:00
public_ol6_latest/primary                                                                                                 |  52 MB     00:12
public_ol6_latest                                                                                                                    32176/32176
Resolving Dependencies
--> Running transaction check
---> Package salt-api.noarch 0:2015.5.3-3.el6 will be installed
--> Processing Dependency: salt-master = 2015.5.3-3.el6 for package: salt-api-2015.5.3-3.el6.noarch
http://bencane.com/2014/07/17/integrating-saltstack-with-other-services-via-salt-api/--> Processing Dependency: python-cherrypy for package: salt-api-2015.5.3-3.el6.noarch
--> Running transaction check
---> Package python-cherrypy.noarch 0:3.2.2-3.el6 will be installed
---> Package salt-master.noarch 0:2015.5.0-1.el6 will be updated
---> Package salt-master.noarch 0:2015.5.3-3.el6 will be an update
--> Processing Dependency: salt = 2015.5.3-3.el6 for package: salt-master-2015.5.3-3.el6.noarch
--> Running transaction check
---> Package salt.noarch 0:2015.5.0-1.el6 will be updated
--> Processing Dependency: salt = 2015.5.0-1.el6 for package: salt-minion-2015.5.0-1.el6.noarch
---> Package salt.noarch 0:2015.5.3-3.el6 will be an update
--> Running transaction check
---> Package salt-minion.noarch 0:2015.5.0-1.el6 will be updated
---> Package salt-minion.noarch 0:2015.5.3-3.el6 will be an update
--> Finished Dependency Resolution

Dependencies Resolved
=================================================================================================================================================
Package                                Arch                          Version                                  Repository                   Size
=================================================================================================================================================
Installing:
salt-api                               noarch                        2015.5.3-3.el6                           epel                         13 k
Installing for dependencies:
python-cherrypy                        noarch                        3.2.2-3.el6                              epel                        465 k
Updating for dependencies:
salt                                   noarch                        2015.5.3-3.el6                           epel                        4.1 M
salt-master                            noarch                        2015.5.3-3.el6                           epel                        965 k
salt-minion                            noarch                        2015.5.3-3.el6                           epel                         26 k

Transaction Summary
=================================================================================================================================================
Install       2 Package(s)
Upgrade       3 Package(s)

Total download size: 5.5 M
Is this ok [y/N]: y
Is this ok [y/N]: y
Downloading Packages:
(1/5): python-cherrypy-3.2.2-3.el6.noarch.rpm                                                                             | 465 kB     00:00
(2/5): salt-2015.5.3-3.el6.noarch.rpm                                                                                     | 4.1 MB     00:09
(3/5): salt-api-2015.5.3-3.el6.noarch.rpm                                                                                 |  13 kB     00:00
(4/5): salt-master-2015.5.3-3.el6.noarch.rpm                                                                              | 965 kB     00:02
(5/5): salt-minion-2015.5.3-3.el6.noarch.rpm                                                                              |  26 kB     00:00
-------------------------------------------------------------------------------------------------------------------------------------------------
Total                                                                                                            409 kB/s | 5.5 MB     00:13
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
Warning: RPMDB altered outside of yum.
  Updating   : salt-2015.5.3-3.el6.noarch                                                                                                    1/8
  Updating   : salt-master-2015.5.3-3.el6.noarch                                                                                             2/8
warning: /etc/salt/master created as /etc/salt/master.rpmnew
  Installing : python-cherrypy-3.2.2-3.el6.noarch                                                                                            3/8
  Installing : salt-api-2015.5.3-3.el6.noarch                                                                                                4/8
  Updating   : salt-minion-2015.5.3-3.el6.noarch                                                                                             5/8
warning: /etc/salt/minion created as /etc/salt/minion.rpmnew
  Cleanup    : salt-minion-2015.5.0-1.el6.noarch                                                                                             6/8
  Cleanup    : salt-master-2015.5.0-1.el6.noarch                                                                                             7/8
  Cleanup    : salt-2015.5.0-1.el6.noarch                                                                                                    8/8
  Verifying  : salt-master-2015.5.3-3.el6.noarch                                                                                             1/8
  Verifying  : python-cherrypy-3.2.2-3.el6.noarch                                                                                            2/8
  Verifying  : salt-2015.5.3-3.el6.noarch                                                                                                    3/8
  Verifying  : salt-api-2015.5.3-3.el6.noarch                                                                                                4/8
  Verifying  : salt-minion-2015.5.3-3.el6.noarch                                                                                             5/8
  Verifying  : salt-minion-2015.5.0-1.el6.noarch                                                                                             6/8
  Verifying  : salt-2015.5.0-1.el6.noarch                                                                                                    7/8
  Verifying  : salt-master-2015.5.0-1.el6.noarch                                                                                             8/8

Installed:
  salt-api.noarch 0:2015.5.3-3.el6
Dependency Installed:
  python-cherrypy.noarch 0:3.2.2-3.el6
Dependency Updated:
  salt.noarch 0:2015.5.3-3.el6               salt-master.noarch 0:2015.5.3-3.el6               salt-minion.noarch 0:2015.5.3-3.el6

Complete!


Generate the key, sign the key and generate a certificate

[root@salt-master-server ~]# mkdir -p /etc/ssl/private
[root@salt-master-server ~]# openssl genrsa -out /etc/ssl/private/key.pem 4096
Generating RSA private key, 4096 bit long modulus
.........................++
.................................++
e is 65537 (0x10001)
[root@salt-master-server ~]# openssl req -new -x509 -key /etc/ssl/private/key.pem -out /etc/ssl/private/cert.pem -days 1826
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:<my-country-code>
State or Province Name (full name) []:<my-state-code>
Locality Name (eg, city) [Default City]:<my-city-code>
Organization Name (eg, company) [Default Company Ltd]:<my-org-name>
Organizational Unit Name (eg, section) []:<my-unit-name>
Common Name (eg, your name or your server's hostname) []:salt-master-server

Email Address []:

Basic salt-api configuration, Salt external authentication system

[root@salt-master-server salt]# diff -u master.orig master
--- master.orig       2015-09-09 15:37:28.733636701 -0400
+++ master      2015-09-09 15:44:14.764932660 -0400
@@ -264,6 +264,11 @@
#    fred:
#      - test.*
#
+external_auth:
+  pam:
+    bldmaster:
+      - .*
+
# Time (in seconds) for a newly generated token to live. Default: 12 hours

#token_expire: 43200

@@ -726,3 +731,9 @@
############################################
# Which returner(s) will be used for minion's result:
#return: mysql
+rest_cherrypy:
+  port: 8080
+  host: 10.3.23.160
+  ssl_crt: /etc/ssl/private/cert.pem
+  ssl_key: /etc/ssl/private/key.pem
+

Restart salt-master and salt-api services

[root@salt-master-server ~]# chmod 666 /var/log/salt/master
[root@salt-master-server ~]# service salt-master restart
Stopping salt-master daemon:                               [  OK  ]
Starting salt-master daemon:                               [  OK  ]
[root@salt-master-server ~]# service salt-api restart
Stopping salt-api daemon:                                  [  OK  ]
Starting salt-api daemon:                                  [  OK  ]
[root@salt-master-server ~]# chkconfig salt-master --list
salt-master     0:off   1:off   2:on    3:on    4:on    5:on    6:off
[root@salt-master-server ~]# chkconfig salt-api --list
salt-api        0:off   1:off   2:off   3:on    4:off   5:on    6:off

Test Salt external authentication

[bldmaster@salt-master-server ~]$ salt -a pam '*' test.ping
username: bldmaster
password:
salt-master-server:
    True
salt-minion-host:
    True
[bldmaster@salt-master-server ~]$ salt -T -a pam '*' test.ping
username: bldmaster
password:
salt-minion-host:
    True
salt-master-server:
    True

Rest_cherrypy

[root@salt-master-server ~]# curl -sSki -X POST https://salt-master-server/login -H 'Accept: application/x-yaml' -d username="bldmaster" -d password="my-password" -d eauth=pam -c ./salt-cookie.txt
HTTP/1.1 200 OK
Content-Length: 161
Access-Control-Expose-Headers: GET, POST
Vary: Accept-Encoding
Server: CherryPy/3.2.2
Allow: GET, HEAD, POST
Access-Control-Allow-Credentials: true
Date: Wed, 09 Sep 2015 20:06:40 GMT
Access-Control-Allow-Origin: *
X-Auth-Token: 6392989d7874abf2a90e89b9f850adca4bd3d53a
Content-Type: application/x-yaml
Set-Cookie: session_id=6392989d7874abf2a90e89b9f850adca4bd3d53a; expires=Thu, 10 Sep 2015 06:06:40 GMT; Path=/

return:
- eauth: pam
  expire: 1441872400.749799
  perms:
  - .*
  start: 1441829200.7497981
  token: 6392989d7874abf2a90e89b9f850adca4bd3d53a
  user: bldmaster
[root@salt-master-server ~]# cat ./salt-cookie.txt
# Netscape HTTP Cookie File
# This file was generated by libcurl! Edit at your own risk.

10.3.23.160     FALSE   /       FALSE   1441865200      session_id      6392989d7874abf2a90e89b9f850adca4bd3d53a

Sunday, April 19, 2015

Saturday, January 17, 2015

Jenkins REST API: Practice within Continuous Integration

Jenkins REST API launch a parameterized build


/usr/bin/curl -X POST http://<jenkins-user>:<jenkins-token>@<jenkins-server-to-build-job>/build --form 'json={"parameter":[{"name":"RELEASE_VERSION","value":"1.0.0"},{"name":"DEVELOPMENT_VERSION","value":"1.0.0-SNAPSHOT"},{"name":"JIRA_ISSUE","value":"<jira-key>"}]}'

Monitor Jenkins build status


http://<jenkins-server-to-build-job>/api/xml
http://<jenkins-server-to-build-job>/lastBuild/api/xml  (Note: only valid while nextbuildnumber > 1) 

Saturday, December 13, 2014

Docker: Practice with Jenkins, Salt

Automate generate Dockerfile within Jenkins pipeline job


# generate Dockerfile
/bin/rm -rf ${WORKSPACE}/docker
/bin/mkdir -p ${WORKSPACE}/docker

cd ${WORKSPACE}/docker
touch Dockerfile

cat <<EOF > Dockerfile
# set the base image to Centos
FROM centos:6.7

# File Author / Maintainer
MAINTAINER buildmaster <buildmaster@qxc.com>

RUN rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm

RUN yum install -y salt salt-minion

# udpate salt file_roots, and pillar_roots
RUN echo 'file_roots:' >> /etc/salt/minion
RUN echo '  base:' >> /etc/salt/minion
RUN echo '    - /srv/salt' >> /etc/salt/minion
RUN echo '    - /srv/formulas' >> /etc/salt/minion
RUN echo '  dev:' >> /etc/salt/minion
RUN echo '    - /srv/salt' >> /etc/salt/minion
RUN echo '    - /srv/formulas' >> /etc/salt/minion
RUN echo 'pillar_roots:' >> /etc/salt/minion
RUN echo '  base:' >> /etc/salt/minion
RUN echo '    - /srv/pillar' >> /etc/salt/minion
RUN echo '  dev:' >> /etc/salt/minion
RUN echo '    - /srv/pillar/qa' >> /etc/salt/minion

# use local file_client
RUN echo 'file_client: local' >> /etc/salt/minion

# define Salt role
RUN salt-call grains.setval roles "[${MY_ROLE}]"
EOF

Build docker image, consume with docker container

# build a docker image from Dockerfile
cd ${WORKSPACE}/docker

docker build -t ${DOCKER_IMAGE}.v${PIPELINE_VERSION} .

# add host directory as a data volume (which only works with at least centos6.7)
# invoke salt-call with docker container 
docker run –v salt_scripts:/srv/rw -t ${DOCKER_IMAGE}.v${PIPELINE_VERSION} salt-call --local pillar.items | /usr/bin/tee ${OUTPUT}

# handle return code and clean up successful docker container
CHECK_SH=${WORKSPACE}/${PIPELINE_VERSION}.`date "+%Y%m%d%M%S"`.sh
/bin/echo "#!/bin.sh" > ${CHECK_SH}
/bin/echo "RET_CODE=0" >> ${CHECK_SH}
/bin/echo "/bin/grep -n -i error ${OUTPUT} > ${OUTPUT}.tmp" >> ${CHECK_SH}
/bin/echo "if [ ! -s ${OUTPUT}.tmp ]; then" >> ${CHECK_SH}
/bin/echo "   docker rmi -f ${DOCKER_IMAGE}.v${PIPELINE_VERSION}" >> ${CHECK_SH}
/bin/echo "else" >> ${CHECK_SH}
/bin/echo "   RET_CODE=1" >> ${CHECK_SH}
/bin/echo "fi" >> ${CHECK_SH}
/bin/echo "exit ${RET_CODE}" >> ${CHECK_SH}

/bin/sh ${CHECK_SH}

Saturday, October 11, 2014

JIRA REST API: query JIRA issue summary

Enable JIRA to accept remote API calls:

Enable Accept remote API calls (Administrator > General Configuration > Set Accept remote API calls to On)

Examples for http and https with summary field display

curl -s -u <jira-user>:<jira-password> -X GET -H "Content-Type: application/json" http://<jira-server>:9090/rest/api/2/search?jql=key=<jira-key>&fields=summary


curl -sk -u <jira-user>:<jira-password> -X GET -H "Content-Type: application/json" http://<jira-server>:8443/rest/api/2/search?jql=key=<jira-key>&fields=summary