Contents

CMIP6数据发布步骤总结

1. 在control machine上安装ansible

2. 在manage machine克隆esgf-ansible的目录

3. 两个配置文件

sample.hosts是描述远程机器的模板,作为数据节点都配置为data only

  • 需要有一个domain name (fully qulified domain name)
    • 在清华经过国际处和网络中心的诸多手续才能申请,而且他们得先看到网站本体才能给你通过。
    • 没有domain name时可以指定ip和端口号临时替代
    • 由于校内没法解析,所以还是

host_vars/myhost.my.org.yml是安装配置,文件名要和hosts里的名称一致

  • github里有配置为data node的示例
    • 关于https证书部分
      • 清华是自动在校园网的出口配置https,所以设置generate_httpd:true来生成个假的就行,别人访问就是https
      • 如果不像清华这种自动配置的,就按照自己的域名用LetsEncrypt设置
    • 有关Globus和Myproxy的证书
      • 注意,清华节点开放端口申请复杂,所以其实没有安装GridFTP,而data node不需要MyProxy服务(用于给用户认证,待明确)。因此设置generate_myproxy和设置globus只是为了防止在esg-publish和unpublish的时候弹出认证。
      • 文件中要求的cert称为Globus services Certificate,服务器用它向Globus注册自己的GridFTP/Myproxy服务。首先在Ansible安装时配置generate_globus为true,以在root用户目录下产生私钥globushostkey.pem和签名请求globushostcsr.csr,随后将CSR邮件给ESGF相应管理员获得ESGF签名的证书globushostcert.pem。可以用ansible的local_certs.yml安装证书,或重新安装时关闭generate_globus选项,在yml相应位置配置此证书的路径。
    • Globus 用户名密码部分
      • 如果出Bug提示没有Globus用户名密码不给通过安装,就需要申请一个globus号,填进去

4. 在target machine上面使用Playbook部署

命令

  • 用户有root权限ansible-playbook -v -i hosts.test --ask-pass -u hxm_stu --ask-become-pass --tags data --limit sample.host install.yml
  • root用户ansible-playbook -v -i hosts.test --ask-pass -u root --tags data --limit sample.host install.yml

曾遇到的问题

  • 在wsl里会说权限是777的话config就忽略了,改下文件夹的权限
  • selinux 会说没有安装libpython-selinux但是已经安了?关闭目标机上的selinux
  • 安装中failed to open file 等问题?先把playbook上的步骤看懂然后在目标机器上手动运行,再重试
  • 下载migation script失败?经常出现下载github repo资源时超时的情况,只能重试
  • 出现 Import Web CA Into Trust Store这一步找不到文件?但是文件都在?
    • 手动在certs.yml里定义executable的位置
  • java 的openjdk 装完之后在/etc/profile里定义,但是安装里还是非要说我没装,只好把java的role改了
  • yum 使用清华源
  • /etc/globus-connect-server-esgf.conf hostcert.pem hostkey.pem不存在 需要看playbook脚本内容,手动自己装上。(但因为清华没用GridFTP其实不影响,可以注掉)
  • 测试安装
    • ansible-playbook -v -i hosts.test --ask-pass -u root --tags data --limit sample.host start.yml status.yml

    • Unable to start service httpd: Job for httpd.service failed because the control process exited with error code. See “systemctl status httpd.service” and “journalctl -xe” for details

      在目标机上启动httpd失败,错误是Syntax error on line 24 of /etc/httpd/conf/httpd.ssl.conf: SSLCertificateChainFile: file ‘/etc/certs/cachain.pem’ does not exist or is empty. 但是清华是自动的https,已经不需要这个了,注释掉就可。

    • 服务器重启 注意默认的catalog需要apache 和 tomcat都起来

    • 由于安全问题,学校会要求升级apache版本。默认情况是ansible脚本中指定apache版本,通过yum安装。但很多情况下系统和第三方yum源不提供新版本(甚至大部分centos6的第三方yum源已经被隐藏了),需要自己编译安装。我的老版本是httpd2.2,编译了httpd2.4,因此2.2的配置文件和modules中的so文件都不能通用。esgf-ansible的github中可以找到2.2和2.4版本的httpd配置文件模板,配置中引入的模块也在编译时安装到modules目录下,这需要根据运行提示缺少哪些模块,参照./configure的help来开启。

5. 部署完成后首次配置发布数据

  • 官方提示:不要用root来发布,尽量建立一个新的账号和用户组

附加的功能

  • cdf2cim
    • CIM2 (Common Information Model 2), 希望直接从netcdf的global attributes中提取出来这一信息,作为json放在指定目录,之后上传到ES-DOC网站里面
    • esg-publisher里已经安装了这个模块,cmip6的话自动调用和扫描
    • 需要管理员在github群组里注册自己的id,然后下载access token
    • 失败了也不影响esg-publisher的其他步骤
  • Citation信息需要联系WIP,来首先注册机构和数据
  • ESGF-Dashboard
    • 概述和配置方法见PCMDI的网页。简单来说,esgf-dashboard-ip程序会把下载信息记录到esgf_dashboardschema下的esgf-dashboard-queue表(注意postgresql的schema不等于db),以及从这个表生成统计信息,最终由tomcat中的esgf-stats-api读取表发布出来网页,如https://cmip.bcc.cma.cn/esgf-stats-api/cmip6/stats-by-space/xml。另外有统计用的节点来harvest,如http://esgf-ui.cmcc.it/esgf-dashboard-ui/federated-view.html
    • 从学校服务器的access log看,所有的来源ip都被隐去了,只能看到校园网的166.111.7.7和166.111.7.8,所以原理上无法按照区域等统计,只能统计个下载量。
    • 清华的这个服务按照教程可以启动,但没有生成数据库表,且esgf-dashboard-ip可执行文件目录中出现了非常多segement fault导致的core.dump信息,怀疑是安装出错导致无法使用。\dn schema等等 set view之后发现全是esgf_dashboard 数据是有的
    • set search_path = esgf_dashboard;
    • 根据PCMDI的重启命令,结合源程序(网上搜到的zip解压看到 /usr/local/esgf-dashboard/src/c/esgf-dashboard-ip/src/dbAccess.c),以及出现执行sql命令出错,怀疑是esgcet没有权限,于是给esgcet加上所有权限 ALTER ROLE esgcet WITH SUPERUSER; /esg/config/esgf.properties里面的用户名设置上
    • 然而还是出错,形式是先报错sql执行不对,之后出现segment fault 然后有一个core dump。sql直接输进数据库,发现原因是缺了一些表,但我感觉这个不重要,因为缺的不是cmip6的表。
    • 用gdb调试,发现原因是读取一个shards.xml文件时xmlReadFile报错找不到文件。
  • Filebeat
    • 现状:2020年时,发现老的esgf-dashboard-ip已经从ansible中移除了,节点数据采集流程改为:先在apache中设置新增一个country_download.log,用filebeat处理后,上报给cmcc.it
    • 安装:全新安装时会自动把相关东西装上,在 https://acme-climate.atlassian.net/wiki/spaces/ESGF/pages/1054113816/Proposed+ESGF+Usage+of+Filebeat+and+Logstash 可以找到手动配置的方法。官方里给的filebeat.yml中- type: log前面少了两个空格,要不然filebeat服务启动会失败。
    • 显示:filebeat起来之后,可以在localhost:5601看到
  • 有关Thredds和root url网页
    • thredds里面有关标题、图片、联系方式、组织等信息在/esg/下面设置
    • 域名的根页面原来是空的,现在在/etc/httpd/htdocs下放了一个html作为首页。内容是如何撤回、更新、追加的信息。

准备,esgprep

  • 软件安装
    • 用到conda 比如在/usr/local/conda/bin ansible安装会给一个esg-pub环境,esgprep这些组件都已经有了
    • 需要hdf5 yum包名其实是hdf5-devel
    • python2.6安装语法不兼容,只能改系统默认python
  • 数据生产步骤 (github上也有)
    1. fetch esgf configuration ini files: esgfetchini
    2. fetch cmor tables: esgfetchtables,用来自动PrePARE
    • 如果文件不是cmor生成: 如果文件里没有cmorized,publish入库的一步会自动检查是否符合cmip6 cmor tables, 有三个配置选项在esg.ini定义https://esgf.github.io/esg-publisher/configuration.html。esgfetchtables的tables要对应文件里cmor版本,默认下载在usr/local。有时这个目录不能访问,而且按照cmor版本fetch branch也会报错,上述选项不太好使,就直接手动PrePARE了。esg.ini加上skip_validation=True(老版本安装的src/python/esgcet/esgcet/config/cmip6_handler.py没有这个选项,手动更新了一下文件)
    • 手动PrePARE: PrePARE -l ./PrePARE_log/ice --table-path ./cmip6-cmor-tables-6.7.31/Tables/ ../ice
    1. DRS (Data Reference Syntax)把结果文件按DRS的格式组织(变量路径中加入version等)可以管理数据版本,生成文件的时候会进行一些检查
      • 初次扫描 esgdrs list --project cmip6 /mypath/ciesm_data/copy3会把结果写进临时的文件
      • 可以预览drs tree 和构建目录结构的语句(todo和tree)。觉得可以了就esgdrs upgrade --project cmip6 /mypath/ciesm_data/copy1 --link 这里会默认在当前目录下创建DRS树,比如选择/esg/data注意默认是直接移动文件,文档里推荐使用–link但若不在同一个物理存储,所以只能用symlink,而symlink会出错。所以尽量同一个存储
    2. 在DRS基础上生成mapfile
      • 检查路径esgmapfile show --project cmip6 --directory /mypath/ciesm_data/ocn --outdir /mypath/ciesm_data/esg/mapfiles/ocn/

      • 生成esgmapfile make --project cmip6 /mypath/ciesm_data/ocn --outdir /mypath/ciesm_data/esg/mapfiles/ocn/

      • 例子

        1
        2
        3
        4
        
        (esgdrs list --project cmip6 /mypath/ciesm_data/ice | tee ../../DRS_log/ice-list.txt) &&
        (esgdrs tree --project cmip6 /mypath/ciesm_data/ice | tee ../../DRS_log/ice-tree.txt) &&
        (esgdrs upgrade --project cmip6 /mypath/ciesm_data/ice --link | tee ../../DRS_log/ice-upgrade.txt) &&
        (esgmapfile make --project cmip6 /mypath/ciesm_data/esg/DRS/ice --outdir /mypath/ciesm_data/esg/mapfiles/ice/)
        
      • esgdrs upgrade 是在执行命令的目录下面生成DRS文件目录结构

      • esgdrs的结果临时文件pkl file放在/tmp

      • esgdrs upgrade生成的新目录里version是扫描的日期,会去掉错误的文件,在这个基础上生成的mapfile的版本也是扫描的日期。

      • 不论是否事先esgdrs,esgmapfile若使用原本文件的目录,生成的mapfile的version日期是文件目录里version,且不会略过错误的文件。(比如ice数据部分prc_Amon_CIESM_ssp245_r1i1p1f1_grrABnJE22594.nc在mapfile里没有忽略,若publish到database在解析attributes里时index out of range)

发布 esgpublish,同样的conda环境 注意publish和unpublish,mapfile一定要保存好

  1. Generate certificate for publication with myproxy-logon 用的普通用户来发布 myproxy-logon -b -s esgf-node.llnl.gov -l username -p 7512 -t 72 -o $HOME/.globus/certificate-file 如果失败,需要ESGF管理员将你的用户名加入列表。

  2. publish

    三步: database, thredds server, index node

    1
    2
    3
    
    1. esgpublish --project cmip6 --map ./mapfiles [--set-replica]
    2. esgpublish --project cmip6 --map ./mapfiles --service fileservice --noscan --thredds [--set-replica]
    3. esgpublish --project cmip6 --map ./mapfiles --noscan --publish [--set-replica]
    

    或者esgpublish --project cmip6 --map ./mapfiles --service fileservice --noscan --thredds --publish (不推荐,容易出错)publish to postgres, Thredds and the Index in one step

  3. unpublish

    • 删除全部,网络原因API可能会失效,多来几遍才能全删esgunpublish --project cmip6 --map ./mapfiles --database-delete --delete
    • thredds在tomcat,重启tomcat后可以看到本地的都被删了
    • 若unpublish不能删除网站上的东西的话,可以直接使用unpublish api来删除
    1
    2
    3
    4
    5
    
    wget --no-check-certificate --ca-certificate $HOME/.globus/certificate-file
    --certificate $HOME/.globus/certificate-file
    --private-key $HOME/.globus/certificate-file --verbose -O response.xml
    --post-data="id=CMIP6.CMIP.THU.CIESM.historical.r1i1p1f1.Amon.clivi.gr.v20191202|cmip.dess.tsinghua.edu.cn"
    https://esgf-node.llnl.gov/esg-search/ws/delete
    

    注意,官方会提到有test publish的地址,但是实际邮件沟通是不能用的,耽误了很久。。。要发布的话应当直接发布

实践经验

  1. 有关两次检查
    手动运行PrePARE检查,然后DRS生成的时候也会检查。如果文件不是cmor生成,在publish时跳过自动的PrePARE。
  2. 有关数据目录
    由于提供给我模式结果是按atm/lnd/ocn这样分组的,我产生的DRS目录和mapfiles目录都是按/atm/lnd/ocn分别存放。这样发布和撤回时也是分开的,便于找错。
  3. 有关更新或者增加文件
    数据原始目录里复制替换nc文件,然后重新运行一遍DRS和mapfile,照常发布即可。
  4. 某次升级esgf软件之后发现部分文件下载需要用户认证
    查看tomcat log发现http下载某些文件时307重定向到restrictedAccess的地址,浏览器弹出的认证是让输入用户名和密码。查看其它机构的ESGF安装,都限制数据集为esgf-user访问(通过esg.ini设置,发布时生成的xml里面写入了这一项,xml也在/esg里面),于是在tomcat/webapps/thredds/WEB-INF/web.xml里面注掉了restricted access datasets相关的security-constraints部分,重启tomcat后就无跳转了。 参考Thredds的restrictedAccess设置方法

6.数据更新、追加、撤回

根据要求,每次更新或撤回错误数据都要先在ERRATA上说明原因,附上影响的文件列表,作为长期记录。

https://errata.es-doc.org/static/index.html

撤回

  • 使用unpublish的delete(不要用retract,否则再次向thredds server发布新版本数据出现operation not supported at this point),可以不删除本地数据库。

    esgunpublish --project cmip6 --map ./mapfiles --delete

  • 将撤回的部分专门放在mapfiles的子目录中保留一段时间,以便检查和重新发布等

更新或追加

  • 首先撤回错误的
  • 对需追加的新文件PrePARE查错, esgdrs list tree upgrade,在drs目录里生成新版本的文件。同时,log保存在DRS_log
  • espmapfile来生成新版本的mapfile
  • 对新的mapfile来esgpublish

作为警醒的一个事件:曾经删除了/etc下所有文件

背景

  • 周二下午-晚上 一直运行esgtest_publish测试发布,出现失败。找到https://github.com/ESGF/esg-publisher/blob/master/src/python/esgcet/esgcet/publish/thredds.py发现是因为访问reiniturl(https://localhost/thredds/admin/debug?Catalogs/recheck)失败,(SSL: SSLV3_ALERT_HANDSHAKE_FAILURE)从而没有得到正确返回。

  • 周三早上 更改esg.ini中的此url设置为http,无效。想到可以直接更改验证条件,但查看thredds文档后认为tomcat服务器8443使用的self-signed web certificate是过去生成的,而服务器修改过fqdn,判断可能需要重新生成,而不是更改thredds.py的验证条件,以避免潜在 的更多问题。

  • 周三下午 删除tomcat设置路径中的cert,尝试使用esgf-ansible安装步骤来重新生成它们。遇到找不到证书而globus-connect-server程序初始化失败,导致安装失败的问题。直接在目标机运行globus-connect-server,同样找不到对应证书文件而失败。查看globus文档后,尝试根据升级指导删除旧的配置文件(由esgf-ansible生成),再重新由esgf-ansible安装和进行globus-connect-server初始化配置。需要删除:

    1
    2
    3
    4
    
    sudo rm /etc/globus-connect-server.conf
    sudo rm -r /etc/grid-security
    sudo rm -r /var/lib/globus-connect-server
    sudo rm /etc/gridftp.conf
    

    删除时使用root,第一次打字错误,因此第二次自动补全,其后输入空格直接执行类似rm /etc/grid * -rf。约5秒后尝试删除globus-connect-server.conf时发现未找到文件,意识到/etc已经全部被删除。考虑到若没有unmount所在硬盘,执行恢复操作也会造成写入,因此未进行任何操作,联系管理员。

五个why

  • 问题:/etc被删除,236集群设置损坏,无法登录和使用
  1. 为什么/etc被删除? -因为使用root执行rm /etc/grid * -rf,意外删除整个目录。
  2. 为什么要删除/etc下的内容? -为了解决esgtest_publish的访问证书出错问题,决定重新配置globus,因此递归删除/etc/globus-connect-server.conf等目录和文件
  3. 为什么要使用root? -在paratera用户下曾经尝试使用esg-pub的环境进行数据发布各项准备,但是出现报错而root没有,尝试解决此问题一段时间无果,就直接使用了root。同时esgf-ansible创建的各目录和配置是root,出于经常配置的惰性也直接使用了root。
  4. 为什么执行-rf没有检查?或采取更安全的方法? -因为急于解决esgtest_publish问题,经过连续的调试后产生了投机的心理,注意力下降,忽视了基本安全操作。
  5. 为什么要手动操作解决重新安装问题,而不是使用脚本? - 本来使用ansible定义脚本来操作可以避免问题,但安装使用过程中经常出现失败,需要调整236服务器的依赖等,最终感到脚本更适合全新服务器安装,不愿再花时间使用脚本

改进

  1. 改变操作时的习惯,检查或是不使用危险的命令,尤其在不同压力或是状态时能够牢记这些
  2. 不把希望寄托在人不犯错上,如尽量使用脚本,以及在本机器esgf部署这种复杂的情况里,花时间整理修改权限等问题,尽量使得运行调试权限不和其他各种文件产生干扰