Exemplo n.º 1
0
Arquivo: images.go Projeto: Ramzec/lxd
func doImageGet(d *Daemon, fingerprint string, public bool) (shared.ImageInfo, Response) {
	imgInfo, err := dbImageGet(d.db, fingerprint, public)
	if err != nil {
		return shared.ImageInfo{}, SmartError(err)
	}

	q := "SELECT key, value FROM images_properties where image_id=?"
	var key, value, name, desc string
	inargs := []interface{}{imgInfo.Id}
	outfmt := []interface{}{key, value}
	results, err := shared.DbQueryScan(d.db, q, inargs, outfmt)
	if err != nil {
		return shared.ImageInfo{}, SmartError(err)
	}
	properties := map[string]string{}
	for _, r := range results {
		key = r[0].(string)
		value = r[1].(string)
		properties[key] = value
	}

	q = "SELECT name, description FROM images_aliases WHERE image_id=?"
	inargs = []interface{}{imgInfo.Id}
	outfmt = []interface{}{name, desc}
	results, err = shared.DbQueryScan(d.db, q, inargs, outfmt)
	if err != nil {
		return shared.ImageInfo{}, InternalError(err)
	}
	aliases := shared.ImageAliases{}
	for _, r := range results {
		name = r[0].(string)
		desc = r[0].(string)
		a := shared.ImageAlias{Name: name, Description: desc}
		aliases = append(aliases, a)
	}

	info := shared.ImageInfo{Fingerprint: imgInfo.Fingerprint,
		Filename:     imgInfo.Filename,
		Properties:   properties,
		Aliases:      aliases,
		Public:       imgInfo.Public,
		Size:         imgInfo.Size,
		Architecture: imgInfo.Architecture,
		CreationDate: imgInfo.CreationDate,
		ExpiryDate:   imgInfo.ExpiryDate,
		UploadDate:   imgInfo.UploadDate}

	return info, nil
}
Exemplo n.º 2
0
/*
 * Note, the code below doesn't deal with snapshots of snapshots.
 * To do that, we'll need to weed out based on # slashes in names
 */
func nextSnapshot(d *Daemon, name string) int {
	base := fmt.Sprintf("%s/snap", name)
	length := len(base)
	q := fmt.Sprintf("SELECT MAX(name) FROM containers WHERE type=? AND SUBSTR(name,1,?)=?")
	var numstr string
	inargs := []interface{}{cTypeSnapshot, length, base}
	outfmt := []interface{}{numstr}
	results, err := shared.DbQueryScan(d.db, q, inargs, outfmt)
	if err != nil {
		return 0
	}
	max := 0

	for _, r := range results {
		numstr = r[0].(string)
		if len(numstr) <= length {
			continue
		}
		substr := numstr[length:]
		var num int
		count, err := fmt.Sscanf(substr, "%d", &num)
		if err != nil || count != 1 {
			continue
		}
		if num >= max {
			max = num + 1
		}
	}

	return max
}
Exemplo n.º 3
0
func containersWatch(d *Daemon) error {
	q := fmt.Sprintf("SELECT name FROM containers WHERE type=?")
	inargs := []interface{}{cTypeRegular}
	var name string
	outfmt := []interface{}{name}

	result, err := shared.DbQueryScan(d.db, q, inargs, outfmt)
	if err != nil {
		return err
	}

	for _, r := range result {
		container, err := newLxdContainer(string(r[0].(string)), d)
		if err != nil {
			return err
		}

		if container.ephemeral == true && container.c.State() != lxc.STOPPED {
			containerWatchEphemeral(container)
		}
	}

	/*
	 * force collect the containers we created above; see comment in
	 * daemon.go:createCmd.
	 */
	runtime.GC()

	return nil
}
Exemplo n.º 4
0
Arquivo: db.go Projeto: Ramzec/lxd
// Get a list of profiles for a given container id.
func dbGetProfiles(db *sql.DB, containerId int) ([]string, error) {
	var name string
	var profiles []string

	query := `
        SELECT name FROM containers_profiles
        JOIN profiles ON containers_profiles.profile_id=profiles.id
		WHERE container_id=?
        ORDER BY containers_profiles.apply_order`
	inargs := []interface{}{containerId}
	outfmt := []interface{}{name}

	results, err := shared.DbQueryScan(db, query, inargs, outfmt)
	if err != nil {
		return nil, err
	}

	for _, r := range results {
		name = r[0].(string)

		profiles = append(profiles, name)
	}

	return profiles, nil
}
Exemplo n.º 5
0
Arquivo: db.go Projeto: Ramzec/lxd
func dbGetDeviceConfig(db *sql.DB, id int, isprofile bool) (shared.Device, error) {
	var query string
	var key, value string
	newdev := shared.Device{} // That's a map[string]string
	inargs := []interface{}{id}
	outfmt := []interface{}{key, value}

	if isprofile {
		query = `SELECT key, value FROM profiles_devices_config WHERE profile_device_id=?`
	} else {
		query = `SELECT key, value FROM containers_devices_config WHERE container_device_id=?`
	}

	results, err := shared.DbQueryScan(db, query, inargs, outfmt)

	if err != nil {
		return newdev, err
	}

	for _, r := range results {
		key = r[0].(string)
		value = r[1].(string)
		newdev[key] = value
	}

	return newdev, nil
}
Exemplo n.º 6
0
func containersRestart(d *Daemon) error {
	q := fmt.Sprintf("SELECT name FROM containers WHERE type=? AND power_state=1")
	inargs := []interface{}{cTypeRegular}
	var name string
	outfmt := []interface{}{name}

	result, err := shared.DbQueryScan(d.db, q, inargs, outfmt)
	if err != nil {
		return err
	}

	_, err = shared.DbExec(d.db, "UPDATE containers SET power_state=0")
	if err != nil {
		return err
	}

	for _, r := range result {
		container, err := newLxdContainer(string(r[0].(string)), d)
		if err != nil {
			return err
		}

		err = templateApply(container, "start")
		if err != nil {
			return err
		}

		container.c.Start()
	}

	return nil
}
Exemplo n.º 7
0
Arquivo: images.go Projeto: Ramzec/lxd
func aliasesGet(d *Daemon, r *http.Request) Response {
	recursion := d.isRecursionRequest(r)

	q := "SELECT name FROM images_aliases"
	var name string
	inargs := []interface{}{}
	outfmt := []interface{}{name}
	results, err := shared.DbQueryScan(d.db, q, inargs, outfmt)
	if err != nil {
		return BadRequest(err)
	}
	response_str := make([]string, 0)
	response_map := make([]shared.ImageAlias, 0)
	for _, res := range results {
		name = res[0].(string)
		if !recursion {
			url := fmt.Sprintf("/%s/images/aliases/%s", shared.APIVersion, name)
			response_str = append(response_str, url)

		} else {
			alias, err := doAliasGet(d, name, d.isTrustedClient(r))
			if err != nil {
				continue
			}
			response_map = append(response_map, alias)
		}
	}

	if !recursion {
		return SyncResponse(true, response_str)
	} else {
		return SyncResponse(true, response_map)
	}
}
Exemplo n.º 8
0
Arquivo: db.go Projeto: Ramzec/lxd
// Get the profile configuration map from the DB
func dbGetProfileConfig(db *sql.DB, name string) (map[string]string, error) {
	var key, value string
	query := `
        SELECT
            key, value
        FROM profiles_config
        JOIN profiles ON profiles_config.profile_id=profiles.id
		WHERE name=?`
	inargs := []interface{}{name}
	outfmt := []interface{}{key, value}
	results, err := shared.DbQueryScan(db, query, inargs, outfmt)
	if err != nil {
		return nil, err
	}

	if len(results) == 0 {
		/*
		 * If we didn't get any rows here, let's check to make sure the
		 * profile really exists; if it doesn't, let's send back a 404.
		 */
		query := "SELECT id FROM profiles WHERE name=?"
		var id int
		results, err := shared.DbQueryScan(db, query, []interface{}{name}, []interface{}{id})
		if err != nil {
			return nil, err
		}

		if len(results) == 0 {
			return nil, NoSuchObjectError
		}
	}

	config := map[string]string{}

	for _, r := range results {
		key = r[0].(string)
		value = r[1].(string)

		config[key] = value
	}

	return config, nil
}
Exemplo n.º 9
0
func containerSnapshotsGet(d *Daemon, r *http.Request) Response {
	recursion_str := r.FormValue("recursion")
	recursion, err := strconv.Atoi(recursion_str)
	if err != nil {
		recursion = 0
	}

	cname := mux.Vars(r)["name"]
	c, err := newLxdContainer(cname, d)
	if err != nil {
		return SmartError(err)
	}

	regexp := fmt.Sprintf("%s/", cname)
	length := len(regexp)
	q := "SELECT name FROM containers WHERE type=? AND SUBSTR(name,1,?)=?"
	var name string
	inargs := []interface{}{cTypeSnapshot, length, regexp}
	outfmt := []interface{}{name}
	results, err := shared.DbQueryScan(d.db, q, inargs, outfmt)
	if err != nil {
		return SmartError(err)
	}

	var result_string []string
	var result_map []shared.Jmap

	for _, r := range results {
		name = r[0].(string)
		if recursion == 0 {
			url := fmt.Sprintf("/%s/containers/%s/snapshots/%s", shared.APIVersion, cname, name)
			result_string = append(result_string, url)
		} else {
			_, err := os.Stat(snapshotStateDir(c, name))
			body := shared.Jmap{"name": name, "stateful": err == nil}
			result_map = append(result_map, body)
		}

	}

	if recursion == 0 {
		return SyncResponse(true, result_string)
	} else {
		return SyncResponse(true, result_map)
	}

}
Exemplo n.º 10
0
Arquivo: db.go Projeto: Ramzec/lxd
func dbListContainers(d *Daemon) ([]string, error) {
	q := fmt.Sprintf("SELECT name FROM containers WHERE type=? ORDER BY name")
	inargs := []interface{}{cTypeRegular}
	var container string
	outfmt := []interface{}{container}
	result, err := shared.DbQueryScan(d.db, q, inargs, outfmt)
	if err != nil {
		return nil, err
	}

	ret := make([]string, 0)
	for _, container := range result {
		ret = append(ret, container[0].(string))
	}

	return ret, nil
}
Exemplo n.º 11
0
func profilesGet(d *Daemon, r *http.Request) Response {
	q := fmt.Sprintf("SELECT name FROM profiles")
	inargs := []interface{}{}
	var name string
	outfmt := []interface{}{name}
	result, err := shared.DbQueryScan(d.db, q, inargs, outfmt)
	if err != nil {
		return SmartError(err)
	}
	response := []string{}
	for _, r := range result {
		name := r[0].(string)
		url := fmt.Sprintf("/%s/profiles/%s", shared.APIVersion, name)
		response = append(response, url)
	}

	return SyncResponse(true, response)
}
Exemplo n.º 12
0
func containerDeleteSnapshots(d *Daemon, cname string) error {
	prefix := fmt.Sprintf("%s/", cname)
	length := len(prefix)
	q := "SELECT name, id FROM containers WHERE type=? AND SUBSTR(name,1,?)=?"
	var id int
	var sname string
	inargs := []interface{}{cTypeSnapshot, length, prefix}
	outfmt := []interface{}{sname, id}
	results, err := shared.DbQueryScan(d.db, q, inargs, outfmt)
	if err != nil {
		return err
	}

	var ids []int

	backing_fs, err := shared.GetFilesystem(shared.VarPath("lxc", cname))
	if err != nil && !os.IsNotExist(err) {
		shared.Debugf("Error cleaning up snapshots: %s\n", err)
		return err
	}

	for _, r := range results {
		sname = r[0].(string)
		id = r[1].(int)
		ids = append(ids, id)
		cdir := shared.VarPath("lxc", cname, "snapshots", sname)

		if backing_fs == "btrfs" {
			exec.Command("btrfs", "subvolume", "delete", cdir).Run()
		}
		os.RemoveAll(cdir)
	}

	for _, id := range ids {
		_, err = shared.DbExec(d.db, "DELETE FROM containers WHERE id=?", id)
		if err != nil {
			return err
		}
	}

	return nil
}
Exemplo n.º 13
0
func doContainerGet(d *Daemon, cname string) (shared.ContainerInfo, Response) {
	_, err := dbGetContainerId(d.db, cname)
	if err != nil {
		return shared.ContainerInfo{}, SmartError(err)
	}

	c, err := newLxdContainer(cname, d)
	if err != nil {
		return shared.ContainerInfo{}, SmartError(err)
	}

	var name string
	regexp := fmt.Sprintf("%s/", cname)
	length := len(regexp)
	q := "SELECT name FROM containers WHERE type=? AND SUBSTR(name,1,?)=?"
	inargs := []interface{}{cTypeSnapshot, length, regexp}
	outfmt := []interface{}{name}
	results, err := shared.DbQueryScan(d.db, q, inargs, outfmt)
	if err != nil {
		return shared.ContainerInfo{}, SmartError(err)
	}

	var body []string

	for _, r := range results {
		name = r[0].(string)

		url := fmt.Sprintf("/%s/containers/%s/snapshots/%s", shared.APIVersion, cname, name)
		body = append(body, url)
	}

	cts, err := c.RenderState()
	if err != nil {
		return shared.ContainerInfo{}, SmartError(err)
	}

	containerinfo := shared.ContainerInfo{State: *cts,
		Snaps: body}

	return containerinfo, nil
}
Exemplo n.º 14
0
Arquivo: db.go Projeto: Ramzec/lxd
func dbGetDevices(db *sql.DB, qName string, isprofile bool) (shared.Devices, error) {
	var q string
	if isprofile {
		q = `SELECT profiles_devices.id, profiles_devices.name, profiles_devices.type
			FROM profiles_devices JOIN profiles
			ON profiles_devices.profile_id = profiles.id
			WHERE profiles.name=?`
	} else {
		q = `SELECT containers_devices.id, containers_devices.name, containers_devices.type
			FROM containers_devices JOIN containers
			ON containers_devices.container_id = containers.id
			WHERE containers.name=?`
	}
	var id int
	var name, dtype string
	inargs := []interface{}{qName}
	outfmt := []interface{}{id, name, dtype}
	results, err := shared.DbQueryScan(db, q, inargs, outfmt)
	if err != nil {
		return nil, err
	}

	devices := shared.Devices{}
	for _, r := range results {
		id = r[0].(int)
		name = r[1].(string)
		dtype = r[2].(string)
		newdev, err := dbGetDeviceConfig(db, id, isprofile)
		if err != nil {
			return nil, err
		}
		newdev["type"] = dtype
		devices[name] = newdev
	}

	return devices, nil
}
Exemplo n.º 15
0
func containersShutdown(d *Daemon) error {
	q := fmt.Sprintf("SELECT name FROM containers WHERE type=?")
	inargs := []interface{}{cTypeRegular}
	var name string
	outfmt := []interface{}{name}

	result, err := shared.DbQueryScan(d.db, q, inargs, outfmt)
	if err != nil {
		return err
	}

	var wg sync.WaitGroup

	for _, r := range result {
		container, err := newLxdContainer(string(r[0].(string)), d)
		if err != nil {
			return err
		}

		_, err = shared.DbExec(d.db, "UPDATE containers SET power_state=1 WHERE name=?", container.name)
		if err != nil {
			return err
		}

		if container.c.State() != lxc.STOPPED {
			wg.Add(1)
			go func() {
				container.c.Shutdown(time.Second * 30)
				container.c.Stop()
				wg.Done()
			}()
		}
		wg.Wait()
	}

	return nil
}
Exemplo n.º 16
0
Arquivo: images.go Projeto: Ramzec/lxd
func doImagesGet(d *Daemon, recursion bool, public bool) (interface{}, error) {
	result_string := make([]string, 0)
	result_map := make([]shared.ImageInfo, 0)

	q := "SELECT fingerprint FROM images"
	var name string
	if public == true {
		q = "SELECT fingerprint FROM images WHERE public=1"
	}
	inargs := []interface{}{}
	outfmt := []interface{}{name}
	results, err := shared.DbQueryScan(d.db, q, inargs, outfmt)
	if err != nil {
		return []string{}, err
	}

	for _, r := range results {
		name = r[0].(string)
		if !recursion {
			url := fmt.Sprintf("/%s/images/%s", shared.APIVersion, name)
			result_string = append(result_string, url)
		} else {
			image, response := doImageGet(d, name, public)
			if response != nil {
				continue
			}
			result_map = append(result_map, image)
		}
	}

	if !recursion {
		return result_string, nil
	} else {
		return result_map, nil
	}
}
Exemplo n.º 17
0
Arquivo: db.go Projeto: Ramzec/lxd
// Get the container configuration map from the DB
func dbGetConfig(db *sql.DB, containerId int) (map[string]string, error) {
	var key, value string
	q := `SELECT key, value FROM containers_config WHERE container_id=?`

	inargs := []interface{}{containerId}
	outfmt := []interface{}{key, value}

	// Results is already a slice here, not db Rows anymore.
	results, err := shared.DbQueryScan(db, q, inargs, outfmt)
	if err != nil {
		return nil, err //SmartError will wrap this and make "not found" errors pretty
	}

	config := map[string]string{}

	for _, r := range results {
		key = r[0].(string)
		value = r[1].(string)

		config[key] = value
	}

	return config, nil
}