├── README.md ├── docs └── img │ └── game.png ├── install-game.sh ├── install-game.yml ├── inventory └── inventory.cfg ├── roles ├── setup-achievement-server │ ├── files │ │ └── achievement-server-template.json │ └── tasks │ │ └── main.yml ├── setup-admin-app │ └── tasks │ │ └── main.yml ├── setup-cicd │ ├── files │ │ └── pipeline.yml │ └── tasks │ │ └── main.yml ├── setup-game-app │ └── tasks │ │ └── main.yml ├── setup-game-server │ ├── files │ │ ├── game-server-build.json │ │ ├── game-server-routes.json │ │ └── game-server-template.json │ └── tasks │ │ └── main.yml ├── setup-leaderboard-app │ └── tasks │ │ └── main.yml ├── setup-score-server │ └── tasks │ │ └── main.yml ├── setup-scoreboard-app │ └── tasks │ │ └── main.yml └── wait-client-apps │ └── tasks │ └── main.yml └── vars └── game-config.yml /README.md: -------------------------------------------------------------------------------- 1 |

2 | Game Screenshot 3 |

4 | 5 | # Introduction 6 | 7 | This is a playbook to install the Red Hat 2016 Summit game in an Openshift environment. It is highly recommended that you view the demo of the game that was done at the 2016 Red Hat Summit [here](https://www.youtube.com/watch?v=ooA6FmTL4Dk) to understand what the game is about. As a summary, the game is a balloon popping game where the attendees can participate by playing the game while the demo is running. 8 | 9 | Note that this game uses a microservice architecture and requires quite a few pods to run, thus if you are using Minishift or the Red Hat CDK it is recommended that you allocate additional memory to the environment using ```minishift config set memory xxxx```. The demo uses approximatly 4 GB of memory and you will need some over and above that for rolling deployments, builds, etc. 10 | 11 | ### Prequisites 12 | 13 | #### Imagestreams 14 | 15 | Note the playbook will add various imagestreams and templates to OpenShift. However, it does not update the nodejs template and this application requires that nodejs version 4 and 6 be available. Check your imagestream and make sure the nodejs imagestream has these version tags, i.e. 16 | 17 | ``` 18 | oc get is nodejs -n openshift 19 | ``` 20 | 21 | If it doesn't, replace the imagestream with one that does: 22 | 23 | ``` 24 | oc project openshift 25 | oc delete is nodejs 26 | oc create -f https://raw.githubusercontent.com/luciddreamz/library/master/official/nodejs/imagestreams/nodejs-rhel7.json 27 | ``` 28 | 29 | #### Cluster Admin Required 30 | 31 | The playbook uses an admin user to install the required templates and imagestreams. The admin user requires a username and password, ```system:admin``` is not used since this playbook must support installations of Openshift that can only be accessed remotely. You can create an admin user in the CDK or minishift by logging in with a username and password and then run the following command: 32 | 33 | ``` 34 | oc adm policy add-cluster-role-to-user cluster-admin 35 | ``` 36 | 37 | #### Ansible Variables 38 | 39 | You will need to update the variables in ```vars/game-config.yml``` to match the particulars of your Openshift installation. 40 | 41 | ### Installing The Game 42 | 43 | To install the game, simply run the ```install.sh``` command which will run the ansible playbook. It will take approximately 10 to 15 minutes to install everything. 44 | 45 | ### Managing The Game 46 | 47 | To manage the game and switch between the different modes (title, start, game over, etc), login into the admin application. The default token is ```CH2UsJePthRWTmLI8EY6```. If you change the token in the game-server, make sure to update it in gamebus-pipeline as well. 48 | 49 | ### Blue/Green Gamebus Deployment 50 | 51 | This playbook installs the gamebus in a blue/green configuration with 100% of the traffic being sent initially to blue. The blue/green gamebus environments are configured as a single vert.x cluster and it uses kubernetes discovery. 52 | 53 | The background of the game client reflects the environment color the player is connected to. A ```gamebus-pipeline``` is included which will build and deploy the application as well as change the route to the opposite color. This pipeline was adapted from the coolstore-microservice demo. 54 | 55 | Note that simply updating the route to send all traffic to the opposite pod will not change the color of the background automatically. This is because the game uses a persistent connection via a WebSocket and thus the connection will not be re-routed unless a new connection is established. The last stage of the pipeline will initiate a reconnect for game and admin clients by sending a curl request to the idle game-server, this should force everyone to the new one. However once in a while it doesn't take and some players may need to do a manual refresh of their browser so be prepared for that. 56 | 57 | However, at the last couple of events I removed the reconnect from the pipeline. I found it actually made for a better experience explaining why the background hadn't changed (persistent websocket connection and HAProxy allowing connections to be drained) and have them refresh their browser manually to see the new color after the explanation. The reconnect isn't seamless so it leads to a bit of a "what happened?" moment. 58 | 59 | When a game player connects the game client, the background color is automatically set based on the color of the environment making it easy for the audience to understand when the environment has been flipped. This is done through the COLOR environment variable. Valid colors include ```default```, ```blue```, ```green``` or ```canary```. This also means that setting the background in the admin application is ignored when the COLOR environment variable is present. 60 | 61 | This demo has been used at three events and it worked well, however feedback is always welcome. 62 | 63 | ### Repositories 64 | 65 | The original game consisted of a number of repositories in github, 21 in total in fact. This version builds a subset of the game: the basic game plus the administration app, scoreboard, leaderboard and achievements are all functional. This version does not include the Pipeline and CICD visualization that was demonstrated in the video. At the moment the following repositories are used: 66 | 67 | | Repository | Description 68 | |---|---| 69 | |[vertx-game-server](https://github.com/gnunn1/vertx-game-server)| The game server that acts as an integration bus for the other microservices. The game, leaderboard and scoreboard all connect to this in order to communicate with the other components. As the name implies, this component uses the [Vert.X](http://vertx.io/) framework. 70 | |[mobile-app](https://github.com/gnunn1/mobile-app)| This is the actual game, it is written in typescript using angular and requires NodeJS 4. It communicates both with the vertx-game-server. 71 | |[mobile-app-admin](https://github.com/gnunn1/mobile-app-admin)| This is the tool to administer the game, without this app you cannot start the game and it requires connectivity to the vertx-game-server. 72 | |[achievement-server](https://github.com/burrsutter/vertx-achievement-service)| Manages the player achievements, it originally was a JEE application that ran on EAP (or Wildfly), however it was recently re-written in vert.x which is wwhat is used here. 73 | |[score-server](https://github.com/gnunn1/score-server)| Aggregates the player scores, runs on BRMS and uses rules to evaluate scoring. This was forked to fix a build issue as a dependency on hibernate-core was needed to compile the hibernate annotations. 74 | |[leaderboard](https://github.com/gnunn1/leaderboard)| A javascript application that is used to display the leaderboard. It requires connectivity to the vertx-game-server. 75 | |[scoreboard](https://github.com/gnunn1/scoreboard)| A javascript application that is used to display the scoreboard. It requires connectivity to the vertx-game-server. 76 | 77 | ### Environment 78 | 79 | I have used this demo three times with the largest audience consisting of 120 people and for this size audience I find a small environment is all that is needed to run the demo. I used a small OpenShift environment (1 master, 3 app nodes) running in AWS with no issue. I use this [playbook](https://github.com/gnunn1/openshift-aws-setup) to provision my AWS environment but it shouldn't matter what you use. 80 | 81 | I typically set the number of gamebus replicas to 2 in the ```vars/game-config.yml``` file. 82 | 83 | ### Random Thoughts 84 | 85 | I've wavered between making the blue/green instances a single vert.x cluster versus separate clusters. The single cluster is easier because the game state, players and other persistent information are carried between the two when switching from blue to green making for a more seamless transition. However it goes against the idea of each color being independent since the eventbus queues would be clustered across both. This means events that should be specific to green or blue get applied to both. For example, one issue I had to deal with is configuration messages being served from the idle environment resulting in the game-client getting the wrong color. 86 | 87 | The original version of the game server (i.e. gamebus) used Hazelcast as the Vert.x cluster manager. I have recently updated it to use Infinispan with replicated caches rather then the distributed ones on Hazelcast. This fixes the problem of the state having to be on enough backups to ensure it survives the blue/green deployment. With the replicated caches every pod has a copy of the cache. 88 | 89 | Another thing I would like to do is deploy a canary on the fly. It would be relatively trivial to create a pipeline to do this as I believe no existing code changes would be required. 90 | 91 | ### Credits 92 | 93 | A big thank you to the folks who originally developed this code for the 2016 Red Hat Summit, they did all the hard work so a big kudos to them. 94 | -------------------------------------------------------------------------------- /docs/img/game.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gnunn1/summit-game-ansible/b48e4a037f885ac4d550c5c2bb74e4c5bf17f20c/docs/img/game.png -------------------------------------------------------------------------------- /install-game.sh: -------------------------------------------------------------------------------- 1 | time ansible-playbook -i inventory/inventory.cfg install-game.yml -------------------------------------------------------------------------------- /install-game.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Provision Summit Balloon Game 3 | hosts: local 4 | 5 | vars_files: 6 | - vars/game-config.yml 7 | 8 | roles: 9 | - setup-achievement-server 10 | - setup-score-server 11 | - setup-game-server 12 | - setup-game-app 13 | - setup-admin-app 14 | - setup-scoreboard-app 15 | - setup-leaderboard-app 16 | - {role: wait-client-apps, when: parallel_build} 17 | - setup-cicd 18 | 19 | pre_tasks: 20 | 21 | - name: Login to openshift as admin 22 | command: "oc login --insecure-skip-tls-verify=true -u {{admin_username}} -p {{admin_password}} {{master_url}}" 23 | 24 | - name: Install ephemeral postgresSQL template 25 | command: "oc apply -f https://raw.githubusercontent.com/luciddreamz/library/master/official/postgresql/templates/postgresql-ephemeral.json -n openshift" 26 | ignore_errors: true 27 | 28 | - name: Install Jboss Image Streams 29 | command: "oc apply -f https://raw.githubusercontent.com/openshift/openshift-ansible/master/roles/openshift_examples/files/examples/v3.7/xpaas-streams/jboss-image-streams.json -n openshift" 30 | ignore_errors: true 31 | 32 | - name: Install BRMS ImageStream 33 | command: "oc apply -f https://raw.githubusercontent.com/openshift/openshift-ansible/release-3.9/roles/openshift_examples/files/examples/v3.9/xpaas-streams/decisionserver64-image-stream.json -n openshift" 34 | ignore_errors: true 35 | 36 | - name: Install BRMS template 37 | command: "oc apply -f https://raw.githubusercontent.com/openshift/openshift-ansible/release-3.9/roles/openshift_examples/files/examples/v3.9/xpaas-templates/decisionserver64-basic-s2i.json -n openshift" 38 | ignore_errors: true 39 | 40 | - name: Install Java S2I ImageStream 41 | command: "oc apply -f https://raw.githubusercontent.com/openshift/openshift-ansible/release-3.9/roles/openshift_examples/files/examples/v3.9/xpaas-streams/openjdk18-image-stream.json -n openshift" 42 | ignore_errors: true 43 | 44 | - name: Login to openshift as user 45 | command: "oc login --insecure-skip-tls-verify=true -u {{username}} -p {{password}} {{master_url}}" 46 | 47 | - name: Create openshift project 48 | command: "oc new-project {{project_name}} --display-name='Summit Balloon Game' --description='Multiplayer mobile balloon game from 2016 Red Hat Summit'" 49 | 50 | - name: Create authentication token secret 51 | command: "oc create secret generic game-auth --from-literal=token={{auth_token}}" 52 | 53 | # - name: Add view role to support kubernetes discovery for system:serviceaccounts:summit-game group 54 | # command: "oc policy add-role-to-group view system:serviceaccounts:{{project_name}} -n {{project_name}}" 55 | # ignore_errors: true 56 | 57 | - name: Update default service account to enable kube API access for infinispan clustering 58 | shell: "oc policy add-role-to-user view system:serviceaccount:$(oc project -q):default -n $(oc project -q)" 59 | 60 | - name: Set empty Maven Mirror variable 61 | set_fact: 62 | maven_mirror_url: "" 63 | when: maven_mirror_url is not defined 64 | -------------------------------------------------------------------------------- /inventory/inventory.cfg: -------------------------------------------------------------------------------- 1 | [local] 2 | localhost ansible_connection=local ansible_python_interpreter=python 3 | -------------------------------------------------------------------------------- /roles/setup-achievement-server/files/achievement-server-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "Template", 3 | "apiVersion": "v1", 4 | "metadata": { 5 | "annotations": { 6 | "iconClass": "icon-jboss", 7 | "description": "Application template for Summit vertx achievement server", 8 | "tags": "java,xpaas", 9 | "version": "1.0.0", 10 | "openshift.io/display-name": "Summit Achievement Server" 11 | }, 12 | "name": "achievement" 13 | }, 14 | "labels": { 15 | "template": "achievement" 16 | }, 17 | "message": "A new Summit achievement server has been created in your project.", 18 | "parameters": [ 19 | { 20 | "description": "The name for the application.", 21 | "displayName": "Application Name", 22 | "name": "APPLICATION_NAME", 23 | "value": "achievement", 24 | "required": true 25 | }, 26 | { 27 | "description": "Custom hostname for http service route. Leave blank for default hostname, e.g.: -.", 28 | "displayName": "Custom http Route Hostname", 29 | "name": "HOSTNAME_HTTP", 30 | "value": "", 31 | "required": false 32 | }, 33 | { 34 | "description": "Git source URI for application", 35 | "displayName": "Git Repository URL", 36 | "name": "SOURCE_REPOSITORY_URL", 37 | "value": "https://github.com/burrsutter/vertx-achievement-service", 38 | "required": true 39 | }, 40 | { 41 | "description": "Git branch/tag reference", 42 | "displayName": "Git Reference", 43 | "name": "SOURCE_REPOSITORY_REF", 44 | "value": "master", 45 | "required": false 46 | }, 47 | { 48 | "description": "Path within Git project to build; empty for root project directory.", 49 | "displayName": "Context Directory", 50 | "name": "CONTEXT_DIR", 51 | "value": "", 52 | "required": false 53 | }, 54 | { 55 | "description": "GitHub trigger secret", 56 | "displayName": "Github Webhook Secret", 57 | "name": "GITHUB_WEBHOOK_SECRET", 58 | "from": "[a-zA-Z0-9]{8}", 59 | "generate": "expression", 60 | "required": true 61 | }, 62 | { 63 | "description": "Generic build trigger secret", 64 | "displayName": "Generic Webhook Secret", 65 | "name": "GENERIC_WEBHOOK_SECRET", 66 | "from": "[a-zA-Z0-9]{8}", 67 | "generate": "expression", 68 | "required": true 69 | }, 70 | { 71 | "description": "Namespace in which the ImageStreams for Red Hat Middleware images are installed. These ImageStreams are normally installed in the openshift namespace. You should only need to modify this if you've installed the ImageStreams in a different namespace/project.", 72 | "displayName": "ImageStream Namespace", 73 | "name": "IMAGE_STREAM_NAMESPACE", 74 | "value": "openshift", 75 | "required": true 76 | } 77 | ], 78 | "objects": [ 79 | { 80 | "kind": "Service", 81 | "apiVersion": "v1", 82 | "spec": { 83 | "ports": [ 84 | { 85 | "port": 9090, 86 | "targetPort": 9090 87 | } 88 | ], 89 | "selector": { 90 | "deploymentConfig": "${APPLICATION_NAME}" 91 | } 92 | }, 93 | "metadata": { 94 | "name": "${APPLICATION_NAME}", 95 | "labels": { 96 | "application": "${APPLICATION_NAME}" 97 | }, 98 | "annotations": { 99 | "description": "The application's http port." 100 | } 101 | } 102 | }, 103 | { 104 | "kind": "Route", 105 | "apiVersion": "v1", 106 | "id": "${APPLICATION_NAME}-http", 107 | "metadata": { 108 | "name": "${APPLICATION_NAME}", 109 | "labels": { 110 | "application": "${APPLICATION_NAME}" 111 | }, 112 | "annotations": { 113 | "description": "Route for application's http service." 114 | } 115 | }, 116 | "spec": { 117 | "host": "${HOSTNAME_HTTP}", 118 | "to": { 119 | "name": "${APPLICATION_NAME}" 120 | } 121 | } 122 | }, 123 | { 124 | "kind": "ImageStream", 125 | "apiVersion": "v1", 126 | "metadata": { 127 | "name": "${APPLICATION_NAME}", 128 | "labels": { 129 | "application": "${APPLICATION_NAME}" 130 | } 131 | } 132 | }, 133 | { 134 | "kind": "BuildConfig", 135 | "apiVersion": "v1", 136 | "metadata": { 137 | "name": "${APPLICATION_NAME}", 138 | "labels": { 139 | "application": "${APPLICATION_NAME}" 140 | } 141 | }, 142 | "spec": { 143 | "source": { 144 | "type": "Git", 145 | "git": { 146 | "uri": "${SOURCE_REPOSITORY_URL}", 147 | "ref": "${SOURCE_REPOSITORY_REF}" 148 | }, 149 | "contextDir": "${CONTEXT_DIR}" 150 | }, 151 | "strategy": { 152 | "type": "Source", 153 | "sourceStrategy": { 154 | "forcePull": true, 155 | "from": { 156 | "kind": "ImageStreamTag", 157 | "namespace": "${IMAGE_STREAM_NAMESPACE}", 158 | "name": "redhat-openjdk18-openshift:1.4" 159 | } 160 | } 161 | }, 162 | "output": { 163 | "to": { 164 | "kind": "ImageStreamTag", 165 | "name": "${APPLICATION_NAME}:latest" 166 | } 167 | }, 168 | "triggers": [ 169 | { 170 | "type": "GitHub", 171 | "github": { 172 | "secret": "${GITHUB_WEBHOOK_SECRET}" 173 | } 174 | }, 175 | { 176 | "type": "Generic", 177 | "generic": { 178 | "secret": "${GENERIC_WEBHOOK_SECRET}" 179 | } 180 | }, 181 | { 182 | "type": "ImageChange", 183 | "imageChange": {} 184 | }, 185 | { 186 | "type": "ConfigChange" 187 | } 188 | ] 189 | } 190 | }, 191 | { 192 | "kind": "DeploymentConfig", 193 | "apiVersion": "v1", 194 | "metadata": { 195 | "name": "${APPLICATION_NAME}", 196 | "labels": { 197 | "application": "${APPLICATION_NAME}" 198 | } 199 | }, 200 | "spec": { 201 | "strategy": { 202 | "type": "Recreate" 203 | }, 204 | "triggers": [ 205 | { 206 | "type": "ImageChange", 207 | "imageChangeParams": { 208 | "automatic": true, 209 | "containerNames": [ 210 | "${APPLICATION_NAME}" 211 | ], 212 | "from": { 213 | "kind": "ImageStreamTag", 214 | "name": "${APPLICATION_NAME}:latest" 215 | } 216 | } 217 | }, 218 | { 219 | "type": "ConfigChange" 220 | } 221 | ], 222 | "replicas": 1, 223 | "selector": { 224 | "deploymentConfig": "${APPLICATION_NAME}" 225 | }, 226 | "template": { 227 | "metadata": { 228 | "name": "${APPLICATION_NAME}", 229 | "labels": { 230 | "deploymentConfig": "${APPLICATION_NAME}", 231 | "application": "${APPLICATION_NAME}", 232 | "vertx-cluster": "true" 233 | } 234 | }, 235 | "spec": { 236 | "terminationGracePeriodSeconds": 75, 237 | "containers": [ 238 | { 239 | "name": "${APPLICATION_NAME}", 240 | "image": "${APPLICATION_NAME}", 241 | "imagePullPolicy": "Always", 242 | "env": [ 243 | { 244 | "name": "JAVA_APP_JAR", 245 | "value": "vertx-achievement-server-1.0-SNAPSHOT-fat.jar" 246 | } 247 | ], 248 | "ports": [ 249 | { 250 | "name": "jolokia", 251 | "containerPort": 8778, 252 | "protocol": "TCP" 253 | }, 254 | { 255 | "name": "http", 256 | "containerPort": 9090, 257 | "protocol": "TCP" 258 | } 259 | ] 260 | } 261 | ] 262 | } 263 | } 264 | } 265 | } 266 | ] 267 | } -------------------------------------------------------------------------------- /roles/setup-achievement-server/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # - name: Create achievement server 3 | # command: "oc new-app --image-stream=openshift/redhat-openjdk18-openshift:1.1~{{ achievement_server_repo }} --name=achievement -e JAVA_APP_JAR=vertx-achievement-server-1.0-SNAPSHOT-fat.jar" 4 | 5 | - name: Create temporary file for template 6 | tempfile: 7 | state: file 8 | suffix: json 9 | register: template_path 10 | 11 | - name: Create achievement server 12 | command: "oc new-app -f roles/setup-achievement-server/files/achievement-server-template.json -p SOURCE_REPOSITORY_URL={{ achievement_server_repo }} --build-env MAVEN_MIRROR_URL={{maven_mirror_url}}" 13 | 14 | - name: Wait for achievement server to be ready 15 | command: "oc get ep achievement" 16 | register: result 17 | until: result.stdout.find("none") == -1 18 | retries: 50 19 | delay: 10 -------------------------------------------------------------------------------- /roles/setup-admin-app/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Setup up mobile-app-admin application 3 | command: "oc new-app openshift/nodejs:6~{{ mobile_admin_app_repo }}" 4 | 5 | - name: Expose route for mobile admin application 6 | command: "oc expose svc mobile-app-admin" 7 | 8 | - name: Create probes 9 | command: "oc set probe dc/mobile-app-admin --readiness --liveness --open-tcp=8080 --initial-delay-seconds=10" 10 | 11 | - name: Wait for mobile-app-admin deployment 12 | command: "oc get ep mobile-app-admin" 13 | register: result 14 | until: result.stdout.find("none") == -1 15 | retries: 50 16 | delay: 10 17 | when: not parallel_build -------------------------------------------------------------------------------- /roles/setup-cicd/files/pipeline.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Template 3 | labels: 4 | demo: summit-game 5 | template: gamebus-pipeline 6 | metadata: 7 | name: gamebus-pipeline 8 | objects: 9 | - apiVersion: v1 10 | kind: BuildConfig 11 | metadata: 12 | labels: 13 | build: ${PIPELINE_NAME} 14 | app: ${APPLICATION_NAME} 15 | name: ${PIPELINE_NAME} 16 | annotations: 17 | pipeline.alpha.openshift.io/uses: '[{"name": "${APPLICATION_NAME}", "kind": "BuildConfig"},{"name": "${APPLICATION_NAME}-blue", "kind": "DeploymentConfig"},{"name": "${APPLICATION_NAME}-green", "kind": "DeploymentConfig"}]' 18 | spec: 19 | runPolicy: Serial 20 | strategy: 21 | jenkinsPipelineStrategy: 22 | jenkinsfile: |- 23 | node ('maven') { 24 | stage 'Build' 25 | openshiftBuild(buildConfig: 'gamebus', namespace: '${PROJECT_NAME}', showBuildLogs: 'true') 26 | openshiftVerifyBuild(buildConfig: 'gamebus', namespace: '${PROJECT_NAME}', waitTime: 900000) 27 | } 28 | 29 | def tag="blue" 30 | def altTag="green" 31 | 32 | node { 33 | stage 'Deploy to Not Live' 34 | sh "oc get route gamebus -n ${PROJECT_NAME} -o jsonpath='{ .spec.to.name }' > activeservice" 35 | activeService = readFile('activeservice').trim() 36 | if (activeService == "gamebus-blue") { 37 | tag = "green" 38 | altTag = "blue" 39 | } 40 | 41 | openshiftTag(sourceStream: 'gamebus', sourceTag: 'latest', namespace: '${PROJECT_NAME}', destinationStream: 'gamebus', destinationTag: "${tag}", destinationNamespace: '${PROJECT_NAME}') 42 | sleep 5 43 | openshiftVerifyDeployment(deploymentConfig: "gamebus-${tag}", replicaCount: '${REPLICA_COUNT}', verifyReplicaCount: true, namespace: '${PROJECT_NAME}') 44 | 45 | stage 'Smoke Tests in PROD (Not Live)' 46 | sleep 5 47 | } 48 | 49 | stage 'Approve Go Live' 50 | timeout(time:30, unit:'MINUTES') { 51 | input message:'Go Live (switch to new version)?' 52 | } 53 | 54 | node { 55 | stage 'Go Live' 56 | sh "oc set route-backends gamebus gamebus-${tag}=100 gamebus-${altTag}=0 -n ${PROJECT_NAME}" 57 | sh "oc set route-backends gamebus-boards gamebus-${tag}-boards=100 gamebus-${altTag}-boards=0 -n ${PROJECT_NAME}" 58 | 59 | sh "oc label svc gamebus-${altTag} app-state=idle --overwrite -n ${PROJECT_NAME}" 60 | sh "oc label svc gamebus-${tag} app-state=live --overwrite -n ${PROJECT_NAME}" 61 | sleep 5 62 | 63 | stage 'Request Reconnect' 64 | sh "curl -H 'Content-Type: application/json' -X POST -d '{\"type\":\"reconnect\",\"token\":\"${AUTH_TOKEN}\"}' http://gamebus-${altTag}:9001/reconnect" 65 | 66 | sleep 5 67 | } 68 | type: JenkinsPipeline 69 | triggers: 70 | - github: 71 | secret: ${GITHUB_WEBHOOK_SECRET} 72 | type: GitHub 73 | - generic: 74 | secret: ${GENERIC_WEBHOOK_SECRET} 75 | type: Generic 76 | parameters: 77 | - description: The name of the application 78 | displayName: Application Name 79 | name: APPLICATION_NAME 80 | required: true 81 | value: gamebus 82 | - description: The name for the pipeline. 83 | displayName: Pipeline Name 84 | name: PIPELINE_NAME 85 | required: true 86 | value: gamebus-pipeline 87 | - description: Project Name 88 | displayName: Project Name 89 | name: PROJECT_NAME 90 | value: summit-game 91 | required: true 92 | - description: GitHub webhook secret 93 | displayName: GitHub Webhook Secret 94 | from: '[a-zA-Z0-9]{8}' 95 | generate: expression 96 | name: GITHUB_WEBHOOK_SECRET 97 | required: true 98 | - description: Generic webhook secret 99 | displayName: Generic Webhook Secret 100 | from: '[a-zA-Z0-9]{8}' 101 | generate: expression 102 | name: GENERIC_WEBHOOK_SECRET 103 | required: true 104 | - description: The number of gamebus replicas 105 | displayName: Replica Count 106 | name: REPLICA_COUNT 107 | required: false 108 | value: '1' 109 | - description: Authentication token 110 | displayName: Authentication token 111 | name: AUTH_TOKEN 112 | required: true 113 | value: 'CH2UsJePthRWTmLI8EY6' 114 | 115 | -------------------------------------------------------------------------------- /roles/setup-cicd/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Install Jenkins 3 | command: "oc new-app jenkins-ephemeral" 4 | 5 | - name: Install pipeline 6 | shell: "oc process -p APPLICATION_NAME=gamebus -p AUTH_TOKEN={{auth_token}} -p REPLICA_COUNT={{gamebus_replica_count}} -p PROJECT_NAME={{project_name}} -f roles/setup-cicd/files/pipeline.yml | oc create -f -" -------------------------------------------------------------------------------- /roles/setup-game-app/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create mobile game application 3 | command: "oc new-app openshift/nodejs:6~{{ mobile_app_repo }}" 4 | 5 | - name: Expose route for mobile app application 6 | command: "oc expose svc mobile-app" 7 | 8 | - name: Create probes 9 | command: "oc set probe dc/mobile-app --readiness --liveness --open-tcp=8080 --initial-delay-seconds=10" 10 | 11 | - name: Wait for mobile-app deployment 12 | command: "oc get ep mobile-app" 13 | register: result 14 | until: result.stdout.find("none") == -1 15 | retries: 50 16 | delay: 10 17 | when: not parallel_build -------------------------------------------------------------------------------- /roles/setup-game-server/files/game-server-build.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "Template", 3 | "apiVersion": "v1", 4 | "metadata": { 5 | "annotations": { 6 | "iconClass": "icon-java", 7 | "description": "Build template for Summit game bus", 8 | "tags": "java", 9 | "version": "1.0.0", 10 | "openshift.io/display-name": "Summit Game Bus" 11 | }, 12 | "name": "gamebus-build" 13 | }, 14 | "labels": { 15 | "template": "gamebus" 16 | }, 17 | "message": "A new Summit game build has been created in your project.", 18 | "parameters": [ 19 | { 20 | "description": "The name for the application.", 21 | "displayName": "Application Name", 22 | "name": "APPLICATION_NAME", 23 | "value": "gamebus", 24 | "required": true 25 | }, 26 | { 27 | "description": "Git source URI for application", 28 | "displayName": "Git Repository URL", 29 | "name": "SOURCE_REPOSITORY_URL", 30 | "value": "https://github.com/burrsutter/vertx-game-server", 31 | "required": true 32 | }, 33 | { 34 | "description": "Git branch/tag reference", 35 | "displayName": "Git Reference", 36 | "name": "SOURCE_REPOSITORY_REF", 37 | "value": "master", 38 | "required": false 39 | }, 40 | { 41 | "description": "Path within Git project to build; empty for root project directory.", 42 | "displayName": "Context Directory", 43 | "name": "CONTEXT_DIR", 44 | "value": "", 45 | "required": false 46 | }, 47 | { 48 | "description": "GitHub trigger secret", 49 | "displayName": "Github Webhook Secret", 50 | "name": "GITHUB_WEBHOOK_SECRET", 51 | "from": "[a-zA-Z0-9]{8}", 52 | "generate": "expression", 53 | "required": true 54 | }, 55 | { 56 | "description": "Generic build trigger secret", 57 | "displayName": "Generic Webhook Secret", 58 | "name": "GENERIC_WEBHOOK_SECRET", 59 | "from": "[a-zA-Z0-9]{8}", 60 | "generate": "expression", 61 | "required": true 62 | }, 63 | { 64 | "description": "Namespace in which the ImageStreams for Red Hat Middleware images are installed. These ImageStreams are normally installed in the openshift namespace. You should only need to modify this if you've installed the ImageStreams in a different namespace/project.", 65 | "displayName": "ImageStream Namespace", 66 | "name": "IMAGE_STREAM_NAMESPACE", 67 | "value": "openshift", 68 | "required": true 69 | }, 70 | { 71 | "description": "Maven Mirror URL", 72 | "displayName": "Maven Mirror URL", 73 | "name": "MAVEN_MIRROR_URL", 74 | "required": false 75 | } 76 | ], 77 | "objects": [ 78 | { 79 | "kind": "ImageStream", 80 | "apiVersion": "v1", 81 | "metadata": { 82 | "name": "${APPLICATION_NAME}", 83 | "labels": { 84 | "app": "${APPLICATION_NAME}" 85 | } 86 | } 87 | }, 88 | { 89 | "kind": "BuildConfig", 90 | "apiVersion": "v1", 91 | "metadata": { 92 | "name": "${APPLICATION_NAME}", 93 | "labels": { 94 | "app": "${APPLICATION_NAME}" 95 | } 96 | }, 97 | "spec": { 98 | "source": { 99 | "type": "Git", 100 | "git": { 101 | "uri": "${SOURCE_REPOSITORY_URL}", 102 | "ref": "${SOURCE_REPOSITORY_REF}" 103 | }, 104 | "contextDir": "${CONTEXT_DIR}" 105 | }, 106 | "strategy": { 107 | "type": "Source", 108 | "sourceStrategy": { 109 | "env": [ 110 | { 111 | "name": "MAVEN_MIRROR_URL", 112 | "value": "${MAVEN_MIRROR_URL}" 113 | } 114 | ], 115 | "forcePull": true, 116 | "from": { 117 | "kind": "ImageStreamTag", 118 | "namespace": "${IMAGE_STREAM_NAMESPACE}", 119 | "name": "redhat-openjdk18-openshift:1.4" 120 | } 121 | } 122 | }, 123 | "output": { 124 | "to": { 125 | "kind": "ImageStreamTag", 126 | "name": "${APPLICATION_NAME}:latest" 127 | } 128 | }, 129 | "triggers": [ 130 | { 131 | "type": "GitHub", 132 | "github": { 133 | "secret": "${GITHUB_WEBHOOK_SECRET}" 134 | } 135 | }, 136 | { 137 | "type": "Generic", 138 | "generic": { 139 | "secret": "${GENERIC_WEBHOOK_SECRET}" 140 | } 141 | } 142 | ] 143 | } 144 | } 145 | ] 146 | } -------------------------------------------------------------------------------- /roles/setup-game-server/files/game-server-routes.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "Template", 3 | "apiVersion": "v1", 4 | "metadata": { 5 | "name": "gamebus-routes" 6 | }, 7 | "labels": { 8 | "template": "gamebus" 9 | }, 10 | "message": "New blue-green routes have been created for the application", 11 | "parameters": [ 12 | { 13 | "description": "The name for the application.", 14 | "displayName": "Application Name", 15 | "name": "APPLICATION_NAME", 16 | "value": "gamebus", 17 | "required": true 18 | }, 19 | { 20 | "description": "Custom hostname for http service route. Leave blank for default hostname, e.g.: -.", 21 | "displayName": "Custom http Route Hostname", 22 | "name": "HOSTNAME_HTTP", 23 | "value": "", 24 | "required": false 25 | }, 26 | { 27 | "description": "Custom hostname for http boards service route. Leave blank for default hostname, e.g.: -.", 28 | "name": "HOSTNAME_BOARDS_HTTP", 29 | "value": "", 30 | "required": false 31 | } 32 | ], 33 | "objects": [ 34 | { 35 | "apiVersion": "v1", 36 | "kind": "Route", 37 | "id": "${APPLICATION_NAME}-http", 38 | "metadata": { 39 | "name": "${APPLICATION_NAME}", 40 | "labels": { 41 | "app": "${APPLICATION_NAME}" 42 | }, 43 | "annotations": { 44 | "description": "Route for application's http service." 45 | } 46 | }, 47 | "spec": { 48 | "host": "${HOSTNAME_HTTP}", 49 | "alternateBackends": [ 50 | { 51 | "kind": "Service", 52 | "name": "${APPLICATION_NAME}-green", 53 | "weight": 0 54 | } 55 | ], 56 | "to": { 57 | "kind": "Service", 58 | "name": "${APPLICATION_NAME}-blue", 59 | "weight": 1 60 | } 61 | } 62 | }, 63 | { 64 | "apiVersion": "v1", 65 | "kind": "Route", 66 | "id": "${APPLICATION_NAME}-boards", 67 | "metadata": { 68 | "name": "${APPLICATION_NAME}-boards", 69 | "labels": { 70 | "app": "${APPLICATION_NAME}" 71 | }, 72 | "annotations": { 73 | "description": "Route for application's board service." 74 | } 75 | }, 76 | "spec": { 77 | "host": "${HOSTNAME_BOARDS_HTTP}", 78 | "alternateBackends": [ 79 | { 80 | "kind": "Service", 81 | "name": "${APPLICATION_NAME}-green-boards", 82 | "weight": 0 83 | } 84 | ], 85 | "to": { 86 | "kind": "Service", 87 | "name": "${APPLICATION_NAME}-blue-boards", 88 | "weight": 1 89 | } 90 | } 91 | } 92 | ] 93 | } 94 | -------------------------------------------------------------------------------- /roles/setup-game-server/files/game-server-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "Template", 3 | "apiVersion": "v1", 4 | "metadata": { 5 | "annotations": { 6 | "iconClass": "icon-java", 7 | "description": "Application template for Summit game bus", 8 | "tags": "java", 9 | "version": "1.0.0", 10 | "openshift.io/display-name": "Summit Game Bus" 11 | }, 12 | "name": "gamebus" 13 | }, 14 | "labels": { 15 | "template": "gamebus" 16 | }, 17 | "message": "A new Summit game server has been created in your project.", 18 | "parameters": [ 19 | { 20 | "description": "The name for the application.", 21 | "displayName": "Application Name", 22 | "name": "APPLICATION_NAME", 23 | "value": "gamebus", 24 | "required": true 25 | }, 26 | { 27 | "description": "The namespace the template resources will be created in", 28 | "displayName": "Namespace", 29 | "name": "NAMESPACE", 30 | "value": "", 31 | "required": true 32 | }, 33 | { 34 | "description": "Deployment color (i.e. default, blue, green or canary)", 35 | "displayName": "Color", 36 | "name": "COLOR", 37 | "value": "default", 38 | "required": true 39 | }, 40 | { 41 | "description": "Number of replicas to deploy", 42 | "displayName": "Replica Count", 43 | "name": "REPLICA_COUNT", 44 | "value": "1", 45 | "required": false 46 | }, 47 | { 48 | "description": "Maven Mirror URL", 49 | "displayName": "Maven Mirror URL", 50 | "name": "MAVEN_MIRROR_URL", 51 | "required": false 52 | }, 53 | { 54 | "description": "The username for the Score server", 55 | "displayName": "Score Username", 56 | "name": "SCORE_USERNAME", 57 | "value": "kieserver", 58 | "required": true 59 | }, 60 | { 61 | "description": "The password for the Score server", 62 | "displayName": "Score Password", 63 | "name": "SCORE_PASSWORD", 64 | "value": "ki3server@", 65 | "required": true 66 | } 67 | ], 68 | "objects": [ 69 | { 70 | "kind": "Service", 71 | "apiVersion": "v1", 72 | "spec": { 73 | "ports": [ 74 | { 75 | "port": 9001, 76 | "targetPort": 9001 77 | } 78 | ], 79 | "selector": { 80 | "deploymentConfig": "${APPLICATION_NAME}-${COLOR}" 81 | } 82 | }, 83 | "metadata": { 84 | "name": "${APPLICATION_NAME}-${COLOR}", 85 | "labels": { 86 | "app": "${APPLICATION_NAME}", 87 | "variant": "${COLOR}" 88 | }, 89 | "annotations": { 90 | "description": "The application's http port." 91 | } 92 | } 93 | }, 94 | { 95 | "kind": "Service", 96 | "apiVersion": "v1", 97 | "spec": { 98 | "ports": [ 99 | { 100 | "port": 9002, 101 | "targetPort": 9002 102 | } 103 | ], 104 | "selector": { 105 | "deploymentConfig": "${APPLICATION_NAME}-${COLOR}" 106 | } 107 | }, 108 | "metadata": { 109 | "name": "${APPLICATION_NAME}-${COLOR}-internal", 110 | "labels": { 111 | "app": "${APPLICATION_NAME}", 112 | "variant": "${COLOR}" 113 | }, 114 | "annotations": { 115 | "description": "The web server's internal http port." 116 | } 117 | } 118 | }, 119 | { 120 | "kind": "Service", 121 | "apiVersion": "v1", 122 | "spec": { 123 | "ports": [ 124 | { 125 | "port": 9003, 126 | "targetPort": 9003 127 | } 128 | ], 129 | "selector": { 130 | "deploymentConfig": "${APPLICATION_NAME}-${COLOR}" 131 | } 132 | }, 133 | "metadata": { 134 | "name": "${APPLICATION_NAME}-${COLOR}-traffic", 135 | "labels": { 136 | "app": "${APPLICATION_NAME}", 137 | "variant": "${COLOR}" 138 | }, 139 | "annotations": { 140 | "description": "The web server's traffic port." 141 | } 142 | } 143 | }, 144 | { 145 | "kind": "Service", 146 | "apiVersion": "v1", 147 | "spec": { 148 | "ports": [ 149 | { 150 | "port": 9004, 151 | "targetPort": 9004 152 | } 153 | ], 154 | "selector": { 155 | "deploymentConfig": "${APPLICATION_NAME}-${COLOR}" 156 | } 157 | }, 158 | "metadata": { 159 | "name": "${APPLICATION_NAME}-${COLOR}-boards", 160 | "labels": { 161 | "app": "${APPLICATION_NAME}", 162 | "variant": "${COLOR}" 163 | }, 164 | "annotations": { 165 | "description": "The web server's leaderboard and scoreboard port." 166 | } 167 | } 168 | }, 169 | { 170 | "kind": "DeploymentConfig", 171 | "apiVersion": "v1", 172 | "metadata": { 173 | "name": "${APPLICATION_NAME}-${COLOR}", 174 | "labels": { 175 | "app": "${APPLICATION_NAME}", 176 | "variant": "${COLOR}" 177 | } 178 | }, 179 | "spec": { 180 | "strategy": { 181 | "type": "Rolling", 182 | "rollingParams": { 183 | "timeoutSeconds": 60 184 | } 185 | }, 186 | "triggers": [ 187 | { 188 | "type": "ImageChange", 189 | "imageChangeParams": { 190 | "automatic": true, 191 | "containerNames": [ 192 | "${APPLICATION_NAME}-${COLOR}" 193 | ], 194 | "from": { 195 | "kind": "ImageStreamTag", 196 | "name": "${APPLICATION_NAME}:${COLOR}" 197 | } 198 | } 199 | }, 200 | { 201 | "type": "ConfigChange" 202 | } 203 | ], 204 | "replicas": "${REPLICA_COUNT}", 205 | "selector": { 206 | "deploymentConfig": "${APPLICATION_NAME}-${COLOR}" 207 | }, 208 | "template": { 209 | "metadata": { 210 | "name": "${APPLICATION_NAME}-${COLOR}", 211 | "labels": { 212 | "app": "${APPLICATION_NAME}", 213 | "variant": "${COLOR}", 214 | "deploymentConfig": "${APPLICATION_NAME}-${COLOR}", 215 | "vertx-cluster": "${APPLICATION_NAME}" 216 | } 217 | }, 218 | "spec": { 219 | "terminationGracePeriodSeconds": 75, 220 | "containers": [ 221 | { 222 | "name": "${APPLICATION_NAME}-${COLOR}", 223 | "image": " ", 224 | "imagePullPolicy": "Always", 225 | "livenessProbe": { 226 | "tcpSocket": { 227 | "port": 9001 228 | }, 229 | "initialDelaySeconds": 15, 230 | "timeoutSeconds": 1 231 | }, 232 | "readinessProbe": { 233 | "tcpSocket": { 234 | "port": 9001 235 | }, 236 | "initialDelaySeconds": 15, 237 | "timeoutSeconds": 1 238 | }, 239 | "env": [ 240 | { 241 | "name": "JAVA_APP_JAR", 242 | "value": "game-service-1.1.0-SNAPSHOT.jar" 243 | }, 244 | { 245 | "name": "JAVA_ARGS", 246 | "value": "-cluster" 247 | }, 248 | { 249 | "name": "SCORE_SERVER", 250 | "value": "http://score:8080/kie-server/services/rest/server/containers/instances/score" 251 | }, 252 | { 253 | "name": "SCORE_SERVER_PORT", 254 | "value": "8080" 255 | }, 256 | { 257 | "name": "ACHIEVEMENTS_SERVER", 258 | "value": "http://achievement:9090/api" 259 | }, 260 | { 261 | "name": "ACHIEVEMENTS_SERVER_PORT", 262 | "value": "9090" 263 | }, 264 | { 265 | "name": "JAVA_OPTIONS", 266 | "value": "-Dvertx.jgroups.config=default-configs/default-jgroups-kubernetes.xml -Djava.net.preferIPv4Stack=true" 267 | }, 268 | { 269 | "name": "SCORE_USER", 270 | "value": "${SCORE_USERNAME}" 271 | }, 272 | { 273 | "name": "SCORE_PASSWORD", 274 | "value": "${SCORE_PASSWORD}" 275 | }, 276 | { 277 | "name": "COLOR", 278 | "value": "${COLOR}" 279 | }, 280 | { 281 | "name": "KUBERNETES_LABELS", 282 | "value": "vertx-cluster=${APPLICATION_NAME}" 283 | }, 284 | { 285 | "name": "KUBERNETES_NAMESPACE", 286 | "value": "${NAMESPACE}" 287 | }, 288 | { 289 | "name": "AUTH_TOKEN", 290 | "valueFrom": { 291 | "secretKeyRef": { 292 | "key": "token", 293 | "name": "game-auth" 294 | } 295 | } 296 | } 297 | ], 298 | "ports": [ 299 | { 300 | "name": "jolokia", 301 | "containerPort": 8778, 302 | "protocol": "TCP" 303 | }, 304 | { 305 | "name": "http", 306 | "containerPort": 9001, 307 | "protocol": "TCP" 308 | }, 309 | { 310 | "name": "internal", 311 | "containerPort": 9002, 312 | "protocol": "TCP" 313 | }, 314 | { 315 | "name": "traffic", 316 | "containerPort": 9003, 317 | "protocol": "TCP" 318 | }, 319 | { 320 | "name": "boards", 321 | "containerPort": 9004, 322 | "protocol": "TCP" 323 | } 324 | ] 325 | } 326 | ] 327 | } 328 | } 329 | } 330 | } 331 | ] 332 | } -------------------------------------------------------------------------------- /roles/setup-game-server/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Create single build for both blue/green rather then separate apps 3 | - name: Create gamebus buildconfig 4 | shell: "oc process -p APPLICATION_NAME=gamebus -p SOURCE_REPOSITORY_URL={{ game_server_repo }} -p MAVEN_MIRROR_URL={{maven_mirror_url}} -f roles/setup-game-server/files/game-server-build.json | oc create -f -" 5 | 6 | - name: Start gamebus build and wait 7 | command: "oc start-build gamebus --wait=true" 8 | 9 | - name: Tag gamebus imagestream for colors 10 | shell: | 11 | oc tag {{project_name}}/gamebus:latest {{project_name}}/gamebus:green 12 | oc tag {{project_name}}/gamebus:latest {{project_name}}/gamebus:blue 13 | oc tag {{project_name}}/gamebus:latest -d 14 | 15 | - name: Create blue game server 16 | command: "oc new-app -f roles/setup-game-server/files/game-server-template.json -p COLOR=blue -p APPLICATION_NAME=gamebus -p REPLICA_COUNT={{gamebus_replica_count}} -p NAMESPACE={{project_name}} -p SCORE_USERNAME={{score_user}} -p SCORE_PASSWORD={{score_password}}" 17 | 18 | - name: Create green game server 19 | command: "oc new-app -f roles/setup-game-server/files/game-server-template.json -p COLOR=green -p APPLICATION_NAME=gamebus -p REPLICA_COUNT={{gamebus_replica_count}} -p NAMESPACE={{project_name}} -p SCORE_USERNAME={{score_user}} -p SCORE_PASSWORD={{score_password}}" 20 | 21 | - name: Wait for blue game server to be ready 22 | command: "oc get ep gamebus-blue" 23 | register: result 24 | until: result.stdout.find("none") == -1 25 | retries: 50 26 | delay: 10 27 | 28 | - name: Wait for green game server to be ready 29 | command: "oc get ep gamebus-green" 30 | register: result 31 | until: result.stdout.find("none") == -1 32 | retries: 50 33 | delay: 10 34 | 35 | - name: Create gamebus blue-green routes 36 | shell: | 37 | oc process -p APPLICATION_NAME=gamebus -f roles/setup-game-server/files/game-server-routes.json | oc create -f - 38 | oc annotate route/gamebus haproxy.router.openshift.io/balance=roundrobin 39 | oc annotate route/gamebus haproxy.router.openshift.io/disable_cookies=true -------------------------------------------------------------------------------- /roles/setup-leaderboard-app/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create leaderboard application 3 | command: "oc new-app openshift/nodejs:8~{{ leaderboard_repo }}" 4 | 5 | - name: Expose route for leaderboard application 6 | command: "oc expose svc leaderboard" 7 | 8 | - name: Wait for leaderboard deployment 9 | command: "oc get ep leaderboard" 10 | register: result 11 | until: result.stdout.find("none") == -1 12 | retries: 50 13 | delay: 10 14 | when: not parallel_build -------------------------------------------------------------------------------- /roles/setup-score-server/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Set score server database facts 3 | set_fact: 4 | score_db_name: "userdb" 5 | score_db_user: "keynote" 6 | score_db_password: "imEffH9QP8QcL" 7 | 8 | - name: Create score database server 9 | command: "oc new-app --template=postgresql-ephemeral -p POSTGRESQL_VERSION=9.5 -p DATABASE_SERVICE_NAME=score-postgresql -p POSTGRESQL_USER={{score_db_user}} -p POSTGRESQL_PASSWORD={{score_db_password}} -p POSTGRESQL_DATABASE={{score_db_name}}" 10 | 11 | - name: Wait for database server to be ready 12 | command: "oc get ep score-postgresql" 13 | register: result 14 | until: result.stdout.find("none") == -1 15 | retries: 10 16 | delay: 10 17 | 18 | - name: Create score server 19 | command: "oc new-app decisionserver64-basic-s2i -p APPLICATION_NAME=score -p SOURCE_REPOSITORY_URL={{ score_server_repo }} -p SOURCE_REPOSITORY_REF=master -p CONTEXT_DIR=score -p KIE_CONTAINER_DEPLOYMENT='score=com.redhatkeynote:score:1.0.0' -p KIE_SERVER_USER={{score_user}} -p KIE_SERVER_PASSWORD={{score_password}} -e DB_JNDI='java:jboss/datasources/KeynoteDS' -e DB_DATABASE={{score_db_name}} -e DB_USERNAME='{{score_db_user}}' -e DB_PASSWORD='{{score_db_password}}' -p MAVEN_MIRROR_URL={{maven_mirror_url}}" 20 | 21 | - name: Wait for score server to be ready 22 | command: "oc get ep score" 23 | register: result 24 | until: result.stdout.find("none") == -1 25 | retries: 50 26 | delay: 20 27 | -------------------------------------------------------------------------------- /roles/setup-scoreboard-app/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create scoreboard application 3 | command: "oc new-app openshift/nodejs:6~{{ scoreboard_repo }}" 4 | 5 | - name: Expose route for scoreboard application 6 | command: "oc expose svc scoreboard" 7 | 8 | - name: Wait for scoreboard deployment 9 | command: "oc get ep scoreboard" 10 | register: result 11 | until: result.stdout.find("none") == -1 12 | retries: 50 13 | delay: 10 14 | when: not parallel_build -------------------------------------------------------------------------------- /roles/wait-client-apps/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: Wait for javascript applications to be ready 2 | command: "oc get ep {{item}}" 3 | register: result 4 | until: result.stdout.find("none") == -1 5 | retries: 50 6 | delay: 15 7 | with_items: 8 | - mobile-app 9 | - mobile-app-admin 10 | - leaderboard 11 | - scoreboard -------------------------------------------------------------------------------- /vars/game-config.yml: -------------------------------------------------------------------------------- 1 | ################################################ 2 | # Minishift variables 3 | ################################################ 4 | master_url: https://127.0.0.1:8443 5 | username: developer 6 | password: developer 7 | 8 | admin_username: admin 9 | admin_password: admin 10 | 11 | ################################################ 12 | # ocplab.com variables 13 | ################################################ 14 | 15 | # master_url: https://ocplab.com:8443 16 | # username: user04 17 | # password: dummy 18 | 19 | # admin_username: admin 20 | # admin_password: dummy 21 | 22 | project_name: summit-game 23 | 24 | # Authorization token to use for admin client 25 | auth_token: CH2UsJePthRWTmLI8EY6 26 | 27 | # The number of replicas to use for each color. If this is set to 2 28 | # then blue will have 2 and green will have 2 for 4 total. 29 | gamebus_replica_count: 2 30 | 31 | # If you are installing on something other then a single node 32 | # cluster, set to true to deploy javascript apps in parallel 33 | parallel_build: false 34 | 35 | # Score server 36 | score_user: kieserver 37 | score_password: ki3server@ 38 | 39 | # Maven repository - set this to use a Maven Mirror for builds 40 | # maven_mirror_url: http://nexus.nexus:8081/content/groups/public 41 | 42 | # Repositories 43 | game_server_repo: https://github.com/gnunn1/vertx-game-server 44 | 45 | # Repo below instead of Burr's fixes hibernate issue when compiling 46 | score_server_repo: https://github.com/gnunn1/score-server 47 | 48 | # Note the achievement server was re-written from EAP to vert.x, this playbook expects the vert.x version 49 | achievement_server_repo: https://github.com/burrsutter/vertx-achievement-service 50 | 51 | # Repo uses a URL based on location so it doesn't have to be changed anymore 52 | mobile_app_repo: https://github.com/gnunn1/mobile-app 53 | 54 | # Repo uses a URL based on location so it doesn't have to be changed anymore 55 | mobile_admin_app_repo: https://github.com/gnunn1/mobile-app-admin 56 | 57 | # Repo uses a URL based on location so it doesn't have to be changed anymore 58 | scoreboard_repo: https://github.com/gnunn1/scoreboard 59 | 60 | # Repo uses a URL based on location so it doesn't have to be changed anymore 61 | leaderboard_repo: https://github.com/gnunn1/leaderboard 62 | --------------------------------------------------------------------------------