示例#1
0
/* Returns a sorted list of all the versions of this cookbook */
func (c *Cookbook) sortedVersions() []*CookbookVersion {
	if config.UsingDB() {
		return c.sortedCookbookVersionsSQL()
	}
	sorted := make([]*CookbookVersion, len(c.Versions))
	keys := make(VersionStrings, len(c.Versions))

	u := 0
	for k, cbv := range c.Versions {
		keys[u] = k
		u++
		datastore.ChkNilArray(cbv)
	}
	sort.Sort(sort.Reverse(keys))

	/* populate sorted now */
	for i, s := range keys {
		/* This shouldn't be able to happen, but somehow it... does? */
		if i >= len(sorted) {
			break
		}
		sorted[i] = c.Versions[s]
	}
	return sorted
}
示例#2
0
// Fill an environment in from a row returned from the SQL server. See the
// equivalent function in node/node.go for more details.
//
// As there, the SQL query that made the row needs to have the same number &
// order of columns as the one in Get(), even if the WHERE clause is different
// or omitted.
func (e *ChefEnvironment) fillEnvFromSQL(row datastore.ResRow) error {
	var (
		da []byte
		oa []byte
		cv []byte
	)
	err := row.Scan(&e.Name, &e.Description, &da, &oa, &cv)
	if err != nil {
		return err
	}

	e.ChefType = "environment"
	e.JSONClass = "Chef::Environment"
	if e.Name == "_default" {
		e.Default = make(map[string]interface{})
		e.Override = make(map[string]interface{})
		e.CookbookVersions = make(map[string]string)
		return nil
	}

	err = datastore.DecodeBlob(da, &e.Default)
	if err != nil {
		return err
	}
	err = datastore.DecodeBlob(oa, &e.Override)
	if err != nil {
		return err
	}
	err = datastore.DecodeBlob(cv, &e.CookbookVersions)
	if err != nil {
		return err
	}
	datastore.ChkNilArray(e)
	return nil
}
示例#3
0
func (r *Role) fillRoleFromSQL(row datastore.ResRow) error {
	var (
		rl []byte
		er []byte
		da []byte
		oa []byte
	)
	err := row.Scan(&r.Name, &r.Description, &rl, &er, &da, &oa)
	if err != nil {
		return err
	}
	r.ChefType = "role"
	r.JSONClass = "Chef::Role"
	err = datastore.DecodeBlob(rl, &r.RunList)
	if err != nil {
		return err
	}
	err = datastore.DecodeBlob(er, &r.EnvRunLists)
	if err != nil {
		return err
	}
	err = datastore.DecodeBlob(da, &r.Default)
	if err != nil {
		return err
	}
	err = datastore.DecodeBlob(oa, &r.Override)
	if err != nil {
		return err
	}
	datastore.ChkNilArray(r)

	return nil
}
示例#4
0
// LatestVersion gets the latest version of this cookbook.
func (c *Cookbook) LatestVersion() *CookbookVersion {
	if c.latest == nil {
		sorted := c.sortedVersions()
		c.latest = sorted[0]
		if c.latest != nil {
			datastore.ChkNilArray(c.latest)
		}
	}
	return c.latest
}
示例#5
0
func (dbi *DataBagItem) fillDBItemFromSQL(row datastore.ResRow) error {
	var rawb []byte
	err := row.Scan(&dbi.id, &dbi.dataBagID, &dbi.Name, &dbi.origName, &dbi.DataBagName, &rawb)
	if err != nil {
		return err
	}
	dbi.ChefType = "data_bag_item"
	dbi.JSONClass = "Chef::DataBagItem"
	err = datastore.DecodeBlob(rawb, &dbi.RawData)
	if err != nil {
		return err
	}
	datastore.ChkNilArray(dbi)
	return nil
}
示例#6
0
// GetVersion gets a particular version of the cookbook.
func (c *Cookbook) GetVersion(cbVersion string) (*CookbookVersion, util.Gerror) {
	if cbVersion == "_latest" {
		return c.LatestVersion(), nil
	}
	var cbv *CookbookVersion
	var found bool

	if config.UsingDB() {
		// Ridiculously cacheable, but let's get it working first. This
		// applies all over the place w/ the SQL bits.
		if cbv, found = c.Versions[cbVersion]; !found {
			var err error
			cbv, err = c.getCookbookVersionSQL(cbVersion)
			if err != nil {
				if err == sql.ErrNoRows {
					found = false
				} else {
					gerr := util.Errorf(err.Error())
					gerr.SetStatus(http.StatusInternalServerError)
					return nil, gerr
				}
			} else {
				found = true
				c.Versions[cbVersion] = cbv
			}
		}
	} else {
		cbv, found = c.Versions[cbVersion]
		if cbv != nil {
			datastore.ChkNilArray(cbv)
			if cbv.Recipes == nil {
				cbv.Recipes = make([]map[string]interface{}, 0)
			}
		}
	}

	if !found {
		err := util.Errorf("Cannot find a cookbook named %s with version %s", c.Name, cbVersion)
		err.SetStatus(http.StatusNotFound)
		return nil, err
	}
	return cbv, nil
}
示例#7
0
// Get a cookbook.
func Get(name string) (*Cookbook, util.Gerror) {
	var cookbook *Cookbook
	var found bool
	if config.UsingDB() {
		var err error
		cookbook, err = getCookbookSQL(name)
		if err != nil {
			if err == sql.ErrNoRows {
				found = false
			} else {
				gerr := util.CastErr(err)
				gerr.SetStatus(http.StatusInternalServerError)
				return nil, gerr
			}
		} else {
			found = true
		}
	} else {
		ds := datastore.New()
		var c interface{}
		c, found = ds.Get("cookbook", name)
		if c != nil {
			cookbook = c.(*Cookbook)
		}
		/* hrm. */
		if cookbook != nil && config.Config.UseUnsafeMemStore {
			for _, v := range cookbook.Versions {
				datastore.ChkNilArray(v)
			}
		}
	}
	if !found {
		err := util.Errorf("Cannot find a cookbook named %s", name)
		err.SetStatus(http.StatusNotFound)
		return nil, err
	}
	return cookbook, nil
}
示例#8
0
// Fill in a node from a row returned from the SQL server. Useful for the case
// down the road where an array of objects is needed, but building it with
// a call to GetList(), then repeated calls to Get() sucks with a real db even
// if it's marginally acceptable in in-memory mode.
//
// NB: This does require the query to look like the one in Get().
func (n *Node) fillNodeFromSQL(row datastore.ResRow) error {
	var (
		rl []byte
		aa []byte
		na []byte
		da []byte
		oa []byte
	)
	err := row.Scan(&n.Name, &n.ChefEnvironment, &rl, &aa, &na, &da, &oa)
	if err != nil {
		return err
	}
	n.ChefType = "node"
	n.JSONClass = "Chef::Node"
	err = datastore.DecodeBlob(rl, &n.RunList)
	if err != nil {
		return err
	}
	err = datastore.DecodeBlob(aa, &n.Automatic)
	if err != nil {
		return err
	}
	err = datastore.DecodeBlob(na, &n.Normal)
	if err != nil {
		return err
	}
	err = datastore.DecodeBlob(da, &n.Default)
	if err != nil {
		return err
	}
	err = datastore.DecodeBlob(oa, &n.Override)
	if err != nil {
		return err
	}
	datastore.ChkNilArray(n)
	return nil
}
示例#9
0
func (cbv *CookbookVersion) fillCookbookVersionFromSQL(row datastore.ResRow) error {
	var (
		defb  []byte
		libb  []byte
		attb  []byte
		recb  []byte
		prob  []byte
		resb  []byte
		temb  []byte
		roob  []byte
		filb  []byte
		metb  []byte
		major int64
		minor int64
		patch int64
	)
	err := row.Scan(&cbv.id, &cbv.cookbookID, &defb, &libb, &attb, &recb, &prob, &resb, &temb, &roob, &filb, &metb, &major, &minor, &patch, &cbv.IsFrozen, &cbv.CookbookName)
	if err != nil {
		return err
	}
	/* Now... populate it. :-/ */
	// These may need to accept x.y versions with only two elements
	// instead of x.y.0 with the added default 0 patch number.
	cbv.Version = fmt.Sprintf("%d.%d.%d", major, minor, patch)
	cbv.Name = fmt.Sprintf("%s-%s", cbv.CookbookName, cbv.Version)
	cbv.ChefType = "cookbook_version"
	cbv.JSONClass = "Chef::CookbookVersion"

	/* TODO: experiment some more with getting this done with
	 * pointers. */
	err = datastore.DecodeBlob(metb, &cbv.Metadata)
	if err != nil {
		return err
	}
	err = datastore.DecodeBlob(defb, &cbv.Definitions)
	if err != nil {
		return err
	}
	err = datastore.DecodeBlob(libb, &cbv.Libraries)
	if err != nil {
		return err
	}
	err = datastore.DecodeBlob(attb, &cbv.Attributes)
	if err != nil {
		return err
	}
	err = datastore.DecodeBlob(recb, &cbv.Recipes)
	if err != nil {
		return err
	}
	err = datastore.DecodeBlob(prob, &cbv.Providers)
	if err != nil {
		return err
	}
	err = datastore.DecodeBlob(temb, &cbv.Templates)
	if err != nil {
		return err
	}
	err = datastore.DecodeBlob(resb, &cbv.Resources)
	if err != nil {
		return err
	}
	err = datastore.DecodeBlob(roob, &cbv.RootFiles)
	if err != nil {
		return err
	}
	err = datastore.DecodeBlob(filb, &cbv.Files)
	if err != nil {
		return err
	}
	datastore.ChkNilArray(cbv)

	return nil
}