##// END OF EJS Templates
Ready for talk...
jeandet -
r1:0ea387ce654c
parent child
Show More
@@ -0,0 +1,73
1 import requests
2 import traceback
3 import configparser
4 from os.path import expanduser
5 home = expanduser("~")
6
7 class TeamCityJsonObject:
8
9 def __init__(self, json):
10 self.__dict__.update(json)
11
12 def __repr__(self):
13 return str(self.__dict__)
14
15
16 class TeamCityProject(TeamCityJsonObject):
17
18 def __init__(self, json):
19 super(TeamCityProject, self).__init__(json)
20
21
22 class TeamCityBuildType(TeamCityJsonObject):
23
24 def __init__(self, json):
25 super(TeamCityBuildType, self).__init__(json)
26
27 class TeamCityBuild(TeamCityJsonObject):
28
29 def __init__(self, json):
30 super(TeamCityBuild, self).__init__(json)
31
32
33 class TeamCityAPI:
34
35 def __init__(self, server, user, password):
36 self.server = server if '/app/rest' in server else server + '/app/rest'
37 self.session = requests.Session()
38 self.session.auth = (user, password)
39 self.session.headers.update({
40 'Accept': 'application/json',
41 'Content-Type': 'application/json'
42 })
43
44 def projects(self):
45 projects = self.session.get(
46 self.server + '/projects').json()
47 return [TeamCityProject(project) for project in projects['project']]
48
49 def build_types(self, project_id=None, project_name=None):
50 if project_id is not None:
51 url = self.server + '/projects/id:' + project_id + '/buildTypes'
52 elif project_name is not None:
53 url = self.server + '/projects/name:' + project_id + '/buildTypes'
54 else:
55 url = self.server + '/buildTypes'
56 build_types = self.session.get(url).json()
57 return [
58 TeamCityBuildType(build_type)
59 for build_type in build_types['buildType']
60 ]
61
62 def build_queue(self):
63 build_queue = self.session.get(tc.server+'/buildQueue').json()
64 return [
65 TeamCityBuild(build)
66 for build in build_queue['build']
67 ]
68
69 config = configparser.ConfigParser()
70 config.read(home+"/.teamcity.conf")
71
72
73 tc = TeamCityAPI(config['DEFAULT']['server'], config['DEFAULT']['user'],config['DEFAULT']['password']) No newline at end of file
@@ -2,11 +2,11
2 "cells": [
2 "cells": [
3 {
3 {
4 "cell_type": "code",
4 "cell_type": "code",
5 "execution_count": 1,
5 "execution_count": 21,
6 "metadata": {
6 "metadata": {
7 "ExecuteTime": {
7 "ExecuteTime": {
8 "end_time": "2018-01-08T23:20:39.306357Z",
8 "end_time": "2018-01-09T08:09:49.457463Z",
9 "start_time": "2018-01-08T23:20:39.297432Z"
9 "start_time": "2018-01-09T08:09:49.451783Z"
10 },
10 },
11 "init_cell": true
11 "init_cell": true
12 },
12 },
@@ -52,8 +52,10
52 "* Rich plugin ecosystem\n",
52 "* Rich plugin ecosystem\n",
53 "* Really customizable system\n",
53 "* Really customizable system\n",
54 "* Not so complex...\n",
54 "* Not so complex...\n",
55 "* Updates so easy (Compared to redmine...)\n",
55 "* Mostly written in Java\n",
56 "* Mostly written in Java\n",
56 "* Closed source :("
57 "* Closed source :(\n",
58 "* Limited to 100 build cfg & 3 agents "
57 ]
59 ]
58 },
60 },
59 {
61 {
@@ -143,10 +145,12
143 "cell_type": "markdown",
145 "cell_type": "markdown",
144 "metadata": {
146 "metadata": {
145 "slideshow": {
147 "slideshow": {
146 "slide_type": "fragment"
148 "slide_type": "subslide"
147 }
149 }
148 },
150 },
149 "source": [
151 "source": [
152 "# Vocabulary\n",
153 "\n",
150 "* **Build artifact**: <span style=\"color:blue\">a file or a folder produced during the build </span> ( [example](https://hephaistos.lpp.polytechnique.fr/teamcity/overview.html) )"
154 "* **Build artifact**: <span style=\"color:blue\">a file or a folder produced during the build </span> ( [example](https://hephaistos.lpp.polytechnique.fr/teamcity/overview.html) )"
151 ]
155 ]
152 },
156 },
@@ -154,6 +158,22
154 "cell_type": "markdown",
158 "cell_type": "markdown",
155 "metadata": {
159 "metadata": {
156 "slideshow": {
160 "slideshow": {
161 "slide_type": "fragment"
162 }
163 },
164 "source": [
165 "\n",
166 "\n",
167 "\n",
168 "\n",
169 "\n",
170 "* **Meta-Runners**: <span style=\"color:blue\">a build config that has been extracted to make a template </span> ( [example](https://hephaistos.lpp.polytechnique.fr/teamcity/admin/editProject.html?projectId=_Root&tab=metaRunner) )"
171 ]
172 },
173 {
174 "cell_type": "markdown",
175 "metadata": {
176 "slideshow": {
157 "slide_type": "slide"
177 "slide_type": "slide"
158 }
178 }
159 },
179 },
@@ -209,6 +229,17
209 "cell_type": "markdown",
229 "cell_type": "markdown",
210 "metadata": {
230 "metadata": {
211 "slideshow": {
231 "slideshow": {
232 "slide_type": "subslide"
233 }
234 },
235 "source": [
236 "# LPP goals (What we want)"
237 ]
238 },
239 {
240 "cell_type": "markdown",
241 "metadata": {
242 "slideshow": {
212 "slide_type": "fragment"
243 "slide_type": "fragment"
213 }
244 }
214 },
245 },
@@ -220,6 +251,17
220 "cell_type": "markdown",
251 "cell_type": "markdown",
221 "metadata": {
252 "metadata": {
222 "slideshow": {
253 "slideshow": {
254 "slide_type": "fragment"
255 }
256 },
257 "source": [
258 "* Give users maximum freedom"
259 ]
260 },
261 {
262 "cell_type": "markdown",
263 "metadata": {
264 "slideshow": {
223 "slide_type": "slide"
265 "slide_type": "slide"
224 }
266 }
225 },
267 },
@@ -232,11 +274,15
232 },
274 },
233 {
275 {
234 "cell_type": "markdown",
276 "cell_type": "markdown",
235 "metadata": {},
277 "metadata": {
278 "slideshow": {
279 "slide_type": "slide"
280 }
281 },
236 "source": [
282 "source": [
237 "# Available build agents\n",
283 "# Available build agents\n",
238 "\n",
284 "\n",
239 "* Based on Docker cloud plugin\n",
285 "* Based on [Docker cloud plugin](https://plugins.jetbrains.com/plugin/9306-docker-cloud)\n",
240 "* Virtually anything that runs either inside **Docker** or **VirtualBox**(Vagrant)\n",
286 "* Virtually anything that runs either inside **Docker** or **VirtualBox**(Vagrant)\n",
241 "* Spawn on demand\n",
287 "* Spawn on demand\n",
242 "* For now **Windows**, **Linux**(Fedora, Ubuntu), **FreeBSD** and **Mac OSX** 10.12.2(Siera)\n"
288 "* For now **Windows**, **Linux**(Fedora, Ubuntu), **FreeBSD** and **Mac OSX** 10.12.2(Siera)\n"
@@ -250,13 +296,33
250 }
296 }
251 },
297 },
252 "source": [
298 "source": [
299 "# FreeBSD & Mac \n",
300 "\n",
301 "[meson@lpp](https://hephaistos.lpp.polytechnique.fr/teamcity/viewLog.html?buildId=6388&tab=buildLog&buildTypeId=mesonbuild_Build_2&logTab=tree&filter=all) [meson@travis](https://travis-ci.org/mesonbuild/meson/builds/325859215?utm_source=github_status&utm_medium=notification)\n",
302 "\n",
303 "[OSX agent](https://github.com/jeandet/teamcity-docker-agent-osx) [FreeBSD agent](https://github.com/jeandet/teamcity-docker-agent-freebsd)\n",
304 "\n",
305 "* Vagrant inside Docker\n",
306 "* Few txt files produces several GB machines\n",
307 "* Easy to deploy\n",
308 "* Hard to debug\n"
309 ]
310 },
311 {
312 "cell_type": "markdown",
313 "metadata": {
314 "slideshow": {
315 "slide_type": "slide"
316 }
317 },
318 "source": [
253 "# I want to choose where I get built!\n",
319 "# I want to choose where I get built!\n",
254 "\n",
320 "\n",
255 "**Team city introduce the notion of build requirements.**\n",
321 "**Team city introduce the notion of build requirements.**\n",
256 "\n",
322 "\n",
257 "- Agents expose [parameters](https://hephaistos.lpp.polytechnique.fr/teamcity/agentDetails.html?agentTypeId=72&tab=agentParameters)(<=> properties). [sources](https://github.com/jeandet/teamcity-docker-complete-agent/blob/master/Dockerfile#L36)\n",
323 "- Agents expose [parameters](https://hephaistos.lpp.polytechnique.fr/teamcity/agentDetails.html?agentTypeId=72&tab=agentParameters)(<=> properties). ( [sources](https://github.com/jeandet/teamcity-docker-complete-agent/blob/master/Dockerfile#L36) )\n",
258 "\n",
324 "\n",
259 "- So for each build config ones can declare some [requirements](https://hephaistos.lpp.polytechnique.fr/teamcity/admin/editRequirements.html?id=buildType:Miniphare_Build) that the agent has to match."
325 "- For each build config, ones can declare some [requirements](https://hephaistos.lpp.polytechnique.fr/teamcity/admin/editRequirements.html?id=buildType:Miniphare_Build) that the agent has to match to get spawned."
260 ]
326 ]
261 },
327 },
262 {
328 {
@@ -267,7 +333,13
267 }
333 }
268 },
334 },
269 "source": [
335 "source": [
270 "# What about reports?\n"
336 "# What about reports?\n",
337 "\n",
338 "* As build artifact ( [LFR](https://hephaistos.lpp.polytechnique.fr/teamcity/viewLog.html?buildId=292&tab=artifacts&buildTypeId=LfrFlightSoftware_Build), [Hephaistos Web](https://hephaistos.lpp.polytechnique.fr/teamcity/project.html?projectId=HephaistosWeb&tab=projectOverview), [LibCDF](https://hephaistos.lpp.polytechnique.fr/teamcity/project.html?projectId=LibCDF&tab=projectOverview) )\n",
339 "* As Mail\n",
340 "* As slack message\n",
341 "* As stdout values ( [GStreamer Ninja](https://hephaistos.lpp.polytechnique.fr/teamcity/admin/editRunType.html?id=buildType:mesonbuild_GStreamerNightly&runnerId=RUNNER_69&cameFromUrl=%2Fteamcity%2Fadmin%2FeditBuildRunners.html%3Fid%3DbuildType%253Amesonbuild_GStreamerNightly%26init%3D1&cameFromTitle=) )\n",
342 "* As XML File ( [LibCDF GTest](https://hephaistos.lpp.polytechnique.fr/teamcity/admin/editBuildFeatures.html?id=buildType:LibCDF_Build) )"
271 ]
343 ]
272 },
344 },
273 {
345 {
@@ -278,7 +350,13
278 }
350 }
279 },
351 },
280 "source": [
352 "source": [
281 "# API?"
353 "# Interactions with other tools\n",
354 "\n",
355 "* SonarQube ([example](https://sonarcloud.io/dashboard?id=sciqlop), [config](https://hephaistos.lpp.polytechnique.fr/teamcity/admin/editRunType.html?id=buildType:SciQLop_Build&runnerId=RUNNER_22&cameFromUrl=%2Fteamcity%2Fadmin%2FeditBuildRunners.html%3Fid%3DbuildType%253ASciQLop_Build%26init%3D1&cameFromTitle=))\n",
356 "* Slack ([example](https://sciqlop.slack.com/messages/C57HU1KBJ/), [config](https://hephaistos.lpp.polytechnique.fr/teamcity/slacknotifications/index.html?projectId=SciQLop))\n",
357 "* Github, Bitbucket, VS Team Services...\n",
358 "* Rhodecode ([Miniphare PR](https://hephaistos.lpp.polytechnique.fr/rhodecode/GIT_REPOSITORIES/LPP/phare/miniphare/miniphare/pull-request/410), [config](https://hephaistos.lpp.polytechnique.fr/teamcity/admin/editRunType.html?id=buildType:Miniphare_Build&runnerId=RUNNER_82&cameFromUrl=%2Fteamcity%2Fadmin%2FeditBuildRunners.html%3Fid%3DbuildType%253AMiniphare_Build%26init%3D1&cameFromTitle=))\n",
359 "* [VS IDE plugin](https://confluence.jetbrains.com/display/TCD10/Visual+Studio+Addin), [Eclipse plugin](https://confluence.jetbrains.com/display/TCD10/Eclipse+Plugin), [IntelliJ-based IDEs](https://blog.jetbrains.com/teamcity/2017/10/teamcity-integration-with-intellij-based-ides/)"
282 ]
360 ]
283 },
361 },
284 {
362 {
@@ -289,8 +367,62
289 }
367 }
290 },
368 },
291 "source": [
369 "source": [
292 "# Time to play!"
370 "# API?\n",
371 "\n",
372 "* Quite easy to [understand](https://confluence.jetbrains.com/display/TCD10/REST+API) ( [buildTypes](https://hephaistos.lpp.polytechnique.fr/teamcity/app/rest/buildTypes/), [projects](https://hephaistos.lpp.polytechnique.fr/teamcity/app/rest/projects/) )\n",
373 "* Almost everything can be done through API"
293 ]
374 ]
375 },
376 {
377 "cell_type": "code",
378 "execution_count": 31,
379 "metadata": {
380 "ExecuteTime": {
381 "end_time": "2018-01-09T08:37:54.802150Z",
382 "start_time": "2018-01-09T08:37:54.793474Z"
383 },
384 "slideshow": {
385 "slide_type": "slide"
386 }
387 },
388 "outputs": [],
389 "source": [
390 "import teamcity\n"
391 ]
392 },
393 {
394 "cell_type": "markdown",
395 "metadata": {
396 "slideshow": {
397 "slide_type": "slide"
398 }
399 },
400 "source": [
401 "# What Next?\n",
402 "\n",
403 "* Improve Rhodecode integration\n",
404 "* Boost agents startup time\n",
405 "* Switch to Docker swarm\n",
406 "* More Meta-Runners"
407 ]
408 },
409 {
410 "cell_type": "markdown",
411 "metadata": {
412 "slideshow": {
413 "slide_type": "slide"
414 }
415 },
416 "source": [
417 "# Questions?\n"
418 ]
419 },
420 {
421 "cell_type": "code",
422 "execution_count": null,
423 "metadata": {},
424 "outputs": [],
425 "source": []
294 }
426 }
295 ],
427 ],
296 "metadata": {
428 "metadata": {
General Comments 0
You need to be logged in to leave comments. Login now