Simplest Enterprise Continuous Integration Solutions
Best Practices of Software Change Configuration & Release Management
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.
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 branchproduction - 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 branchreleases - 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 -aLinux 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: 6392989d7874abf2a90e89b9f850ad ca4bd3d53a
Content-Type: application/x-yaml
Set-Cookie: session_id= 6392989d7874abf2a90e89b9f850ad ca4bd3d53a; expires=Thu, 10 Sep 2015 06:06:40 GMT; Path=/
return:
- eauth: pam
expire: 1441872400.749799
perms:
- .*
start: 1441829200.7497981
token: 6392989d7874abf2a90e89b9f850ad ca4bd3d53a
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 6392989d7874abf2a90e89b9f850ad ca4bd3d53a
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 Dockerfilecd ${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}
Labels:
Continuous Deployment,
Continuous Integration,
DevOps,
Docker
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/
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
Subscribe to:
Posts (Atom)