这看起来似乎很简单。但我可以告诉你,我已经绞尽脑汁待了几天。我已经阅读了很多文档,与人们一起坐在IRC上,并与同事交谈,此时我还没有得到我真正想到的答案。
我已经研究了几种可能的方法
我不喜欢这两个因为自上而下执行的必要性......它们似乎适合于编排多个节点状态,而不是单个节点中的工作流。
这是我真正想避免的,因为这是一个重复的工作流程,我不想像这样构建自定义。如果我和队友一起沿着这条路走下去,那就太可容易了。
这些没有重复应用状态或逻辑顺序/工作流程的概念(我知道)。
还有一些我不会提及的。
没有进一步的讨论,这就是我的困境。
目标:
Jenkins部署非常简单。我们放入包裹和配置中,然后设置好。
单元测试更难。作为一个例子,我有这个状态文件。
动作/ version.sls:
# Hit's the jenkins CLI interface to check for version info
# This can be used to verify that jenkins is active and the version we want
# Import some info
{%- from 'jenkins/init.sls' import jenkins_home with context %}
# Install plugins in jenkins_plugins list
jenkins_version:
cmd.run:
- name: java -jar jenkins-cli.jar -s "http://127.0.0.1:8080" version
- cwd: /var/lib/tomcat/webapps/ROOT/WEB-INF/
- user: jenkins
actions.version基本上验证了jenkins是否正在运行且可查询。我们希望在几个点的构建过程中确保这一点。
示例... tomcat需要时间才能启动。我们不得不为重启操作添加延迟。如果您查看下面的start.sls,您可以看到该操作正在发生。请注意在init_delay上打开的错误:。
动作/ start.sls:
# Starts the tomcat service
tomcat_start:
service.running:
- name: tomcat
- enable: True
- full_restart: True
# Not functional atm see --> https://github.com/saltstack/salt/issues/20631
# - init_delay: 120
# initiate a 120 second delay after any service start to let tomcat come up.
tomcat_wait:
module.run:
- name: test.sleep
- length: 60
include:
- jenkins.actions.version
现在我们通过执行actions.stop和actions.start来实现此重启功能。我们有这个actions.version状态,我们可以用它来验证系统是否已准备好继续使用jenkins特定的状态工作流。
我想做一些像这样的事情......
Install Jenkins --> Grab yaml of plugins --> install plugins that need it
非常直接。
除了循环使用插件的yaml我使用的是Jinja 现在我无法调用并确保可以重复应用start.sls和version.sls状态。
我正在寻找,这是一个很好的方法。
这类似于jenkins.sls
{% set repo_username = "foo" -%}
{% set repo_password = "bar" -%}
include:
- jenkins.actions.version
- jenkins.actions.stop
- jenkins.actions.start
# Install Jenkins
jenkins:
pkg:
- installed
# Import Jenkins Plugins as List, and Working Path
{%- from 'jenkins/init.sls' import jenkins_home with context %}
{%- import_yaml "jenkins/plugins.sls" as jenkins_plugins %}
{%- import_yaml "jenkins/custom-plugins.sls" as custom_plugins %}
# Grab updated package list
jenkins-contact-update-server:
cmd.run:
- name: curl -L http://updates.jenkins-ci.org/update-center.json | sed '1d;$d' > {{ jenkins_home }}/updates/default.json
- unless: test -d {{ jenkins_home }}/updates/default.json
- require:
- pkg: jenkins
- service: tomcat
# Install plugins in jenkins_plugins list
{% for plugin in jenkins_plugins %}
jenkins-plugin-{{ plugin }}:
cmd.run:
- name: java -jar jenkins-cli.jar -s "http://127.0.0.1:8080" install-plugin "{{ plugin }}"
- unless: java -jar jenkins-cli.jar -s "http://127.0.0.1:8080" list-plugins | grep "{{ plugin }}"
- cwd: /var/lib/tomcat/webapps/ROOT/WEB-INF/
- user: jenkins
- require:
- pkg: jenkins
- service: tomcat
这是我被困的地方。要求不会这样做。和列表 行动似乎没有在盐中线性安排。我需要 能够只是验证jenkins已经准备好了。我需要 能够在单个插件之后重启tomcat 迭代被添加。我需要能够做到这一点来满足 插件顺序中的依赖项。
- sls: jenkins.actions.version
- sls: jenkins.actions.stop
- sls: jenkins.actions.start
# This can't work for several reasons
# - watch_in:
# - sls: jenkins-safe-restart
{% endfor %}
# Install custom plugins in the custom_plugins list
{% for cust_plugin,cust_plugin_url in custom_plugins.iteritems() %}
# manually downloading the plugin, because jenkins-cli.jar doesn't seem to work direct to artifactory URLs.
download-plugin-{{ cust_plugin }}:
cmd.run:
- name: curl -o {{ cust_plugin }}.jpi -O "https://{{ repo_username }}:{{ repo_password }}@{{ cust_plugin_url }}"
- unless: java -jar jenkins-cli.jar -s "http://127.0.0.1:8080" list-plugins | grep "{{ cust_plugin }}"
- cwd: /tmp
- user: jenkins
- require:
- pkg: jenkins
- service: tomcat
# installing the plugin ( REQUIRES TOMCAT RESTART AFTER )
custom-plugin-{{ cust_plugin }}:
cmd.run:
- name: java -jar jenkins-cli.jar -s "http://127.0.0.1:8080" install-plugin /tmp/{{ cust_plugin }}.jpi
- unless: java -jar jenkins-cli.jar -s "http://127.0.0.1:8080" list-plugins | grep "{{ cust_plugin }}"
- cwd: /var/lib/tomcat/webapps/ROOT/WEB-INF/
- user: jenkins
- require:
- pkg: jenkins
- service: tomcat
{% endfor %}
答案 0 :(得分:3)
如果不使用反应器,信标,尤其是在没有编写自己的python执行模块的情况下,你将无法实现这一目标。
Jenkins Master获得部署
使用函数install(...):
在python中编写jenkins执行模块。在该函数中,您可以通过调用现有的执行模块或自己编写来管理任何依赖项。
我们可以在部署过程中对其进行单元测试
在jenkins模块的安装功能中,您将根据安装结果触发特定events。
if not _run_deployment_phase(...):
__salt__['event.send']('jenkins/install/error', {
'finished': False,
'message': "Something failed during the deployment!",
})
你会map that event to reactor sls files并处理它。
我们只在必要时重启tomcat
编写一个tomcat模块。添加_is_up(...)
函数,通过解析结果的tomcat日志来检查tomcat是否已启动。在状态模块中调用函数并添加mod_watch函数。
def mod_watch():
# required dict to return
return_dict = {
"name": "Tomcat install",
"changes": {},
"result": False,
"comment": "",
}
if __salt__["tomcat._is_up"]():
return_dict["result"] = True
return_dict["comment"] = "Tomcat is up."
if __opts__["test"]:
return_dict["result"] = None
return_dict["comment"] = "comment here about what will change"
return return_dict
# execute changes now
return return_dict
在状态文件中使用状态模块。
install tomcat:
tomcat.install:
- name: ...
- user: ...
...
wait until tomcat is up:
cmd.run:
- name: ...
- watch:
- tomcat: install tomcat
我们可以基于每个包更新插件
向名为install_plugin的jenkins执行模块添加一个函数。查看pkg.install代码以复制接口。
非常强调良好的清洁直观清晰的盐配置
编写python执行模块,以实现简单且可维护的配置逻辑。在您自己的状态模块中使用该执行模块。内部状态文件调用您自己的状态模块,并为您喜欢的任何状态渲染器提供单独的配置。
答案 1 :(得分:0)
状态只按设计执行一次。如果需要多次执行相同的操作,则需要多个状态。此外,包含仅包含一次。
您应该将所有代码放入单个sls文件中,并通过jinja迭代生成状态,而不是所有这些包含/需要您正在做的事情。
如果您要做的是添加一堆插件,添加配置文件,然后最后重新启动,那么您应该按顺序执行所有操作,不要使用require,并使用listen或listen_in而不是看或看_in。
listen / listen_in导致在状态运行结束时触发的操作发生。它们与Ansible中的处理程序概念类似。
答案 2 :(得分:0)
这是一个很老的问题,但是如果您将Jenkins / tomcat的启动/停止过程更改为标准的init / systemd / windows服务(所有行为良好的服务都应如此),则可以使用service.running Jenkins服务,并将其添加到每个custom-plugin-{{cust_plugin}}状态。
require_in:
- svc: jenkins
watch_in:
- svc: jenkins
您可以继续将cmd.run模块与onchanges一起使用。您必须在每个custom-plugin-{{cust_plugin}}状态中添加onchanges_in :,但是您需要在on changes列表中至少包含一项,否则该命令将在每次状态运行时触发。>
答案 3 :(得分:-1)
如果您使用require,则会导致盐重新排序您的状态。如果您希望状态按顺序运行,只需按照您希望它们运行的顺序编写它们。
Watch / watch_in也将重新订购您的州。如果您使用listen / listen_in,它会将触发的操作排队,以按状态运行结束时触发的顺序运行。
请参阅:
http://ryandlane.com/blog/2014/07/14/truly-ordered-execution-using-saltstack/ http://ryandlane.com/blog/2015/01/06/truly-ordered-execution-using-saltstack-part-2/