Heat Providers

本文介绍如何使用OpenStack Heat的资源提供者特性来定义自定义模板,并通过实例演示创建资源组及获取嵌套堆栈详情的过程。

Providers are an extension to our existing internal model, which allows user-definable "resource providers" to be specified via templates.

1. Register “Resource Providers”

For example, use Global Environment to register resource "My::WP::Server":

root@test725:~# cat /etc/heat/environment.d/default.yaml 
resource_registry:
    # allow older templates with Quantum in them.
    "OS::Quantum*": "OS::Neutron*"
    # Choose your implementation of AWS::CloudWatch::Alarm
    #"AWS::CloudWatch::Alarm": "file:///etc/heat/templates/AWS_CloudWatch_Alarm.yaml"
    "AWS::CloudWatch::Alarm": "OS::Heat::CWLiteAlarm"
    "OS::Metering::Alarm": "OS::Ceilometer::Alarm"
    "AWS::RDS::DBInstance": ”file:///etc/heat/templates/AWS_RDS_DBInstance.yaml”
    "My::WP::Server": "file:///etc/heat/templates/server.yaml"

Please note that the template resource URL here must end with ”.yaml” or ”.template”, or it will not be treated as a custom template resource.

Here, /etc/heat/templates/server.yaml is customizable template defined by yourself:

heat_template_version: 2013-05-23

description: Test Template

parameters:
  image:
    default: 7a3dcd55-b793-4523-9da9-231433902020 
    type: string
    description: Image use to boot a server

  net:
    default: e8542140-27cb-4474-8bd1-c726413b20c8 
    type: string
    description: Network ID for the server

  flavor:
    default: m1.small 
    type: string
    description: Flavor use to boot a server
    
  key_name:
    default: demo-key 
    type: string
    description: keypair name use to boot a server

resources:
  init:
    type: OS::Heat::SoftwareConfig
    properties:
      group: script 
      inputs:
      - name: welcome_msg 
      config: |
        #!/bin/bash
        echo $welcome_msg > ~/welcome.txt

  deployment:
    type: OS::Heat::SoftwareDeployment
    properties:
      config:
        get_resource: init 
      server:
        get_resource: server
      input_values:
        welcome_msg: "Hello, world"

  server:
    type: OS::Nova::Server
    properties:
      image: {get_param: image}
      networks:
      - uuid: {get_param: net}
      flavor: {get_param: flavor} 
      key_name: {get_param: key_name}
      user_data_format: SOFTWARE_CONFIG 

outputs:
  server_private_ip:
    description: IP address of the server in the private network
    value: { get_attr: [ server, first_address ] }

Now, restart service heat-engine, you can find similar messages in /var/log/heat/heat-engine.log:

INFO heat.engine.environment [-] Registering My::WP::Server -> file:///etc/heat/templates/server.yaml

And you can verify it by this:

root@test725:~# heat resource-type-list | grep My::WP::Server
| My::WP::Server  |


2. Create Stack with providers resource

heat stack-create -f resource_group.yml stack55

Here resource_group.yml is like this, and server_private_ip is the output in server.yaml:

heat_template_version: 2013-05-23

description: Test Resource Group Template

resources:
  servers:
    type: OS::Heat::ResourceGroup
    properties:
      count: 2
      resource_def:
        type: My::WP::Server 

outputs:
  server_resources:
    description: The actual server details
    value: { get_attr: [servers, refs]}

  server_0_private_ip:
    description: private ip of server 0
    value: { get_attr: [servers, resource.0.server_private_ip]}

  server_1_private_ip:
    description: private ip of server 1
    value: { get_attr: [servers, resource.1.server_private_ip]}

Also, you can verify it:


In addition, you can get the nested stack details:




3. References

https://wiki.openstack.org/wiki/Heat/Providers
http://hardysteven.blogspot.com/2013/10/heat-providersenvironments-101-ive.html
http://hardysteven.blogspot.com/2013/08/heat-nested-resource-introspection.html
http://docs.openstack.org/developer/heat/template_guide/environment.html

http://docs.openstack.org/developer/heat/template_guide/openstack.html

private void setupBarChart(com.github.mikephil.charting.charts.BarChart chart, List<BarEntry> entries, float minY, float maxY, int number, int charType, boolean isWeek) { // 基本配置 chart.setDrawGridBackground(false); chart.getDescription().setEnabled(false); chart.getLegend().setEnabled(false); chart.setTouchEnabled(false); chart.setDrawValueAboveBar(false); chart.setBackgroundColor(Color.TRANSPARENT); chart.setAutoScaleMinMaxEnabled(false); // Y轴配置 YAxis leftAxis = chart.getAxisLeft(); leftAxis.setEnabled(false); YAxis rightAxis = chart.getAxisRight(); rightAxis.setTextColor(Color.parseColor("#6C7A89")); rightAxis.setTextSize(3f); rightAxis.setAxisMinimum(minY); rightAxis.setAxisMaximum(maxY); rightAxis.setDrawGridLines(true); rightAxis.setGridColor(Color.parseColor("#1E2532")); rightAxis.setLabelCount(number, true); // X轴配置 XAxis xAxis = chart.getXAxis(); xAxis.setEnabled(true); xAxis.setDrawLabels(true); xAxis.setPosition(XAxis.XAxisPosition.BOTTOM); xAxis.setDrawGridLines(false); xAxis.setTextColor(Color.parseColor("#6C7A89")); xAxis.setTextSize(8f); xAxis.setLabelCount(13, true); xAxis.setAxisMinimum(0); xAxis.setAxisMaximum(isWeek ? 9f: 1440f); xAxis.setGranularity(isWeek?1f:120f); // 最小间隔 1 秒 xAxis.setAvoidFirstLastClipping(true); xAxis.setValueFormatter(new ValueFormatter() { @Override public String getFormattedValue(float value) { if (isWeek) { int week = (int) value; if (week >= 1 && week <= 7) { return weekDays[week]; } return ""; } else { int hour = (int) (value / 60); int minute = (int) (value % 60); if (hour % 2 == 0 && minute == 0) { return String.format(Locale.getDefault(), "%02d:%02d", hour, minute); } return ""; } } }); List<BarEntry> newList1 = new ArrayList<>(entries); //charType1为血氧 2为压力 3 为体温 其他为默认正常色 ValueGradientProvider provider = (e, dsIndex, idx) -> { float y = e.getY(); if (charType == 1) { if (y >= 95f) { return new int[]{colorBens.get("green").getStartColor(), colorBens.get("green").getEndColor()}; } else if (y > 88f) { return new int[]{colorBens.get("yellow").getStartColor(), colorBens.get("yellow").getEndColor()}; } else { return new int[]{colorBens.get("red").getStartColor(), colorBens.get("red").getEndColor()}; } } else if (charType == 2) { if (y > 45f) { return new int[]{colorBens.get("red").getStartColor(), colorBens.get("red").getEndColor()}; } else if (y > 30f) { return new int[]{colorBens.get("yellow").getStartColor(), colorBens.get("yellow").getEndColor()}; } else if (y > 15f) { return new int[]{colorBens.get("green").getStartColor(), colorBens.get("green").getEndColor()}; } else { return new int[]{colorBens.get("blue").getStartColor(), colorBens.get("blue").getEndColor()}; } } else if (charType == 3) { if (y >= 38.0f) { return new int[]{colorBens.get("red").getStartColor(), colorBens.get("red").getEndColor()}; } else if (y > 37.2f) { return new int[]{colorBens.get("yellow").getStartColor(), colorBens.get("yellow").getEndColor()}; } else { return new int[]{colorBens.get("green").getStartColor(), colorBens.get("green").getEndColor()}; } } else return new int[]{colorBens.get("green").getStartColor(), colorBens.get("green").getEndColor()}; }; GradientBarChartRenderer renderer = new GradientBarChartRenderer( chart, chart.getAnimator(), chart.getViewPortHandler(), provider ); chart.setRenderer(renderer); // 数据集配置 BarDataSet dataSet1 = new BarDataSet(newList1, ".."); dataSet1.setAxisDependency(YAxis.AxisDependency.RIGHT); BarData barData = new BarData(dataSet1); barData.setBarWidth(16f); barData.setDrawValues(false); chart.setVisibleXRangeMaximum(1440f); // 强制显示 1440 分钟范围 chart.moveViewToX(0); chart.setData(barData); chart.invalidate(); private final String[] weekDays = {"", "周一", "周二", "周三", "周四", "周五", "周六", "周日", ""}; long zzz = TimeTools.updateDateTime("2025-08-21 19:30:00","yyyy-MM-dd"); //// // entryList_heat.add(new BarEntry((float) (TimeTools.updateDateTime("2025-08-21 19:30:00", "yyyy-MM-dd HH:mm") - zzz) /60/1000 ,36)); // entryList_heat.add(new BarEntry((float) (TimeTools.updateDateTime("2025-08-21 20:30:00", "yyyy-MM-dd HH:mm") - zzz) /60/1000 ,37)); // entryList_heat.add(new BarEntry((float) (TimeTools.updateDateTime("2025-08-21 21:30:00", "yyyy-MM-dd HH:mm") - zzz) /60/1000 ,37.2f)); entryList_heat.add(new BarEntry((float) (TimeTools.updateDateTime("2025-08-21 22:30:00", "yyyy-MM-dd HH:mm") - zzz) /60/1000 ,36.7f)); entryList_heat.add(new BarEntry((float) (TimeTools.updateDateTime("2025-08-21 05:30:00", "yyyy-MM-dd HH:mm") - zzz) /60/1000 ,35)); entryList_heat.add(new BarEntry((float) (TimeTools.updateDateTime("2025-08-21 06:30:00", "yyyy-MM-dd HH:mm") - zzz) /60/1000 ,99)); entryList_heat.add(new BarEntry((float) (TimeTools.updateDateTime("2025-08-21 10:30:00", "yyyy-MM-dd HH:mm") - zzz) /60/1000 ,96)); entryList_heat.add(new BarEntry((float) (TimeTools.updateDateTime("2025-08-21 11:30:00", "yyyy-MM-dd HH:mm") - zzz) /60/1000 ,95)); entryList_heat.add(new BarEntry((float) (TimeTools.updateDateTime("2025-08-21 12:30:00", "yyyy-MM-dd HH:mm") - zzz) /60/1000 ,99)); // bigCardDialog.updateTiwenList(entryList_heat,colorBens); // setupBarChart(mBinding.pIdTiwen.barchart, entryList_heat, 0, 45, "HH:mm", 3); // setupLineChart(mBinding.pIdXinzang.linechart, barEntryList_xinzang, 40,120,"#EA7A61","#4AEA7A61"); List<String > stringList = new ArrayList<>(); stringList.add(1 + " %"); stringList.add(1 + " %"); stringList.add(1 + " %"); bigCardDialog.updateOxgbloodList(entryList_heat, colorBens,stringList); 数据没有显示
09-04
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值