コード例 #1
0
ファイル: serverconfig.go プロジェクト: Ramzec/lxd
func setServerConfig(d *Daemon, key string, value string) error {

	tx, err := shared.DbBegin(d.db)
	if err != nil {
		return err
	}

	_, err = tx.Exec("DELETE FROM config WHERE key=?", key)
	if err != nil {
		tx.Rollback()
		return err
	}

	if value != "" {
		str := `INSERT INTO config (key, value) VALUES (?, ?);`
		stmt, err := tx.Prepare(str)
		if err != nil {
			tx.Rollback()
			return err
		}
		defer stmt.Close()
		_, err = stmt.Exec(key, value)
		if err != nil {
			tx.Rollback()
			return err
		}
	}

	err = shared.TxCommit(tx)
	if err != nil {
		return err
	}
	return nil
}
コード例 #2
0
ファイル: images.go プロジェクト: Ramzec/lxd
func dbInsertImage(d *Daemon, fp string, fname string, sz int64, public int,
	arch int, properties map[string]string) error {
	tx, err := shared.DbBegin(d.db)
	if err != nil {
		return err
	}

	stmt, err := tx.Prepare(`INSERT INTO images (fingerprint, filename, size, public, architecture, upload_date) VALUES (?, ?, ?, ?, ?, strftime("%s"))`)
	if err != nil {
		tx.Rollback()
		return err
	}
	defer stmt.Close()

	result, err := stmt.Exec(fp, fname, sz, public, arch)
	if err != nil {
		tx.Rollback()
		return err
	}

	if len(properties) > 0 {

		id64, err := result.LastInsertId()
		if err != nil {
			tx.Rollback()
			return err
		}
		id := int(id64)

		pstmt, err := tx.Prepare(`INSERT INTO images_properties (image_id, type, key, value) VALUES (?, 0, ?, ?)`)
		if err != nil {
			tx.Rollback()
			return err
		}
		defer pstmt.Close()

		for k, v := range properties {

			// we can assume, that there is just one
			// value per key
			_, err = pstmt.Exec(id, k, v)
			if err != nil {
				tx.Rollback()
				return err
			}
		}

	}

	if err := shared.TxCommit(tx); err != nil {
		return err
	}

	return nil
}
コード例 #3
0
ファイル: container_put.go プロジェクト: Ramzec/lxd
func containerReplaceConfig(d *Daemon, ct *lxdContainer, name string, newConfig containerConfigReq) error {

	/* check to see that the config actually applies to the container
	 * successfully before saving it. in particular, raw.lxc and
	 * raw.apparmor need to be parsed once to make sure they make sense.
	 */
	if err := ct.applyConfig(newConfig.Config, false); err != nil {
		return err
	}

	tx, err := shared.DbBegin(d.db)
	if err != nil {
		return err
	}

	/* Update config or profiles */
	if err = dbClearContainerConfig(tx, ct.id); err != nil {
		shared.Debugf("Error clearing configuration for container %s\n", name)
		tx.Rollback()
		return err
	}

	if err = dbInsertContainerConfig(tx, ct.id, newConfig.Config); err != nil {
		shared.Debugf("Error inserting configuration for container %s\n", name)
		tx.Rollback()
		return err
	}

	/* handle profiles */
	if emptyProfile(newConfig.Profiles) {
		_, err := tx.Exec("DELETE from containers_profiles where container_id=?", ct.id)
		if err != nil {
			tx.Rollback()
			return err
		}
	} else {
		if err := dbInsertProfiles(tx, ct.id, newConfig.Profiles); err != nil {

			tx.Rollback()
			return err
		}
	}

	err = AddDevices(tx, "container", ct.id, newConfig.Devices)
	if err != nil {
		tx.Rollback()
		return err
	}

	return shared.TxCommit(tx)
}
コード例 #4
0
ファイル: images.go プロジェクト: Ramzec/lxd
func imageDelete(d *Daemon, r *http.Request) Response {
	fingerprint := mux.Vars(r)["fingerprint"]

	imgInfo, err := dbImageGet(d.db, fingerprint, false)
	if err != nil {
		return SmartError(err)
	}

	fname := shared.VarPath("images", imgInfo.Fingerprint)
	err = os.Remove(fname)
	if err != nil {
		shared.Debugf("Error deleting image file %s: %s\n", fname, err)
	}

	vgname, vgnameIsSet, err := getServerConfigValue(d, "core.lvm_vg_name")
	if err != nil {
		return InternalError(fmt.Errorf("Error checking server config: %v", err))
	}

	if vgnameIsSet {
		err = shared.LVMRemoveLV(vgname, imgInfo.Fingerprint)
		if err != nil {
			return InternalError(fmt.Errorf("Failed to remove deleted image LV: %v", err))
		}

		lvsymlink := fmt.Sprintf("%s.lv", fname)
		err = os.Remove(lvsymlink)
		if err != nil {
			return InternalError(fmt.Errorf("Failed to remove symlink to deleted image LV: '%s': %v", lvsymlink, err))
		}
	} else if d.BackingFs == "btrfs" {
		subvol := fmt.Sprintf("%s.btrfs", fname)
		exec.Command("btrfs", "subvolume", "delete", subvol).Run()
	}

	tx, err := shared.DbBegin(d.db)
	if err != nil {
		return InternalError(err)
	}

	_, _ = tx.Exec("DELETE FROM images_aliases WHERE image_id=?", imgInfo.Id)
	_, _ = tx.Exec("DELETE FROM images_properties WHERE image_id?", imgInfo.Id)
	_, _ = tx.Exec("DELETE FROM images WHERE id=?", imgInfo.Id)

	if err := shared.TxCommit(tx); err != nil {
		return InternalError(err)
	}

	return EmptySyncResponse
}
コード例 #5
0
ファイル: profiles.go プロジェクト: Ramzec/lxd
func dbProfileDelete(db *sql.DB, name string) error {
	tx, err := shared.DbBegin(db)
	if err != nil {
		return err
	}
	_, err = tx.Exec("DELETE FROM profiles WHERE name=?", name)
	if err != nil {
		tx.Rollback()
		return err
	}

	err = shared.TxCommit(tx)

	return err
}
コード例 #6
0
ファイル: profiles.go プロジェクト: Ramzec/lxd
func profilesPost(d *Daemon, r *http.Request) Response {
	req := profilesPostReq{}
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		return BadRequest(err)
	}

	if req.Name == "" {
		return BadRequest(fmt.Errorf("No name provided"))
	}

	name := req.Name

	tx, err := shared.DbBegin(d.db)
	if err != nil {
		return InternalError(err)
	}
	result, err := tx.Exec("INSERT INTO profiles (name) VALUES (?)", name)
	if err != nil {
		tx.Rollback()
		return SmartError(err)
	}
	id64, err := result.LastInsertId()
	if err != nil {
		tx.Rollback()
		return InternalError(fmt.Errorf("Error inserting %s into database", name))
	}
	id := int(id64)

	err = addProfileConfig(tx, id, req.Config)
	if err != nil {
		tx.Rollback()
		return SmartError(err)
	}

	err = AddDevices(tx, "profile", id, req.Devices)
	if err != nil {
		tx.Rollback()
		return SmartError(err)
	}

	err = shared.TxCommit(tx)
	if err != nil {
		return InternalError(err)
	}

	return EmptySyncResponse
}
コード例 #7
0
ファイル: certificates.go プロジェクト: Ramzec/lxd
func saveCert(d *Daemon, host string, cert *x509.Certificate) error {
	tx, err := shared.DbBegin(d.db)
	if err != nil {
		return err
	}
	fingerprint := shared.GenerateFingerprint(cert)
	stmt, err := tx.Prepare("INSERT INTO certificates (fingerprint,type,name,certificate) VALUES (?, ?, ?, ?)")
	if err != nil {
		tx.Rollback()
		return err
	}
	defer stmt.Close()
	_, err = stmt.Exec(fingerprint, 1, host, pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert.Raw}))
	if err != nil {
		tx.Rollback()
		return err
	}

	return shared.TxCommit(tx)
}
コード例 #8
0
ファイル: images.go プロジェクト: Ramzec/lxd
func imagePut(d *Daemon, r *http.Request) Response {
	fingerprint := mux.Vars(r)["fingerprint"]

	imageRaw := imagePutReq{}
	if err := json.NewDecoder(r.Body).Decode(&imageRaw); err != nil {
		return BadRequest(err)
	}

	imgInfo, err := dbImageGet(d.db, fingerprint, false)
	if err != nil {
		return SmartError(err)
	}

	tx, err := shared.DbBegin(d.db)
	if err != nil {
		return InternalError(err)
	}

	_, err = tx.Exec(`DELETE FROM images_properties WHERE image_id=?`, imgInfo.Id)

	stmt, err := tx.Prepare(`INSERT INTO images_properties (image_id, type, key, value) VALUES (?, ?, ?, ?)`)
	if err != nil {
		tx.Rollback()
		return InternalError(err)
	}

	for key, value := range imageRaw.Properties {
		_, err = stmt.Exec(imgInfo.Id, 0, key, value)
		if err != nil {
			tx.Rollback()
			return InternalError(err)
		}
	}

	if err := shared.TxCommit(tx); err != nil {
		return InternalError(err)
	}

	return EmptySyncResponse
}
コード例 #9
0
ファイル: db.go プロジェクト: Ramzec/lxd
func createDefaultProfile(db *sql.DB) error {
	rows, err := shared.DbQuery(db, "SELECT id FROM profiles WHERE name=?", "default")
	if err != nil {
		return err
	}
	defer rows.Close()
	id := -1
	for rows.Next() {
		var xId int
		rows.Scan(&xId)
		id = xId
	}
	if id != -1 {
		// default profile already exists
		return nil
	}

	tx, err := shared.DbBegin(db)
	if err != nil {
		return err
	}
	result, err := tx.Exec("INSERT INTO profiles (name) VALUES (?)", "default")
	if err != nil {
		tx.Rollback()
		return err
	}
	id64, err := result.LastInsertId()
	if err != nil {
		tx.Rollback()
		return err
	}
	id = int(id64)

	result, err = tx.Exec(`INSERT INTO profiles_devices 
		(profile_id, name, type) VALUES (?, ?, ?)`,
		id, "eth0", "nic")
	if err != nil {
		tx.Rollback()
		return err
	}
	id64, err = result.LastInsertId()
	if err != nil {
		tx.Rollback()
		return err
	}
	devId := int(id64)

	_, err = tx.Exec(`INSERT INTO profiles_devices_config
		(profile_device_id, key, value) VALUES (?, ?, ?)`,
		devId, "nictype", "bridged")
	if err != nil {
		tx.Rollback()
		return err
	}

	/* TODO - analyze system to choose a bridge */
	_, err = tx.Exec(`INSERT INTO profiles_devices_config
		(profile_device_id, key, value) VALUES (?, ?, ?)`,
		devId, "parent", "lxcbr0")
	if err != nil {
		tx.Rollback()
		return err
	}

	if err := tx.Commit(); err != nil {
		return err
	}

	return nil
}
コード例 #10
0
ファイル: profiles.go プロジェクト: Ramzec/lxd
func profilePut(d *Daemon, r *http.Request) Response {
	name := mux.Vars(r)["name"]

	req := profilesPostReq{}
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		return BadRequest(err)
	}

	tx, err := shared.DbBegin(d.db)
	if err != nil {
		return InternalError(err)
	}

	rows, err := tx.Query("SELECT id FROM profiles WHERE name=?", name)
	if err != nil {
		tx.Rollback()
		return SmartError(err)
	}
	var id int
	for rows.Next() {
		var i int
		err = rows.Scan(&i)
		if err != nil {
			shared.Debugf("DBERR: profilePut: scan returned error %q\n", err)
			tx.Rollback()
			return InternalError(err)
		}
		id = i
	}
	rows.Close()
	err = rows.Err()
	if err != nil {
		shared.Debugf("DBERR: profilePut: Err returned an error %q\n", err)
		tx.Rollback()
		return InternalError(err)
	}

	err = dbClearProfileConfig(tx, id)
	if err != nil {
		tx.Rollback()
		return InternalError(err)
	}

	err = addProfileConfig(tx, id, req.Config)
	if err != nil {
		tx.Rollback()
		return SmartError(err)
	}

	err = AddDevices(tx, "profile", id, req.Devices)
	if err != nil {
		tx.Rollback()
		return SmartError(err)
	}

	err = shared.TxCommit(tx)
	if err != nil {
		return InternalError(err)
	}

	return EmptySyncResponse
}