当前位置 博文首页 > 赵英超的博客:大数据管理神器:Ambari自定义stack和服务二次开
Ambari 是 Apache Software Foundation 的一个顶级开源项目,是一个集中部署、管理、监控 Hadoop 分布式集群的工具。
CDH收购HDP后,HDP逐渐闭源,导致开源社区大数据运维越来越需要一款比较优秀平台支撑,首推ambari。但是很多刚接触,难免很难快速入手,因此结合自己多年经验及社区资料,整理如下供大家参考参考,有问题欢迎大家共同探讨。
个人建议开发方向:
1、参照HDP,基于Apache项目做二次开发。
2、支持自定义ambari stack,以便于支撑多种组件包安装(比如:大数据、算法、K8S等等)。
3、移除rpm/deb package安装,建议tar包安装,以便于快速支撑多平台。
4、组件支持mpack模式安装、卸载、更新。
5、增强监控模块。
6、汉化。
7、组建设区统一力量共同参与开发。
https://ambari.apache.org/
https://github.com/apache/ambari
Ambari是Hortonworks贡献给社区的、完全开源的、Hadoop生态的集群管理、监控、部署的工具;
Ambari Web通过调用Ambari REST API实现对Hadoop生态系统各个组件的操作,同时Ambari REST API也支持与现有的其它外部工具集成,已扩展服务的应用面。可以说,Ambari REST API是唯一暴露给“外部”系统(这里可以指代Ambari Web、Ambari Shell等内部系统和其它外部系统)的操作Ambari的方式。?
?
说起?Ambari?,不得不提下?Hortonworks和它的竞争对手们?。
因为Apache社区版的Hadoop在面对企业级的应用时存在稳定性、可靠性、性能、易用性等方面的限制,许多公司都对其进行了“二次包装”,这些公司被称为Hadoop商业发行版提供商。
大浪淘沙,自从10年前(2006年)Hadoop诞生到今天(2016年)为止,这一市场已被几大公司瓜分,国外比较著名的提供商有Cloudera、MapR、Hortonworks、IBM、Amazon等,国内比较著名的提供商有华为、星环科技等。这里面,目前只有Cloudera和Hortonworks两家国外公司有提供不收费的Hadoop商业发行版,分别叫作Cloudera’s Distribution Including Apache Hadoop(简称“CDH”)和Hortonworks Data Platform(简称“HDP”)。这两家公司也都提供了相应的集群管理、部署、监控的工具,分别是Cloudera Manager和Ambari。apache
值得注意的是,Cloudera Manager要比Ambari在年纪上大三岁,但这并不妨碍Ambari的快速成长,目前来看,Ambari与Cloudera Manager的功能差距正在迅速缩小,且因为Ambari是彻底开源的,社区很是活跃,增长了愈来愈多的企业级的新特性,使得Ambari自己变的愈来愈强大。同时,很多公司也对Apache Ambari进行了“二次包装”,将Ambari从面向运维转变成了面向数据服务,将来说不定还会产生“Ambari商业发行版提供商”这样的称呼。
?
参考:https://blog.csdn.net/tianbaochao/article/details/72156247
Ambari是一个强大的大数据集群管理平台。在实际使用中,我们使用的大数据组件不会局限于官网提供的那些。如何在Ambari中集成进去其他组件呢?
Ambari充分利用了一些已有的优秀开源软件,巧妙地把它们结合起来,使其在分布式环境中做到了集群式服务管理能力、监控能力、展示能力,这些优秀的开源软件有:
(1)、agent端,采用了puppet管理节点。
(2)、在web端,采用ember.js作为前端MVC框架和NodeJS相关工具,用handlebars.js作为页面渲染引擎,在CSS/HTML方面还用了Bootstrap框架。
(3)、在Server端,采用了Jetty、Spring、JAX-RS等。
(4)、同时利用了Ganglia、Nagios的分布式监控能力。
Ambari框架采用的是Server/Client的模式,主要由两部分组成:ambari-agent和ambari-server。ambari依赖其它已经成熟的工具,例如:其ambari-server就依赖python,而ambari-agent还同时依赖ruby,puppet,fecter等工具,还有它也依赖一些监控工具nagios和ganglia用于监控集群状况。其中:
puppet是分布式集群配置管理工具,也是典型的Server/Client模式,能够集中式管理分布式集群的安装配置部署,主要语言是ruby。
facter是用Python写的一个节点资源采集库,用于采集节点的系统信息,例如OS信息,由于ambari-agent 主要是用Python写的,因此用facter可以很好的采集到节点信息。
?
目录 | 描述 |
ambari-server | Ambari的Server程序,主要管理部署在每个节点上的管理监控程序 |
Ambari-agent | 部署在监控节点上运行的管理监控程序 |
Contrib | 自定义第三方库 |
ambari-web | Ambari页面UI的代码,作为用户与Ambari server交互的。 |
ambari-views | 用于扩展Ambari Web UI中的框架 |
Docs | 文档 |
ambari-common | Ambari-server 和Ambari-agent 共用的代码 |
?
在ambari-server开放的Rest API中分为主要的两大类 API,其中一类为ambari-web提供监控管理服务,另一类用于与ambari-agent交互,接受ambari-agent向ambari-server发送心跳请求。Master模块接受API和Agent Interface的请求,完成ambari-server的集中式管理监控逻辑,而每个agent节点只负责所在节点的状态采集及维护工作。
由图中可以看出,主要有4部分:
两条业务线:
?
?
由图中可以看出,主要有4部分:
Resource Service:资源服务,用来接收前端的 Rest 请求。关于 Resource 的几个基本概念:
HeartBeatHandler:处理 Agent 的 Heartbeat 请求。
ActionQueue:每个 Host 都有一个 ActionQueue 记录着需要这台 Host 执行的命令。
FSM:维护组件状态的有限状态机。
简述一下 Ambari Server 的工作流程:
前端请求处理流程:前端提交一个 Rest 请求,相应 Resource 的 Service 处理请求,根据 ResourceType 找到对应的 ResourceProvider 执行具体的操作;如果存在需要 Agent 执行的操作,则把操作存储到相应 Host 的 ActionQueue 中;如果需要改变组件的状态,则需要操作 FSM。
Agent 请求处理流程:Agent Heartbeat 每10秒执行一次,Heartbeat Request 会携带命令的执行情况、组件状态以及 Host 状态等信息,HeartBeatHandler 会根据汇报上来的命令执行情况,去操作 FSM 来维护组件的状态;HeartBeatHandler 会从 ActionQueue 中取出需要 Host 执行的命令、修改的配置、Alert 定义等信息,通过 HeartBeat Response 返回给 Agent 执行。
总体来说由于 Ambari Server 和 Ambari Agent 之间是通过短连接进行通信,所以 Server 无法把需要执行的命令,直接推送给相应的 Agent,所以需要 ActionQueue 来存储命令,然后通过 Heartbeat 把命令下发给 Agent 执行。
?
由图中看,主要有3部分:
4个数据容器:
简一下 Ambari Agent 的工作流程:
Ambari-agent是一个无状态的,其功能分两部分:
采集所在节点的信息并且汇总发送心跳发送汇报给ambari-server。
处理ambari-server的执行请求。
因此它有两种队列:
(1)、消息队列Message Queue,或称为ResultQueue。包括节点状态信息(包括注册信息)和执行结果信息,并且汇总后通过心跳发送给ambari-server。
(2)、操作队列ActionQueue。用于接收ambari-server发送过来的状态操作,然后交给执行器调用puppet或Python脚本等模块执行任务。
???Live Cluster State:集群现有状态,各个节点汇报上来的状态信息会更改该状态;
???Desired State:用户希望该节点所处状态,是用户在页面进行了一系列的操作,需要更改某些服务的状态,这些状态还没有在节点上产生作用;
???Action State:操作状态,是状态改变时的请求状态,也可以看作是一种中间状态,这种状态可以辅助LiveCluster State向Desired State状态转变。
?
Ambari-server的Heartbeat Handler模块用于接收各个agent的心跳请求(心跳请求里面主要包含两类信息:节点状态信息和返回的操作结果),把节点状态信息传递给FSM状态机去维护着该节点的状态,并且把返回的操作结果信息返回给Action Manager去做进一步的处理。
Coordinator模块又可以称为API handler,主要在接收WEB端操作请求后,会检查它是否符合要求,stageplanner分解成一组操作,最后提供给ActionManager去完成执行操作。
因此,从上图就可以看出,Ambari-Server的所有状态信息的维护和变更都会记录在数据库中,用户做一些更改服务的操作都会在数据库上做一些相应的记录,同时,agent通过心跳来获得数据库的变更历史。
Ambari-web使用了一个流行的前端Embar.js MVC框架实现,Embar.js是一个TodoMVC框架,它涵盖了现今典型的单页面应用(single page application)几乎所有的行为。
使用了nodejs
使用brunch 作为项目的构建管理工具
Brunch ,是一个超快的HTML5构建工具。它有如下功能:
(1)、编译你的脚本、模板、样式、链接它们。
(2)、将脚本和模板封装进common.js/AMD模块里,链接脚本和样式。
(3)、为链接文件生成源地图,复制资源和静态文件。
(4)、通过缩减代码和优化图片来收缩输出,看管你的文件更改。
(5)、并通过控制台和系统提示通知你错误。
Nodejs 是一个基于Chrome JavaScript运行时建立的一个平台,用来方便的搭建快速的易于扩展的网络应用,NodeJS借助事件驱动,非阻塞I/O模型变得轻量和高效,非常适合运行在分布式设备的数据密集型的实时应用。
目录或文件 | 描述 |
app/ | 主要应用程序代码。包括Ember中的view、templates、controllers、models、routes |
config.coffee | Brunch应用程序生成器的配置文件 |
package.json | Npm包管理配置文件 |
test/ | 测试文件 |
vendor/ | Javascript库和样式表适用第三方库。 |
Ambari-web/app/
目录或文件 | 描述 |
assets/ | 静态文件 |
controllers/ | 控制器 |
data/ | 数据 |
mappers/ | JSON数据到Client的Ember实体的映射 |
models | MVC中的Model |
routes/ | 路由器 |
styles | 样式文件 |
views | 试图文件 |
templates/ | 页面模板 |
app.js | Ember主程序文件 |
config.js | 配置文件 |
Ambari-server使用的jetty作为Servlet容器作为内嵌的java服务器,其中相关的代码在server/controller 下的AmbariServer.java中。 其中Session的管理似乎AmbariSessionManager 重写了SessionManager类
(1)、jetty 是一个开源的Servlet容器,它为基于java的web容器,它的API以一组JAR包的形式发布。开发人员可以将Jetty容器实例化成一个对象,可以迅速为一些独立运行的Java应用提供网络和web连接。
(2)、Google Guice 一个google的IOC容器
(3)、Spring
(4)、JAX-RS
?
Ambari-server依赖于 Ambari-Views 项目
包名 | 描述 |
org.apache.ambari.server.api.services | 对web接口的入口方法,处理/api/v1/* 的请求 |
org.apache.ambari.server.controller | 对Ambari中cluster的管理处理,如新增host,更新service、删除component等 |
org.apache.ambari.service.orm.* | 对数据库的操作 |
org.apache.ambari.server.agent.rest | 处理与Agent的接口 |
org.apache.ambari.security | 是使用Spring Security来做权限管理 |
Ambari Server 会读取 Stack 和 Service 的配置文件。当用 Ambari 创建服务的时候,Ambari Server 传送 Stack 和 Service 的配置文件以及 Service 生命周期的控制脚本到 Ambari Agent。Agent 拿到配置文件后,会下载安装公共源里软件包(Redhat,就是使用 yum 服务)。安装完成后,Ambari Server 会通知 Agent 去启动 Service。之后 Ambari Server 会定期发送命令到 Agent 检查 Service 的状态,Agent 上报给 Server,并呈现在 Ambari 的 GUI 上。
每次的REST API的请求都会经过server的请求分发器(Request Dispatcher)分发。若是是操做agent,会经过任务编排器(Orchestrator)生成Stage DAG,依次按顺序下发相应的Stage;若是是对监控、告警的操做,能够经过统一的SPI(Service Provider Interferce)调用完成;
Ambari将集群的配置、各个服务的配置等信息持久化在server端的DB中;
server与agent的惟一的交流方式是经过RPC,即agent向server报告心跳,server将command经过response发回给agent,agent本地执行命令,好比:agent端执行相应的服务组件启停的操做。
第一层抽象:资源
在类Unix系统中,咱们确定据说过这样一句话“一切皆是文件”,即普通的文件、目录、块设备、套接字都是以文件被对待,提供统一的操做模型。在Ambari的世界里,“一切皆是资源”。
例子:
Hadoop生态圈的组件被抽象成一个个服务,Ambari Stack能够当作一系列服务的集合,每个Ambari Stack下面对应了适配不一样系统的Ambari Service,好比HDFS、HBase等等;每个Ambari Service一般由不一样的组件构成,好比HDFS包含有不一样的组件Datanode、NameNode;每个组件可能分布在不一样的机器上,好比HDFS的一个DataNode在HostA上,另外一个DataNode在HostB上。Ambari对这些不一样层次的对象作了一层抽象,把它们都看成“资源”来看待:
一个Service由多个ServiceComponent构成,一个ServiceComponent又由多个ServiceComponentHost构成,好比:
Service: HDFS, YARN, HBase, etc
ServiceComponent: HDFS.NameNode, YARN.ResourceManager, HBase.RegionServer, etc
ServiceComponentHost: HDFS.NameNode.HostA, YARN.ResourceManager.HostB, etc
上面的Service、ServiceComponent、ServiceComponentHost都是资源的一种类型,在Ambari中,有多达74种类型(Ambari2.0.0版本)的不一样资源(Resource),每一种类型都有相应的XXXResourceProvider提供相应的操做接口,好比ClusterResourceProvider,又经过XXXService来暴露相应资源的REST API,好比ClusterService。这样一看,对“资源”的增删改查就比较容易理解了。
?
第二层抽象:操做
对应上面的三种资源,有三种操做的抽象:
Operation: Service层面的操做(Install/Start/Stop/Config),一个Operation能够做用于一个或多个Service;
Stage: ServicesComponent层面的操做,根据不一样ServicesComponent操做间的依赖关系,一个Operation的全部Task可能被划分红多个Stage,一个Stage内的多个Task相互没有依赖,能够并行执行;
Task: ServiceComponentHost层面的操做,为了完成一个Operation,须要为不一样的机器分配一系列的Task去执行;
?
须要特别说明的是操做的执行顺序,能够将Ambari的Stage DAG类比成Spark计算模型中的RDD DAG:
不一样的Stage只能顺序执行。后面的Stage只有在前面Stage执行成功后才会下发给Agent。若是前面Stage失败,后面的Stage将取消;
同一个Stage内的多个Task能够并行执行,能够同时下发给Agent,若是某个Task失败,其余的已下发且正执行的Task将被取消;
分配给同一个机器的不一样Task只会顺序执行;
下图描述了这三种资源与操做的对应关系:
?
上述的三个操做抽象是定义态的描述,它们分别对应一个执行态的抽象:
StagePlan: 执行态的Operation,是一个Stage DAG;
Action:执行态的Stage,由多个Command构成;
Command: 执行态的Task,下发给具体的机器执行。主要有如下几种:?
ExecuteCommand: 对服务组件执行INSTALL/START/STOP等操做;
StatusCommand: 对服务组件执行死活检查(由Server按期下发);
CancelCommand: 取消其余已经下发的Task(当Stage中的某个Task失败时);
RegistrationCommand: 要求Agent向Server从新注册(当发现Server维护的心跳序号与Agent上报的不一致时);
?
下图经过一个具体实例(启动HDFS和YARN服务),展现了其Stage DAG的构建逻辑:
Stage1所有执行完才能够进行Stage2的执行,Stage1里面的Task能够并行执行。
这样的设计模型使得Ambari能够支持几乎全部的组件,作到“包罗万物”。
解决Hadoop生态系统部署
配置管理
可以将默认配置写入stack中(stack后续介绍),在开启时ambari将stack中各个版本的config文件读入,在使用blueprint创建集群部署hadoop时,直接生成command-json文件。(blueprint后续介绍)
服务状态展示、监控、报警
?
资源
ambari将集群及集群中的服务、组件、机器都视为资源,资源的状态都会记录在db中
Hadoop生态
Stack
发行版本的含义,如HDP,可以有若干版本。
Service
服务,属于stack,一个stack下可以有多个service,service也可以分多个版本,版本间可以有继承关系。例如zookeeper就是一项服务。
Component
组件,属于service,一个service下可以有多个component组成。例如HDFS服务下的组件有datanode,namenode等。
角色
Component可以指定部署时的角色,如master、slave等,也可以指定每种角色需要的host个数。例如namenode为单一host组件,可以部署在master机器上,datanode可以部署在多台host上那么可以指定部署datanode的角色为slave
host
host为运行ambari-agent的一台机器,同时也是搭建集群内部的一台机器,可以为host设置对应的角色,例如master,slave等。
restAPI->ambari-server
单步创建
Blueprint?
调用一次restAPI即可进行集群创建、服务安装、组件部署、服务开始等集群操作,简化了单步创建的调用次数。
ambari-server->ambari-agent
Stack为一系列service的集合。可以在Ambari中定义多个不同版本的stacks。比如HDP3.1为一个stack,可以包含Hadoop, Spark等等多个特定版本的service。
HDP
2.0.6
metainfo.xml (stack的相关信息,包括继承关系等版本层的性质)
services (该路径下存储各个服务)
ZOOKEEPER
metainfo.xml (里面配置了组件名称,操作组件的脚本名称,脚本的语言种类等信息)
configuration
global.xml (服务配置,在blueprint创建集群时使用)
zookeeper-log4j.xml
package
scripts
zookeeper_server.py (组件的操作脚本 包括安装、查询状态、开启组件、关闭组件等操作)
zookeeper_cilent.py
...
templates (在部署时脚本里所用到的模板文件)
...
YARN
...
HDFS
...
...
hooks (在调用脚本前需要执行的脚本,例如为集群各个服务创建linux-user)
...
repos (yum安装所需要的repos配置信息)
...
?
当写创建好stack后,需要重启ambari-server。可以在浏览器中通过restfulAPI来查看stack创建是否成功。
http://:8080/api/v1/stacks
对于服务下的metainfo.xml一定要保证格式、内容的正确性,如果ambari不能正常读取,那将识别不出stack的信息。
Stack和Service的关系
Ambari中stacks相关的配置信息位于:
如果多个stacks需要使用相同的service配置,需要将配置放置于common-services中。common-services目录中存放的内容可供任意版本的stack直接使用或继承。
common-services目录位于源码包的ambari-server/src/main/resources/common-services目录中。如果某个服务需要在多个stacks之中共享,需要将此service定义在common-services中。通常来说common-services中给出了各个service的公用配置。比如下文提到的组件在ambari中的配置项(configuration)部分的配置。
Service的目录结构如下所示:
HDFS Service目录结构:
root@/var/lib/ambari-server/resources/stacks/HDP$ tree 3.0/services/HDFS/
3.0/services/HDFS/
├── alerts.json
├── configuration
│?? ├── core-site.xml
│?? ├── hadoop-env.xml
│?? ├── hadoop-metrics2.properties.xml
│?? ├── hadoop-policy.xml
│?? ├── hdfs-log4j.xml
│?? ├── hdfs-site.xml
│?? ├── ranger-hdfs-audit.xml
│?? ├── ranger-hdfs-plugin-properties.xml
│?? ├── ranger-hdfs-policymgr-ssl.xml
│?? ├── ranger-hdfs-security.xml
│?? ├── ssl-client.xml
│?? ├── ssl-server.xml
│?? └── viewfs-mount-table.xml
├── kerberos.json
├── metainfo.xml
├── metrics.json
├── package
│?? ├── alerts
│?? │?? ├── alert_checkpoint_time.py
│?? │?? ├── alert_checkpoint_time.pyc
│?? │?? ├── alert_checkpoint_time.pyo
│?? │?? ├── alert_datanode_unmounted_data_dir.py
│?? │?? ├── alert_datanode_unmounted_data_dir.pyc
│?? │?? ├── alert_datanode_unmounted_data_dir.pyo
│?? │?? ├── alert_ha_namenode_health.py
│?? │?? ├── alert_ha_namenode_health.pyc
│?? │?? ├── alert_ha_namenode_health.pyo
│?? │?? ├── alert_metrics_deviation.py
│?? │?? ├── alert_metrics_deviation.pyc
│?? │?? ├── alert_metrics_deviation.pyo
│?? │?? ├── alert_upgrade_finalized.py
│?? │?? ├── alert_upgrade_finalized.pyc
│?? │?? └── alert_upgrade_finalized.pyo
│?? ├── archive.zip
│?? ├── files
│?? │?? ├── checkWebUI.py
│?? │?? ├── checkWebUI.pyc
│?? │?? └── checkWebUI.pyo
│?? ├── scripts
│?? │?? ├── balancer-emulator
│?? │?? │?? ├── balancer-err.log
│?? │?? │?? ├── balancer.log
│?? │?? │?? ├── hdfs-command.py
│?? │?? │?? ├── hdfs-command.pyc
│?? │?? │?? └── hdfs-command.pyo
│?? │?? ├── datanode.py
│?? │?? ├── datanode.pyc
│?? │?? ├── datanode.pyo
│?? │?? ├── datanode_upgrade.py
│?? │?? ├── datanode_upgrade.pyc
│?? │?? ├── datanode_upgrade.pyo
│?? │?? ├── hdfs_client.py
│?? │?? ├── hdfs_client.pyc
│?? │?? ├── hdfs_client.pyo
│?? │?? ├── hdfs_datanode.py
│?? │?? ├── hdfs_datanode.pyc
│?? │?? ├── hdfs_datanode.pyo
│?? │?? ├── hdfs_namenode.py
│?? │?? ├── hdfs_namenode.pyc
│?? │?? ├── hdfs_namenode.pyo
│?? │?? ├── hdfs_nfsgateway.py
│?? │?? ├── hdfs_nfsgateway.pyc
│?? │?? ├── hdfs_nfsgateway.pyo
│?? │?? ├── hdfs.py
│?? │?? ├── hdfs.pyc
│?? │?? ├── hdfs.pyo
│?? │?? ├── hdfs_rebalance.py
│?? │?? ├── hdfs_rebalance.pyc
│?? │?? ├── hdfs_rebalance.pyo
│?? │?? ├── hdfs_snamenode.py
│?? │?? ├── hdfs_snamenode.pyc
│?? │?? ├── hdfs_snamenode.pyo
│?? │?? ├── __init__.py
│?? │?? ├── __init__.pyc
│?? │?? ├── __init__.pyo
│?? │?? ├── install_params.py
│?? │?? ├── install_params.pyc
│?? │?? ├── install_params.pyo
│?? │?? ├── journalnode.py
│?? │?? ├── journalnode.pyc
│?? │?? ├── journalnode.pyo
│?? │?? ├── journalnode_upgrade.py
│?? │?? ├── journalnode_upgrade.pyc
│?? │?? ├── journalnode_upgrade.pyo
│?? │?? ├── namenode_ha_state.py
│?? │?? ├── namenode_ha_state.pyc
│?? │?? ├── namenode_ha_state.pyo
│?? │?? ├── namenode.py
│?? │?? ├── namenode.pyc
│?? │?? ├── namenode.pyo
│?? │?? ├── namenode_upgrade.py
│?? │?? ├── namenode_upgrade.pyc
│?? │?? ├── namenode_upgrade.pyo
│?? │?? ├── nfsgateway.py
│?? │?? ├── nfsgateway.pyc
│?? │?? ├── nfsgateway.pyo
│?? │?? ├── params_linux.py
│?? │?? ├── params_linux.pyc
│?? │?? ├── params_linux.pyo
│?? │?? ├── params.py
│?? │?? ├── params.pyc
│?? │?? ├── params.pyo
│?? │?? ├── params_windows.py
│?? │?? ├── params_windows.pyc
│?? │?? ├── params_windows.pyo
│?? │?? ├── service_check.py
│?? │?? ├── service_check.pyc
│?? │?? ├── service_check.pyo
│?? │?? ├── setup_ranger_hdfs.py
│?? │?? ├── setup_ranger_hdfs.pyc
│?? │?? ├── setup_ranger_hdfs.pyo
│?? │?? ├── snamenode.py
│?? │?? ├── snamenode.pyc
│?? │?? ├── snamenode.pyo
│?? │?? ├── status_params.py
│?? │?? ├── status_params.pyc
│?? │?? ├── status_params.pyo
│?? │?? ├── utils.py
│?? │?? ├── utils.pyc
│?? │?? ├── utils.pyo
│?? │?? ├── zkfc_slave.py
│?? │?? ├── zkfc_slave.pyc
│?? │?? └── zkfc_slave.pyo
│?? └── templates
│?? ├── exclude_hosts_list.j2
│?? ├── hdfs.conf.j2
│?? ├── hdfs_dn_jaas.conf.j2
│?? ├── hdfs_jaas.conf.j2
│?? ├── hdfs_jn_jaas.conf.j2
│?? ├── hdfs_nn_jaas.conf.j2
│?? ├── include_hosts_list.j2
│?? ├── input.config-hdfs.json.j2
│?? └── slaves.j2
├── quicklinks
│?? └── quicklinks.json
├── service_advisor.py
├── service_advisor.pyc
├── service_advisor.pyo
├── themes
│?? ├── directories.json
│?? └── theme.json
└── widgets.json
9 directories, 135 files
root@/var/lib/ambari-server/resources/stacks/HDP$