salt-stack - 在 saltstack 中,我如何有条件地、迭代地( jinja )应用包含的状态

标签 salt-stack jinja2

乍一看这似乎非常简单。但我可以告诉你,我已经为此绞尽脑汁好几天了。我读过很多文档,与人们一起坐在 IRC 上,并与同事交谈过,但目前我还没有一个我认为真正站得住脚的答案。

我研究了几种可能的方法

  • react 堆
  • 编排运行者

我不喜欢这两个,因为自上而下的执行必要性......它们似乎是为编排多个节点状态而定制的,而不是单个节点中的工作流程。

  • 自定义状态

这是我非常想避免的事情,因为这是一个重复的工作流程,而且我不想构建这样的自定义。如果我和我的队友一起走这条路,就会有太多的难以辨认的空间。

  • 需要/观看

这些没有重复应用状态的概念(据我所知),或者按照逻辑顺序/工作流程。

还有一些我不会提及的。

无需进一步讨论,这就是我的困境。

目标:

  • Jenkins Master 已部署
  • 我们可以在部署进行时对其进行单元测试
  • 我们仅在必要时重新启动 tomcat
  • 我们可以按包更新插件
  • 非常强调良好、干净、直观、清晰的 salt 配置

Jenkins 部署非常简单。我们放入包和配置,然后就设置好了。

单元测试更加困难。作为一个例子,我有这个状态文件。

actions/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 上出现的错误: 。

Action /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

非常简单。

除了,要循环遍历我正在使用 Jinja 的插件的 yaml。
现在我没有办法调用并确保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

这就是我被困住的地方。 require 不会这样做。并列出 在 salt 中, Action 似乎不是线性安排的。我需要 能够验证 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 %}

最佳答案

如果不使用 react 器、信标,尤其是不编写自己的 python 执行模块,您将无法实现这一目标。

Jenkins Master gets Deployed

使用Python函数install(...):编写一个jenkins执行模块。在该函数中,您可以通过调用现有执行模块或自己编写它们来管理任何依赖项。

We can unit.test the deployment as it proceeds

在 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并处理它。

We only restart tomcat when necessary

编写一个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

We can update plugins on a per package basis

向您的 jenkins 执行模块添加一个名为 install_plugin 的函数。查看pkg.install代码来复制界面。

A big emphasis on good clean intuitively clear salt configs

编写Python执行模块以实现简单且可维护的配置逻辑。在您自己的状态模块中使用该执行模块。内部状态文件调用您自己的状态模块,并为您喜欢的任何状态渲染器提供单独的配置。

关于salt-stack - 在 saltstack 中,我如何有条件地、迭代地( jinja )应用包含的状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32656152/

相关文章:

mysql - 使用SaltStack创建Mysql数据库

ubuntu - 如何让 schedule.present 在 saltstack 中工作?

python - 比较 jinja2 模板中的两个变量

flask - 在 flask 中传递模板中的作业列表

azure - 远程执行平台

salt-stack - 如何在 salt-api 中使用 cmd.run

python - jinja + form + unicode 控制字符 + xml/docx 集成

javascript - Jinja2:如何创建多维 javascript 数组?

python - 如何为我的博客中的帖子实现 'Vote up' 系统?

centos - 我如何让 Salt Master 应用基本的 SLS 文件来对抗 Salt Minion?