func (p ContainerWrap) LabelByKey(key string) (string, error) {
	if val, ok := p.Labels[key]; ok {
		return val, nil
	}

	logging.Debug("LabelByKey:: container: %s: key %q is not present", p.Name, key)
	return "", nil
}
func processTemplates(cnf *config.Config) error {

	apiURL := cnf.Host + cnf.Prefix
	meta, err := metadata.NewClientAndWait(apiURL)
	if err != nil {
		return errors.Annotate(err, "get meta client")
	}

	logging.Info("connect rancher metadata url: %q", apiURL)

	//expand template paths
	logging.Debug("expand template paths")
	for idx, set := range cnf.Sets {
		if !path.IsAbs(set.TemplatePath) {
			cnf.Sets[idx].TemplatePath = path.Join(DEFAULT_TEMPLATE_DIR, set.TemplatePath)
		}
	}

	version := "init"
	for {
		newVersion, err := meta.GetVersion()
		if err != nil {
			return errors.Annotate(err, "get version")
		}

		if newVersion == version {
			time.Sleep(5 * time.Second)
			continue
		}

		version = newVersion
		logging.Info("metadata changed - refresh config")

		for _, set := range cnf.Sets {
			scratch.Reset()
			if err := processTemplateSet(meta, set); err != nil {
				return errors.Annotate(err, "process template set")
			}
		}

		time.Sleep(time.Duration(cnf.Repeat) * time.Second)
	}

	return nil
}
func (p ContainerWrap) PortInternal(idx int) (string, error) {
	if len(p.Ports) == 0 {
		return "", nil
	}

	if idx >= len(p.Ports) {
		return "", errors.Errorf("PortInternal:: index %d out of range", idx)
	}

	part := p.Ports[idx]
	if part == "" {
		return part, nil
	}

	logging.Debug(part)
	items := strings.Split(part, ":")
	part = items[len(items)-1]
	if strings.Contains(part, "/") {
		part = strings.Split(part, "/")[0]
	}

	return part, nil

}