func FromFile(path string) (chklst Checklist, err error) {
	log.Debugf("Creating checklist from %s", path)
	return FromBytes(chkutil.FileToBytes(path))
}
FromFile reads the file at the path and parses its utf8 encoded yaml
data, turning it into a checklist struct.
package checklists
import (
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"github.com/CiscoCloud/distributive/chkutil"
	"github.com/CiscoCloud/distributive/errutil"
	log "github.com/Sirupsen/logrus"
	"github.com/ghodss/yaml"
)
var remoteCheckDir = "/var/run/distributive/"
type Checklist struct {
	Name   string
	Checks []*CheckWrapper  
	Origin string           
}
func (chklst *Checklist) MakeReport() (anyFailed bool, report string) {
	if chklst == nil {  
		log.Warn("Nil checklist passed to makeReport. Please report this bug.")
		return
	}
	log.Debug("Making report for " + chklst.Name)
	codes := make(chan int)
	msgs := make(chan string)
	for _, chk := range chklst.Checks {
		log.Info("Running check " + chk.ID())
		go func(chk *CheckWrapper, codes chan int, msgs chan string) {
			log.Debug("Running check " + chk.ID())
			code, msg, err := chk.Status()
			if err != nil {
				log.WithFields(log.Fields{
					"ID":    chk.ID(),
					"error": err.Error(),
				}).Warn("There was an error running a check")
			}
			codes <- code
			msgs <- msg
		}(chk, codes, msgs)
	}
	total := len(chklst.Checks)
	passed := 0
	failed := 0
	other := 0
	for _ = range chklst.Checks {
		code := <-codes
		switch code {
		case 0:
			passed++
		case 1:
			failed++
		default:
			other++
		}
	}
	close(codes)
	report += "↴\nTotal: " + fmt.Sprint(total)
	report += "\nPassed: " + fmt.Sprint(passed)
	report += "\nFailed: " + fmt.Sprint(failed)
	report += "\nOther: " + fmt.Sprint(other)
	for _ = range chklst.Checks {
		if msg := <-msgs; msg != "" {
			report += "\n" + msg
		}
	}
	close(msgs)
	return (failed > 0), report
}
type CheckYAML struct {
	ID string `json:"id"`
	Parameters []string `json:"parameters"`
}
type ChecklistYAML struct {
	Name      string      `json:"name"`
	Checklist []CheckYAML `json"checklist"`
}
func FromBytes(data []byte) (chklst Checklist, err error) {
	var chklstYAML ChecklistYAML
	err = yaml.Unmarshal(data, &chklstYAML)
	if err != nil {
		return chklst, err
	}
	chklst.Name = chklstYAML.Name
	for _, chkYAML := range chklstYAML.Checklist {
		chkStruct := constructCheck(chkYAML)
		if chkStruct == nil {
			log.WithFields(log.Fields{
				"check":     chkYAML.ID,
				"checklist": chklst.Name,
				"params":    chkYAML.Parameters,
			}).Fatal("Unable to parse check")
		}
		_, err := chkStruct.New(chkYAML.Parameters)
		if err != nil {
			log.WithFields(log.Fields{
				"check":  chkYAML.ID,
				"params": chkYAML.Parameters,
				"error":  err.Error(),
			}).Fatal("Error while constructing check")
		}
		chklst.Checks = append(chklst.Checks, chkStruct)
	}
	if len(chklst.Checks) < 1 {
		log.WithFields(log.Fields{
			"checklist": chklst.Name,
		}).Fatal("Checklist had no checks associated with it!")
	}
	return chklst, nil
}