<commit_before>package main

import (
	"database/sql"
	"fmt"
	"strings"

	"git.zxq.co/ripple/rippleapi/common"
	"git.zxq.co/x/rs"
	"github.com/gin-gonic/gin"
	"golang.org/x/crypto/bcrypt"
	"gopkg.in/mailgun/mailgun-go.v1"
)

func passwordReset(c *gin.Context) {
	ctx := getContext(c)
	if ctx.User.ID != 0 {
		simpleReply(c, errorMessage{"You're already logged in!"})
		return
	}

	field := "username"
	if strings.Contains(c.PostForm("username"), "@") {
		field = "email"
	}

	var (
		id         int
		username   string
		email      string
		privileges uint64
	)

	err := db.QueryRow("SELECT id, username, email, privileges FROM users WHERE "+field+" = ?",
		c.PostForm("username")).
		Scan(&id, &username, &email, &privileges)

	switch err {
	case nil:
		// ignore
	case sql.ErrNoRows:
		simpleReply(c, errorMessage{"That user could not be found."})
		return
	default:
		c.Error(err)
		resp500(c)
		return
	}

	if common.UserPrivileges(privileges)&
		(common.UserPrivilegeNormal|common.UserPrivilegePendingVerification) == 0 {
		simpleReply(c, errorMessage{"You look pretty banned/locked here."})
		return
	}

	// generate key
	key := rs.String(50)

	// TODO: WHY THE FUCK DOES THIS USE USERNAME AND NOT ID PLEASE WRITE MIGRATION
	_, err = db.Exec("INSERT INTO password_recovery(k, u) VALUES (?, ?)", key, username)

	if err != nil {
		c.Error(err)
		resp500(c)
		return
	}

	content := fmt.Sprintf(
		"Hey %s! Someone, which we really hope was you, requested a password reset for your account. "+
			"In case it was you, please click here to reset your password on Ripple. "+
			"Otherwise, silently ignore this email.",
		username,
		config.BaseURL+"/pwreset/continue?k="+key,
	)
	msg := mailgun.NewMessage(
		config.MailgunFrom,
		"Ripple password recovery instructions",
		content,
		email,
	)
	msg.SetHtml(content)
	_, _, err = mg.Send(msg)

	if err != nil {
		c.Error(err)
		resp500(c)
		return
	}

	addMessage(c, successMessage{"Done! You should shortly receive an email from us at the email you used to sign up on Ripple."})
	getSession(c).Save()
	c.Redirect(302, "/")
}

func passwordResetContinue(c *gin.Context) {
	k := c.Query("k")

	// todo: check logged in
	if k == "" {
		respEmpty(c, "Password reset", errorMessage{"Nope."})
		return
	}

	var username string
	switch err := db.QueryRow("SELECT u FROM password_recovery WHERE k = ? LIMIT 1", k).
		Scan(&username); err {
	case nil:
		// move on
	case sql.ErrNoRows:
		respEmpty(c, "Reset password", errorMessage{"That key could not be found. Perhaps it expired?"})
		return
	default:
		c.Error(err)
		resp500(c)
		return
	}

	renderResetPassword(c, username, k)
}

func passwordResetContinueSubmit(c *gin.Context) {
	// todo: check logged in
	var username string
	switch err := db.QueryRow("SELECT u FROM password_recovery WHERE k = ? LIMIT 1", c.PostForm("k")).
		Scan(&username); err {
	case nil:
		// move on
	case sql.ErrNoRows:
		respEmpty(c, "Reset password", errorMessage{"That key could not be found. Perhaps it expired?"})
		return
	default:
		c.Error(err)
		resp500(c)
		return
	}

	p := c.PostForm("password")

	if s := validatePassword(p); s != "" {
		renderResetPassword(c, username, c.PostForm("k"), errorMessage{s})
		return
	}

	pass, err := generatePassword(p)
	if err != nil {
		c.Error(err)
		resp500(c)
		return
	}

	_, err = db.Exec("UPDATE users SET password_md5 = ?, salt = '', password_version = '2' WHERE username = ?",
		pass, username)
	if err != nil {
		c.Error(err)
		resp500(c)
		return
	}

	_, err = db.Exec("DELETE FROM password_recovery WHERE k = ? LIMIT 1", c.PostForm("k"))
	if err != nil {
		c.Error(err)
		resp500(c)
		return
	}

	addMessage(c, successMessage{"All right, we have changed your password and you should now be able to login! Have fun!"})
	getSession(c).Save()
	c.Redirect(302, "/login")
}

func renderResetPassword(c *gin.Context, username, k string, messages ...message) {
	simple(c, getSimpleByFilename("pwreset/continue.html"), messages, map[string]interface{}{
		"Username": username,
		"Key":      k,
	})
}

func generatePassword(p string) (string, error) {
	s, err := bcrypt.GenerateFromPassword([]byte(cmd5(p)), bcrypt.DefaultCost)
	return string(s), err
}

func changePassword(c *gin.Context) {
	ctx := getContext(c)
	if ctx.User.ID == 0 {
		resp403(c)
	}
	s, err := qb.QueryRow("SELECT email FROM users WHERE id = ?", ctx.User.ID)
	if err != nil {
		c.Error(err)
	}
	simple(c, getSimpleByFilename("settings/password.html"), nil, map[string]interface{}{
		"email": s["email"],
	})
}

func changePasswordSubmit(c *gin.Context) {
	var messages []message
	ctx := getContext(c)
	if ctx.User.ID == 0 {
		resp403(c)
	}
	defer func() {
		s, err := qb.QueryRow("SELECT email FROM users WHERE id = ?", ctx.User.ID)
		if err != nil {
			c.Error(err)
		}
		simple(c, getSimpleByFilename("settings/password.html"), messages, map[string]interface{}{
			"email": s["email"],
		})
	}()

	var password string
	db.Get(&password, "SELECT password_md5 FROM users WHERE id = ? LIMIT 1", ctx.User.ID)

	if err := bcrypt.CompareHashAndPassword(
		[]byte(password),
		[]byte(cmd5(c.PostForm("currentpassword"))),
	); err != nil {
		messages = append(messages, errorMessage{"Wrong password."})
		return
	}

	uq := new(common.UpdateQuery)
	uq.Add("email", c.PostForm("email"))
	if c.PostForm("newpassword") != "" {
		if s := validatePassword(c.PostForm("newpassword")); s != "" {
			messages = append(messages, errorMessage{s})
			return
		}
		pw, err := generatePassword(c.PostForm("newpassword"))
		if err == nil {
			uq.Add("password_md5", pw)
		}
		sess := getSession(c)
		sess.Set("pw", cmd5(pw))
		sess.Save()
	}
	_, err := db.Exec("UPDATE users SET "+uq.Fields()+" WHERE id = ? LIMIT 1", append(uq.Parameters, ctx.User.ID)...)
	if err != nil {
		c.Error(err)
	}

	messages = append(messages, successMessage{"Your settings have been saved."})
}
<commit_msg>Reset EmailVerified flag when changing email<commit_after>package main

import (
	"database/sql"
	"fmt"
	"strings"

	"git.zxq.co/ripple/rippleapi/common"
	"git.zxq.co/x/rs"
	"github.com/gin-gonic/gin"
	"golang.org/x/crypto/bcrypt"
	"gopkg.in/mailgun/mailgun-go.v1"
)

func passwordReset(c *gin.Context) {
	ctx := getContext(c)
	if ctx.User.ID != 0 {
		simpleReply(c, errorMessage{"You're already logged in!"})
		return
	}

	field := "username"
	if strings.Contains(c.PostForm("username"), "@") {
		field = "email"
	}

	var (
		id         int
		username   string
		email      string
		privileges uint64
	)

	err := db.QueryRow("SELECT id, username, email, privileges FROM users WHERE "+field+" = ?",
		c.PostForm("username")).
		Scan(&id, &username, &email, &privileges)

	switch err {
	case nil:
		// ignore
	case sql.ErrNoRows:
		simpleReply(c, errorMessage{"That user could not be found."})
		return
	default:
		c.Error(err)
		resp500(c)
		return
	}

	if common.UserPrivileges(privileges)&
		(common.UserPrivilegeNormal|common.UserPrivilegePendingVerification) == 0 {
		simpleReply(c, errorMessage{"You look pretty banned/locked here."})
		return
	}

	// generate key
	key := rs.String(50)

	// TODO: WHY THE FUCK DOES THIS USE USERNAME AND NOT ID PLEASE WRITE MIGRATION
	_, err = db.Exec("INSERT INTO password_recovery(k, u) VALUES (?, ?)", key, username)

	if err != nil {
		c.Error(err)
		resp500(c)
		return
	}

	content := fmt.Sprintf(
		"Hey %s! Someone, which we really hope was you, requested a password reset for your account. "+
			"In case it was you, please click here to reset your password on Ripple. "+
			"Otherwise, silently ignore this email.",
		username,
		config.BaseURL+"/pwreset/continue?k="+key,
	)
	msg := mailgun.NewMessage(
		config.MailgunFrom,
		"Ripple password recovery instructions",
		content,
		email,
	)
	msg.SetHtml(content)
	_, _, err = mg.Send(msg)

	if err != nil {
		c.Error(err)
		resp500(c)
		return
	}

	addMessage(c, successMessage{"Done! You should shortly receive an email from us at the email you used to sign up on Ripple."})
	getSession(c).Save()
	c.Redirect(302, "/")
}

func passwordResetContinue(c *gin.Context) {
	k := c.Query("k")

	// todo: check logged in
	if k == "" {
		respEmpty(c, "Password reset", errorMessage{"Nope."})
		return
	}

	var username string
	switch err := db.QueryRow("SELECT u FROM password_recovery WHERE k = ? LIMIT 1", k).
		Scan(&username); err {
	case nil:
		// move on
	case sql.ErrNoRows:
		respEmpty(c, "Reset password", errorMessage{"That key could not be found. Perhaps it expired?"})
		return
	default:
		c.Error(err)
		resp500(c)
		return
	}

	renderResetPassword(c, username, k)
}

func passwordResetContinueSubmit(c *gin.Context) {
	// todo: check logged in
	var username string
	switch err := db.QueryRow("SELECT u FROM password_recovery WHERE k = ? LIMIT 1", c.PostForm("k")).
		Scan(&username); err {
	case nil:
		// move on
	case sql.ErrNoRows:
		respEmpty(c, "Reset password", errorMessage{"That key could not be found. Perhaps it expired?"})
		return
	default:
		c.Error(err)
		resp500(c)
		return
	}

	p := c.PostForm("password")

	if s := validatePassword(p); s != "" {
		renderResetPassword(c, username, c.PostForm("k"), errorMessage{s})
		return
	}

	pass, err := generatePassword(p)
	if err != nil {
		c.Error(err)
		resp500(c)
		return
	}

	_, err = db.Exec("UPDATE users SET password_md5 = ?, salt = '', password_version = '2' WHERE username = ?",
		pass, username)
	if err != nil {
		c.Error(err)
		resp500(c)
		return
	}

	_, err = db.Exec("DELETE FROM password_recovery WHERE k = ? LIMIT 1", c.PostForm("k"))
	if err != nil {
		c.Error(err)
		resp500(c)
		return
	}

	addMessage(c, successMessage{"All right, we have changed your password and you should now be able to login! Have fun!"})
	getSession(c).Save()
	c.Redirect(302, "/login")
}

func renderResetPassword(c *gin.Context, username, k string, messages ...message) {
	simple(c, getSimpleByFilename("pwreset/continue.html"), messages, map[string]interface{}{
		"Username": username,
		"Key":      k,
	})
}

func generatePassword(p string) (string, error) {
	s, err := bcrypt.GenerateFromPassword([]byte(cmd5(p)), bcrypt.DefaultCost)
	return string(s), err
}

func changePassword(c *gin.Context) {
	ctx := getContext(c)
	if ctx.User.ID == 0 {
		resp403(c)
	}
	s, err := qb.QueryRow("SELECT email FROM users WHERE id = ?", ctx.User.ID)
	if err != nil {
		c.Error(err)
	}
	simple(c, getSimpleByFilename("settings/password.html"), nil, map[string]interface{}{
		"email": s["email"],
	})
}

func changePasswordSubmit(c *gin.Context) {
	var messages []message
	ctx := getContext(c)
	if ctx.User.ID == 0 {
		resp403(c)
	}
	defer func() {
		s, err := qb.QueryRow("SELECT email FROM users WHERE id = ?", ctx.User.ID)
		if err != nil {
			c.Error(err)
		}
		simple(c, getSimpleByFilename("settings/password.html"), messages, map[string]interface{}{
			"email": s["email"],
		})
	}()

	var password string
	db.Get(&password, "SELECT password_md5 FROM users WHERE id = ? LIMIT 1", ctx.User.ID)

	if err := bcrypt.CompareHashAndPassword(
		[]byte(password),
		[]byte(cmd5(c.PostForm("currentpassword"))),
	); err != nil {
		messages = append(messages, errorMessage{"Wrong password."})
		return
	}

	uq := new(common.UpdateQuery)
	uq.Add("email", c.PostForm("email"))
	if c.PostForm("newpassword") != "" {
		if s := validatePassword(c.PostForm("newpassword")); s != "" {
			messages = append(messages, errorMessage{s})
			return
		}
		pw, err := generatePassword(c.PostForm("newpassword"))
		if err == nil {
			uq.Add("password_md5", pw)
		}
		sess := getSession(c)
		sess.Set("pw", cmd5(pw))
		sess.Save()
	}
	_, err := db.Exec("UPDATE users SET "+uq.Fields()+" WHERE id = ? LIMIT 1", append(uq.Parameters, ctx.User.ID)...)
	if err != nil {
		c.Error(err)
	}

	db.Exec("UPDATE users SET flags = flags & ~3 WHERE id = ? LIMIT 1", ctx.User.ID)

	messages = append(messages, successMessage{"Your settings have been saved."})
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"sync"
	"sync/atomic"

	"github.com/pkg/errors"

	"github.com/lxc/lxd/lxd/db"
	"github.com/lxc/lxd/lxd/device"
	"github.com/lxc/lxd/lxd/instance"
	"github.com/lxc/lxd/lxd/instance/instancetype"
	"github.com/lxc/lxd/lxd/state"
	storagePools "github.com/lxc/lxd/lxd/storage"
	storageDrivers "github.com/lxc/lxd/lxd/storage/drivers"
	"github.com/lxc/lxd/shared"
	"github.com/lxc/lxd/shared/idmap"
	"github.com/lxc/lxd/shared/logger"
	"github.com/lxc/lxd/shared/version"
)

func init() {
	// Expose storageVolumeMount to the device package as StorageVolumeMount.
	device.StorageVolumeMount = storageVolumeMount

	// Expose storageVolumeUmount to the device package as StorageVolumeUmount.
	device.StorageVolumeUmount = storageVolumeUmount

	// Expose storageRootFSApplyQuota to the device package as StorageRootFSApplyQuota.
	device.StorageRootFSApplyQuota = storageRootFSApplyQuota
}

// Simply cache used to storage the activated drivers on this LXD instance. This
// allows us to avoid querying the database everytime and API call is made.
var storagePoolDriversCacheVal atomic.Value
var storagePoolDriversCacheLock sync.Mutex

func readStoragePoolDriversCache() map[string]string {
	drivers := storagePoolDriversCacheVal.Load()
	if drivers == nil {
		return map[string]string{}
	}

	return drivers.(map[string]string)
}

func storagePoolVolumeAttachPrepare(s *state.State, poolName string, volumeName string, volumeType int, c instance.Container) error {
	// Load the DB records
	poolID, pool, err := s.Cluster.StoragePoolGet(poolName)
	if err != nil {
		return err
	}

	_, volume, err := s.Cluster.StoragePoolNodeVolumeGetTypeByProject("default", volumeName, volumeType, poolID)
	if err != nil {
		return err
	}

	poolVolumePut := volume.Writable()

	// Check if unmapped
	if shared.IsTrue(poolVolumePut.Config["security.unmapped"]) {
		// No need to look at containers and maps for unmapped volumes
		return nil
	}

	// Get the on-disk idmap for the volume
	var lastIdmap *idmap.IdmapSet
	if poolVolumePut.Config["volatile.idmap.last"] != "" {
		lastIdmap, err = idmap.JSONUnmarshal(poolVolumePut.Config["volatile.idmap.last"])
		if err != nil {
			logger.Errorf("Failed to unmarshal last idmapping: %s", poolVolumePut.Config["volatile.idmap.last"])
			return err
		}
	}

	var nextIdmap *idmap.IdmapSet
	nextJsonMap := "[]"
	if !shared.IsTrue(poolVolumePut.Config["security.shifted"]) {
		// Get the container's idmap
		if c.IsRunning() {
			nextIdmap, err = c.CurrentIdmap()
		} else {
			nextIdmap, err = c.NextIdmap()
		}
		if err != nil {
			return err
		}

		if nextIdmap != nil {
			nextJsonMap, err = idmapsetToJSON(nextIdmap)
			if err != nil {
				return err
			}
		}
	}
	poolVolumePut.Config["volatile.idmap.next"] = nextJsonMap

	// Get mountpoint of storage volume
	remapPath := storagePools.GetStoragePoolVolumeMountPoint(poolName, volumeName)

	if !nextIdmap.Equals(lastIdmap) {
		logger.Debugf("Shifting storage volume")

		if !shared.IsTrue(poolVolumePut.Config["security.shifted"]) {
			volumeUsedBy, err := storagePoolVolumeUsedByInstancesGet(s, "default", poolName, volumeName)
			if err != nil {
				return err
			}

			if len(volumeUsedBy) > 1 {
				for _, ctName := range volumeUsedBy {
					instt, err := instance.LoadByProjectAndName(s, c.Project(), ctName)
					if err != nil {
						continue
					}

					if instt.Type() != instancetype.Container {
						continue
					}

					ct := instt.(instance.Container)

					var ctNextIdmap *idmap.IdmapSet
					if ct.IsRunning() {
						ctNextIdmap, err = ct.CurrentIdmap()
					} else {
						ctNextIdmap, err = ct.NextIdmap()
					}
					if err != nil {
						return fmt.Errorf("Failed to retrieve idmap of container")
					}

					if !nextIdmap.Equals(ctNextIdmap) {
						return fmt.Errorf("Idmaps of container %v and storage volume %v are not identical", ctName, volumeName)
					}
				}
			} else if len(volumeUsedBy) == 1 {
				// If we're the only one who's attached that container
				// we can shift the storage volume.
				// I'm not sure if we want some locking here.
				if volumeUsedBy[0] != c.Name() {
					return fmt.Errorf("idmaps of container and storage volume are not identical")
				}
			}
		}

		// Unshift rootfs
		if lastIdmap != nil {
			var err error

			if pool.Driver == "zfs" {
				err = lastIdmap.UnshiftRootfs(remapPath, storageDrivers.ShiftZFSSkipper)
			} else {
				err = lastIdmap.UnshiftRootfs(remapPath, nil)
			}

			if err != nil {
				logger.Errorf("Failed to unshift \"%s\"", remapPath)
				return err
			}

			logger.Debugf("Unshifted \"%s\"", remapPath)
		}

		// Shift rootfs
		if nextIdmap != nil {
			var err error

			if pool.Driver == "zfs" {
				err = nextIdmap.ShiftRootfs(remapPath, storageDrivers.ShiftZFSSkipper)
			} else {
				err = nextIdmap.ShiftRootfs(remapPath, nil)
			}

			if err != nil {
				logger.Errorf("Failed to shift \"%s\"", remapPath)
				return err
			}

			logger.Debugf("Shifted \"%s\"", remapPath)
		}
		logger.Debugf("Shifted storage volume")
	}

	jsonIdmap := "[]"
	if nextIdmap != nil {
		var err error
		jsonIdmap, err = idmapsetToJSON(nextIdmap)
		if err != nil {
			logger.Errorf("Failed to marshal idmap")
			return err
		}
	}

	// Update last idmap
	poolVolumePut.Config["volatile.idmap.last"] = jsonIdmap

	err = s.Cluster.StoragePoolVolumeUpdateByProject("default", volumeName, volumeType, poolID, poolVolumePut.Description, poolVolumePut.Config)
	if err != nil {
		return err
	}

	return nil
}

func resetContainerDiskIdmap(container instance.Container, srcIdmap *idmap.IdmapSet) error {
	dstIdmap, err := container.DiskIdmap()
	if err != nil {
		return err
	}

	if dstIdmap == nil {
		dstIdmap = new(idmap.IdmapSet)
	}

	if !srcIdmap.Equals(dstIdmap) {
		var jsonIdmap string
		if srcIdmap != nil {
			idmapBytes, err := json.Marshal(srcIdmap.Idmap)
			if err != nil {
				return err
			}
			jsonIdmap = string(idmapBytes)
		} else {
			jsonIdmap = "[]"
		}

		err := container.VolatileSet(map[string]string{"volatile.last_state.idmap": jsonIdmap})
		if err != nil {
			return err
		}
	}

	return nil
}

func setupStorageDriver(s *state.State, forceCheck bool) error {
	pools, err := s.Cluster.StoragePoolsNotPending()
	if err != nil {
		if err == db.ErrNoSuchObject {
			logger.Debugf("No existing storage pools detected")
			return nil
		}
		logger.Debugf("Failed to retrieve existing storage pools")
		return err
	}

	// In case the daemon got killed during upgrade we will already have a
	// valid storage pool entry but it might have gotten messed up and so we
	// cannot perform StoragePoolCheck(). This case can be detected by
	// looking at the patches db: If we already have a storage pool defined
	// but the upgrade somehow got messed up then there will be no
	// "storage_api" entry in the db.
	if len(pools) > 0 && !forceCheck {
		appliedPatches, err := s.Node.Patches()
		if err != nil {
			return err
		}

		if !shared.StringInSlice("storage_api", appliedPatches) {
			logger.Warnf("Incorrectly applied \"storage_api\" patch, skipping storage pool initialization as it might be corrupt")
			return nil
		}

	}

	for _, poolName := range pools {
		logger.Debugf("Initializing and checking storage pool %q", poolName)
		errPrefix := fmt.Sprintf("Failed initializing storage pool %q", poolName)

		pool, err := storagePools.GetPoolByName(s, poolName)
		if err != nil {
			return errors.Wrap(err, errPrefix)
		}

		_, err = pool.Mount()
		if err != nil {
			return errors.Wrap(err, errPrefix)
		}
	}

	// Update the storage drivers cache in api_1.0.go.
	storagePoolDriversCacheUpdate(s)
	return nil
}

func storagePoolDriversCacheUpdate(s *state.State) {
	// Get a list of all storage drivers currently in use
	// on this LXD instance. Only do this when we do not already have done
	// this once to avoid unnecessarily querying the db. All subsequent
	// updates of the cache will be done when we create or delete storage
	// pools in the db. Since this is a rare event, this cache
	// implementation is a classic frequent-read, rare-update case so
	// copy-on-write semantics without locking in the read case seems
	// appropriate. (Should be cheaper then querying the db all the time,
	// especially if we keep adding more storage drivers.)

	drivers, err := s.Cluster.StoragePoolsGetDrivers()
	if err != nil && err != db.ErrNoSuchObject {
		return
	}

	data := map[string]string{}

	// Get the driver info.
	info := storageDrivers.SupportedDrivers(s)
	for _, entry := range info {
		if shared.StringInSlice(entry.Name, drivers) {
			data[entry.Name] = entry.Version
		}
	}

	// Prepare the cache entries.
	backends := []string{}
	for k, v := range data {
		backends = append(backends, fmt.Sprintf("%s %s", k, v))
	}

	// Update the user agent.
	version.UserAgentStorageBackends(backends)

	storagePoolDriversCacheLock.Lock()
	storagePoolDriversCacheVal.Store(data)
	storagePoolDriversCacheLock.Unlock()

	return
}

// storageVolumeMount initialises a new storage interface and checks the pool and volume are
// mounted. If they are not then they are mounted.
func storageVolumeMount(state *state.State, poolName string, volumeName string, volumeTypeName string, inst instance.Instance) error {
	c, ok := inst.(instance.Container)
	if !ok {
		return fmt.Errorf("Received non-LXC container instance")
	}

	volumeType, err := storagePools.VolumeTypeNameToType(volumeTypeName)
	if err != nil {
		return err
	}

	pool, err := storagePools.GetPoolByName(state, poolName)
	if err != nil {
		return err
	}

	// Mount the storage volume.
	ourMount, err := pool.MountCustomVolume(volumeName, nil)
	if err != nil {
		return err
	}

	revert := true
	if ourMount {
		defer func() {
			if !revert {
				return
			}

			pool.UnmountCustomVolume(volumeName, nil)
		}()
	}

	// Custom storage volumes do not currently support projects, so hardcode "default" project.
	err = storagePoolVolumeAttachPrepare(state, poolName, volumeName, volumeType, c)
	if err != nil {
		return err
	}

	revert = false
	return nil
}

// storageVolumeUmount unmounts a storage volume on a pool.
func storageVolumeUmount(state *state.State, poolName string, volumeName string, volumeType int) error {
	pool, err := storagePools.GetPoolByName(state, poolName)
	if err != nil {
		return err
	}

	_, err = pool.UnmountCustomVolume(volumeName, nil)
	if err != nil {
		return err
	}

	return nil
}

// storageRootFSApplyQuota applies a quota to an instance if it can, if it cannot then it will
// return false indicating that the quota needs to be stored in volatile to be applied on next boot.
func storageRootFSApplyQuota(state *state.State, inst instance.Instance, size string) error {
	pool, err := storagePools.GetPoolByInstance(state, inst)
	if err != nil {
		return err
	}

	err = pool.SetInstanceQuota(inst, size, nil)
	if err != nil {
		return err
	}

	return nil
}
<commit_msg>lxd/storage: Removes storageVolumeMount and storagePoolVolumeAttachPrepare<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"sync"
	"sync/atomic"

	"github.com/pkg/errors"

	"github.com/lxc/lxd/lxd/db"
	"github.com/lxc/lxd/lxd/device"
	"github.com/lxc/lxd/lxd/instance"
	"github.com/lxc/lxd/lxd/state"
	storagePools "github.com/lxc/lxd/lxd/storage"
	storageDrivers "github.com/lxc/lxd/lxd/storage/drivers"
	"github.com/lxc/lxd/shared"
	"github.com/lxc/lxd/shared/idmap"
	"github.com/lxc/lxd/shared/logger"
	"github.com/lxc/lxd/shared/version"
)

func init() {
	// Expose storageVolumeUmount to the device package as StorageVolumeUmount.
	device.StorageVolumeUmount = storageVolumeUmount

	// Expose storageRootFSApplyQuota to the device package as StorageRootFSApplyQuota.
	device.StorageRootFSApplyQuota = storageRootFSApplyQuota
}

// Simply cache used to storage the activated drivers on this LXD instance. This
// allows us to avoid querying the database everytime and API call is made.
var storagePoolDriversCacheVal atomic.Value
var storagePoolDriversCacheLock sync.Mutex

func readStoragePoolDriversCache() map[string]string {
	drivers := storagePoolDriversCacheVal.Load()
	if drivers == nil {
		return map[string]string{}
	}

	return drivers.(map[string]string)
}

func resetContainerDiskIdmap(container instance.Container, srcIdmap *idmap.IdmapSet) error {
	dstIdmap, err := container.DiskIdmap()
	if err != nil {
		return err
	}

	if dstIdmap == nil {
		dstIdmap = new(idmap.IdmapSet)
	}

	if !srcIdmap.Equals(dstIdmap) {
		var jsonIdmap string
		if srcIdmap != nil {
			idmapBytes, err := json.Marshal(srcIdmap.Idmap)
			if err != nil {
				return err
			}
			jsonIdmap = string(idmapBytes)
		} else {
			jsonIdmap = "[]"
		}

		err := container.VolatileSet(map[string]string{"volatile.last_state.idmap": jsonIdmap})
		if err != nil {
			return err
		}
	}

	return nil
}

func setupStorageDriver(s *state.State, forceCheck bool) error {
	pools, err := s.Cluster.StoragePoolsNotPending()
	if err != nil {
		if err == db.ErrNoSuchObject {
			logger.Debugf("No existing storage pools detected")
			return nil
		}
		logger.Debugf("Failed to retrieve existing storage pools")
		return err
	}

	// In case the daemon got killed during upgrade we will already have a
	// valid storage pool entry but it might have gotten messed up and so we
	// cannot perform StoragePoolCheck(). This case can be detected by
	// looking at the patches db: If we already have a storage pool defined
	// but the upgrade somehow got messed up then there will be no
	// "storage_api" entry in the db.
	if len(pools) > 0 && !forceCheck {
		appliedPatches, err := s.Node.Patches()
		if err != nil {
			return err
		}

		if !shared.StringInSlice("storage_api", appliedPatches) {
			logger.Warnf("Incorrectly applied \"storage_api\" patch, skipping storage pool initialization as it might be corrupt")
			return nil
		}

	}

	for _, poolName := range pools {
		logger.Debugf("Initializing and checking storage pool %q", poolName)
		errPrefix := fmt.Sprintf("Failed initializing storage pool %q", poolName)

		pool, err := storagePools.GetPoolByName(s, poolName)
		if err != nil {
			return errors.Wrap(err, errPrefix)
		}

		_, err = pool.Mount()
		if err != nil {
			return errors.Wrap(err, errPrefix)
		}
	}

	// Update the storage drivers cache in api_1.0.go.
	storagePoolDriversCacheUpdate(s)
	return nil
}

func storagePoolDriversCacheUpdate(s *state.State) {
	// Get a list of all storage drivers currently in use
	// on this LXD instance. Only do this when we do not already have done
	// this once to avoid unnecessarily querying the db. All subsequent
	// updates of the cache will be done when we create or delete storage
	// pools in the db. Since this is a rare event, this cache
	// implementation is a classic frequent-read, rare-update case so
	// copy-on-write semantics without locking in the read case seems
	// appropriate. (Should be cheaper then querying the db all the time,
	// especially if we keep adding more storage drivers.)

	drivers, err := s.Cluster.StoragePoolsGetDrivers()
	if err != nil && err != db.ErrNoSuchObject {
		return
	}

	data := map[string]string{}

	// Get the driver info.
	info := storageDrivers.SupportedDrivers(s)
	for _, entry := range info {
		if shared.StringInSlice(entry.Name, drivers) {
			data[entry.Name] = entry.Version
		}
	}

	// Prepare the cache entries.
	backends := []string{}
	for k, v := range data {
		backends = append(backends, fmt.Sprintf("%s %s", k, v))
	}

	// Update the user agent.
	version.UserAgentStorageBackends(backends)

	storagePoolDriversCacheLock.Lock()
	storagePoolDriversCacheVal.Store(data)
	storagePoolDriversCacheLock.Unlock()

	return
}

// storageVolumeUmount unmounts a storage volume on a pool.
func storageVolumeUmount(state *state.State, poolName string, volumeName string, volumeType int) error {
	pool, err := storagePools.GetPoolByName(state, poolName)
	if err != nil {
		return err
	}

	_, err = pool.UnmountCustomVolume(volumeName, nil)
	if err != nil {
		return err
	}

	return nil
}

// storageRootFSApplyQuota applies a quota to an instance if it can, if it cannot then it will
// return false indicating that the quota needs to be stored in volatile to be applied on next boot.
func storageRootFSApplyQuota(state *state.State, inst instance.Instance, size string) error {
	pool, err := storagePools.GetPoolByInstance(state, inst)
	if err != nil {
		return err
	}

	err = pool.SetInstanceQuota(inst, size, nil)
	if err != nil {
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>package mips

import (
	"errors"
	"fmt"
)

var (
	RAWHazard       = errors.New("RAW Hazard")
	WARHazard       = errors.New("WAR Hazard")
	WAWHazard       = errors.New("WAW Hazard")
	Stall           = errors.New("Stall")
	FlushPipeline   = errors.New("Pipeline should flush")
	BranchResolving = errors.New("Branch is resolving")
)

type Instruction interface {
	SetCPU(cpu *CPU)
	OpCode() string
	SetOpCode(opcode string)
	String() string
	Label() Label
	SetLabel(label Label)
	SetText(text string)
	Destination() Operand
	SetDestination(o Operand)
	OperandA() Operand
	SetOperandA(o Operand)
	OperandB() Operand
	SetOperandB(o Operand)
	Flush()

	IF1() error
	IF2() error
	IF3() error
	ID() error
	EX() error
	MEM1() error
	MEM2() error
	MEM3() error
	WB() error
}

type OperandType int

const (
	operandTypeInvalid OperandType = iota
	operandTypeImmediate
	operandTypeOffset
	operandTypeNormal
	operandTypeLabel
)

type Operand struct {
	text     string
	Register Register
	Offset   int
	Type     OperandType
}

type Label string

type instruction struct {
	cpu         *CPU
	label       Label
	text        string
	opcode      string
	destination Operand
	operandA    Operand
	operandB    Operand
	destinationAcquired bool
}

func (op Operand) String() string {
	switch op.Type {
	case operandTypeImmediate:
		return fmt.Sprintf("#%d", op.Offset)
	case operandTypeNormal:
		return fmt.Sprintf("%s", op.Register)
	case operandTypeOffset:
		return fmt.Sprintf("%d(%s)", op.Offset, op.Register)
	case operandTypeLabel:
		return op.text
	}
	return "@unknown@"
}

func (op Operand) Value(cpu *CPU) (value Word, err error) {
	switch op.Type {
	case operandTypeImmediate:
		value = Word(op.Offset)
	case operandTypeNormal:
		if cpu.Registers.Locked(op.Register) {
			return value, RAWHazard
		}
		value = cpu.Registers.Get(op.Register)
	case operandTypeOffset:
		if cpu.Registers.Locked(op.Register) {
			return value, RAWHazard
		}
		value = cpu.Registers.Get(op.Register) + Word(op.Offset)
	case operandTypeLabel:
		value = Word(cpu.Labels[Label(op.text)])
	default:
		err = errors.New("Invalid operand type:")
	}
	return value, err
}

////////////////////////////////////////////////////////////////
// Instruction
////////////////////////////////////////////////////////////////

func NewInstruction(opcode string) (i Instruction, err error) {

	switch opcode {
	case "LD":
		i = new(LD)
	case "SD":
		i = new(SD)
	case "DADD":
		i = new(DADD)
	case "DADDI":
		i = new(DADDI)
	case "BNEZ":
		i = new(BNEZ)
	default:
		return nil, errors.New(fmt.Sprintf("Invalid opcode. %s", opcode))
	}
	i.SetOpCode(opcode)
	return
}

func (i instruction) String() string {
	result := fmt.Sprintf("%s %s %s", i.opcode, i.destination, i.operandA)
	if i.operandB.Type != operandTypeInvalid {
		result += fmt.Sprintf(" %s", i.operandB)
	}
	if i.label != "" {
		result += fmt.Sprintf(" (label: %s)", i.label)
	}
	return result
}

func (i instruction) OpCode() string {
	return i.opcode
}

func (i *instruction) SetOpCode(opcode string) {
	i.opcode = opcode
}

func (i *instruction) Label() Label {
	return i.label
}

func (i *instruction) SetLabel(label Label) {
	i.label = label
}

func (i *instruction) SetCPU(cpu *CPU) {
	i.cpu = cpu
}

func (i *instruction) SetText(text string) {
	i.text = text
}

func (i *instruction) Destination() Operand {
	return i.destination
}

func (i *instruction) SetDestination(d Operand) {
	i.destination = d
}

func (i *instruction) OperandA() Operand {
	return i.operandA
}

func (i *instruction) SetOperandA(o Operand) {
	i.operandA = o
}

func (i *instruction) OperandB() Operand {
	return i.operandB
}

func (i *instruction) SetOperandB(o Operand) {
	i.operandB = o
}

func (i *instruction) AcquireDestintion() {
	i.cpu.Registers.Acquire(i.destination.Register)
	i.destinationAcquired = true
}

func (i *instruction) ReleaseDestintion() {
	fmt.Println("releasing", i)
	if i.destinationAcquired {
		i.cpu.Registers.Release(i.destination.Register)
		i.destinationAcquired = false
	}
}

func (i *instruction) Flush() {
	i.ReleaseDestintion()
}

// Default blank stage implementations

func (i *instruction) IF1() error  { return nil }
func (i *instruction) IF2() error  { return nil }
func (i *instruction) IF3() error  { return nil }
func (i *instruction) ID() error   { return nil }
func (i *instruction) EX() error   { return nil }
func (i *instruction) MEM1() error { return nil }
func (i *instruction) MEM2() error { return nil }
func (i *instruction) MEM3() error { return nil }
func (i *instruction) WB() error   { return nil }

////////////////////////////////////////////////////////////////
// Actual Instruction Implementations
////////////////////////////////////////////////////////////////

type loadStoreInstruction struct {
	instruction
	address Word
	value   Word
}

////////////////////////////////////////////////////////////////
// LD
////////////////////////////////////////////////////////////////

type LD struct {
	loadStoreInstruction
}

func (i *LD) ID() error {
	val, err := i.operandA.Value(i.cpu)
	if err != nil {
		return err
	}
	i.address = val
	i.AcquireDestintion()

	return nil
}

func (i *LD) MEM3() error {
	//fmt.Println("MEM1 LD", i)
	i.value = i.cpu.Ram[i.address]

	// if forwarding is enabled writeback early
	// @todo for accuracy this shoudl be implemented with something akin to
	// an inter-pipeline register
	if i.cpu.ForwardingEnabled {
		return i.performWB()
	}
	return nil
}

func (i *LD) performWB() error {
	i.ReleaseDestintion()
	return i.cpu.Registers.Set(i.destination.Register, i.value)
}

func (i *LD) WB() error {
	// if forwarding is not enabled then we've already provided the register value
	if i.cpu.ForwardingEnabled == false {
		return i.performWB()
	}
	return nil
}

////////////////////////////////////////////////////////////////
// SD
////////////////////////////////////////////////////////////////

type SD struct {
	loadStoreInstruction
}

func (i *SD) ID() error {

	val, err := i.operandA.Value(i.cpu)
	if err != nil {
		return err
	}
	i.value = val

	val, err = i.destination.Value(i.cpu)
	if err != nil {
		return err
	}
	i.address = val

	return nil
}

func (i *SD) WB() error {
	//fmt.Println("WD SD", i)
	i.cpu.Ram[i.address] = i.value
	// @todo memory write errors, etc
	return nil
}

////////////////////////////////////////////////////////////////
// ALUInstruction
////////////////////////////////////////////////////////////////

type ALUInstruction struct {
	instruction
	t1, t2 Word // temporaries
	value  Word
}

func (i *ALUInstruction) performWB() error {
	i.ReleaseDestintion()
	return i.cpu.Registers.Set(i.destination.Register, i.value)
}

func (i *ALUInstruction) WB() error {
	if i.cpu.ForwardingEnabled == false {
		return i.performWB()
	}
	return nil
}

////////////////////////////////////////////////////////////////
// DADD
////////////////////////////////////////////////////////////////

type DADD struct {
	ALUInstruction
}

func (i *DADD) ID() (err error) {

	i.t1, err = i.operandA.Value(i.cpu)
	if err != nil {
		return err
	}

	i.t2, err = i.operandB.Value(i.cpu)
	if err != nil {
		return err
	}
	i.AcquireDestintion()
	return nil
}

func (i *DADD) EX() error {
	//fmt.Println("DADD EX", i)
	// @todo consider overflow?
	i.value = i.t1 + i.t2

	if i.cpu.ForwardingEnabled == true {
		return i.performWB()
	}
	return nil
}

////////////////////////////////////////////////////////////////
// DADDI
////////////////////////////////////////////////////////////////

type DADDI struct {
	ALUInstruction
}

func (i *DADDI) ID() (err error) {

	i.t1, err = i.operandA.Value(i.cpu)
	if err != nil {
		return err
	}

	i.t2, err = i.operandB.Value(i.cpu)
	if err != nil {
		return err
	}
	i.AcquireDestintion()
	return nil
}

func (i *DADDI) EX() error {
	//fmt.Println("DADDI EX", i)
	i.value = i.t1 + i.t2
	// @todo consider overflow
	if i.cpu.ForwardingEnabled == true {
		return i.performWB()
	}
	return nil
}

////////////////////////////////////////////////////////////////
// BNEZ
////////////////////////////////////////////////////////////////

type BNEZ struct {
	instruction
	target  Word
	nextPC int
}

func (i *BNEZ) IF1() (err error) {
	//fmt.Println("BNEZ IF1")
	i.nextPC = i.cpu.InstructionPointer
	switch i.cpu.BranchMode {
	case branchModeFlush:
		return BranchResolving
	case branchModePredictNotTaken:
		return nil
	case branchModePredictTaken:
		return nil
	}
	return nil
}

func (i *BNEZ) IF2() (err error) {
	i.target, err = i.operandA.Value(i.cpu)
	if err != nil {
		return err
	}
	switch i.cpu.BranchMode {
	case branchModeFlush:
		return BranchResolving
	case branchModePredictNotTaken:
		return nil
	case branchModePredictTaken:
		//fmt.Println("Predicting taken, flushing and setting PC")
		i.cpu.InstructionPointer = int(i.target)
		return FlushPipeline
	}
	return nil
}

func (i *BNEZ) IF3() (err error) {
	//fmt.Println("BNEZ IF3")
	if i.cpu.BranchMode == branchModeFlush {
		return BranchResolving
	}
	return nil
}

func (i *BNEZ) ID() (err error) {
	//fmt.Println("BNEZ ID")
	// note, "destination" is a misnomer, the second argument, operandA is the target
	val, err := i.destination.Value(i.cpu)
	if err != nil {
		//fmt.Println("BNEZ ", err)
		return err
	}
	//fmt.Println("BNEZ GO")
	branchTaken := val != 0
	switch i.cpu.BranchMode {
	case branchModeFlush:
		if branchTaken {
			//fmt.Println("setting pc!", i.target, val)
			i.cpu.InstructionPointer = int(i.target)
			return FlushPipeline
		} else {
			//fmt.Println("setting pc to start!", i.nextPC)
			i.cpu.InstructionPointer = i.nextPC
			return FlushPipeline
		}

	case branchModePredictNotTaken:
		if branchTaken {
			//fmt.Println("prediction incorrect, setting pc and flushing!", i.target)
			i.cpu.InstructionPointer = int(i.target)
			return FlushPipeline
		} else {
			//fmt.Println("prediction correct! continuing normally", i.target)
			return nil
		}

	case branchModePredictTaken:
		if branchTaken {
			//fmt.Println("prediction correct, continuing normally!")
			return nil
		} else {
			//fmt.Println("prediction incorrect, setting pc and flushing!", i.target)
			i.cpu.InstructionPointer = int(i.nextPC)
			return FlushPipeline
		}
	}

	return nil
}
<commit_msg>ssshhhh<commit_after>package mips

import (
	"errors"
	"fmt"
)

var (
	RAWHazard       = errors.New("RAW Hazard")
	WARHazard       = errors.New("WAR Hazard")
	WAWHazard       = errors.New("WAW Hazard")
	Stall           = errors.New("Stall")
	FlushPipeline   = errors.New("Pipeline should flush")
	BranchResolving = errors.New("Branch is resolving")
)

type Instruction interface {
	SetCPU(cpu *CPU)
	OpCode() string
	SetOpCode(opcode string)
	String() string
	Label() Label
	SetLabel(label Label)
	SetText(text string)
	Destination() Operand
	SetDestination(o Operand)
	OperandA() Operand
	SetOperandA(o Operand)
	OperandB() Operand
	SetOperandB(o Operand)
	Flush()

	IF1() error
	IF2() error
	IF3() error
	ID() error
	EX() error
	MEM1() error
	MEM2() error
	MEM3() error
	WB() error
}

type OperandType int

const (
	operandTypeInvalid OperandType = iota
	operandTypeImmediate
	operandTypeOffset
	operandTypeNormal
	operandTypeLabel
)

type Operand struct {
	text     string
	Register Register
	Offset   int
	Type     OperandType
}

type Label string

type instruction struct {
	cpu         *CPU
	label       Label
	text        string
	opcode      string
	destination Operand
	operandA    Operand
	operandB    Operand
	destinationAcquired bool
}

func (op Operand) String() string {
	switch op.Type {
	case operandTypeImmediate:
		return fmt.Sprintf("#%d", op.Offset)
	case operandTypeNormal:
		return fmt.Sprintf("%s", op.Register)
	case operandTypeOffset:
		return fmt.Sprintf("%d(%s)", op.Offset, op.Register)
	case operandTypeLabel:
		return op.text
	}
	return "@unknown@"
}

func (op Operand) Value(cpu *CPU) (value Word, err error) {
	switch op.Type {
	case operandTypeImmediate:
		value = Word(op.Offset)
	case operandTypeNormal:
		if cpu.Registers.Locked(op.Register) {
			return value, RAWHazard
		}
		value = cpu.Registers.Get(op.Register)
	case operandTypeOffset:
		if cpu.Registers.Locked(op.Register) {
			return value, RAWHazard
		}
		value = cpu.Registers.Get(op.Register) + Word(op.Offset)
	case operandTypeLabel:
		value = Word(cpu.Labels[Label(op.text)])
	default:
		err = errors.New("Invalid operand type:")
	}
	return value, err
}

////////////////////////////////////////////////////////////////
// Instruction
////////////////////////////////////////////////////////////////

func NewInstruction(opcode string) (i Instruction, err error) {

	switch opcode {
	case "LD":
		i = new(LD)
	case "SD":
		i = new(SD)
	case "DADD":
		i = new(DADD)
	case "DADDI":
		i = new(DADDI)
	case "BNEZ":
		i = new(BNEZ)
	default:
		return nil, errors.New(fmt.Sprintf("Invalid opcode. %s", opcode))
	}
	i.SetOpCode(opcode)
	return
}

func (i instruction) String() string {
	result := fmt.Sprintf("%s %s %s", i.opcode, i.destination, i.operandA)
	if i.operandB.Type != operandTypeInvalid {
		result += fmt.Sprintf(" %s", i.operandB)
	}
	if i.label != "" {
		result += fmt.Sprintf(" (label: %s)", i.label)
	}
	return result
}

func (i instruction) OpCode() string {
	return i.opcode
}

func (i *instruction) SetOpCode(opcode string) {
	i.opcode = opcode
}

func (i *instruction) Label() Label {
	return i.label
}

func (i *instruction) SetLabel(label Label) {
	i.label = label
}

func (i *instruction) SetCPU(cpu *CPU) {
	i.cpu = cpu
}

func (i *instruction) SetText(text string) {
	i.text = text
}

func (i *instruction) Destination() Operand {
	return i.destination
}

func (i *instruction) SetDestination(d Operand) {
	i.destination = d
}

func (i *instruction) OperandA() Operand {
	return i.operandA
}

func (i *instruction) SetOperandA(o Operand) {
	i.operandA = o
}

func (i *instruction) OperandB() Operand {
	return i.operandB
}

func (i *instruction) SetOperandB(o Operand) {
	i.operandB = o
}

func (i *instruction) AcquireDestintion() {
	i.cpu.Registers.Acquire(i.destination.Register)
	i.destinationAcquired = true
}

func (i *instruction) ReleaseDestintion() {
	if i.destinationAcquired {
		i.cpu.Registers.Release(i.destination.Register)
		i.destinationAcquired = false
	}
}

func (i *instruction) Flush() {
	i.ReleaseDestintion()
}

// Default blank stage implementations

func (i *instruction) IF1() error  { return nil }
func (i *instruction) IF2() error  { return nil }
func (i *instruction) IF3() error  { return nil }
func (i *instruction) ID() error   { return nil }
func (i *instruction) EX() error   { return nil }
func (i *instruction) MEM1() error { return nil }
func (i *instruction) MEM2() error { return nil }
func (i *instruction) MEM3() error { return nil }
func (i *instruction) WB() error   { return nil }

////////////////////////////////////////////////////////////////
// Actual Instruction Implementations
////////////////////////////////////////////////////////////////

type loadStoreInstruction struct {
	instruction
	address Word
	value   Word
}

////////////////////////////////////////////////////////////////
// LD
////////////////////////////////////////////////////////////////

type LD struct {
	loadStoreInstruction
}

func (i *LD) ID() error {
	val, err := i.operandA.Value(i.cpu)
	if err != nil {
		return err
	}
	i.address = val
	i.AcquireDestintion()

	return nil
}

func (i *LD) MEM3() error {
	//fmt.Println("MEM1 LD", i)
	i.value = i.cpu.Ram[i.address]

	// if forwarding is enabled writeback early
	// @todo for accuracy this shoudl be implemented with something akin to
	// an inter-pipeline register
	if i.cpu.ForwardingEnabled {
		return i.performWB()
	}
	return nil
}

func (i *LD) performWB() error {
	i.ReleaseDestintion()
	return i.cpu.Registers.Set(i.destination.Register, i.value)
}

func (i *LD) WB() error {
	// if forwarding is not enabled then we've already provided the register value
	if i.cpu.ForwardingEnabled == false {
		return i.performWB()
	}
	return nil
}

////////////////////////////////////////////////////////////////
// SD
////////////////////////////////////////////////////////////////

type SD struct {
	loadStoreInstruction
}

func (i *SD) ID() error {

	val, err := i.operandA.Value(i.cpu)
	if err != nil {
		return err
	}
	i.value = val

	val, err = i.destination.Value(i.cpu)
	if err != nil {
		return err
	}
	i.address = val

	return nil
}

func (i *SD) WB() error {
	//fmt.Println("WD SD", i)
	i.cpu.Ram[i.address] = i.value
	// @todo memory write errors, etc
	return nil
}

////////////////////////////////////////////////////////////////
// ALUInstruction
////////////////////////////////////////////////////////////////

type ALUInstruction struct {
	instruction
	t1, t2 Word // temporaries
	value  Word
}

func (i *ALUInstruction) performWB() error {
	i.ReleaseDestintion()
	return i.cpu.Registers.Set(i.destination.Register, i.value)
}

func (i *ALUInstruction) WB() error {
	if i.cpu.ForwardingEnabled == false {
		return i.performWB()
	}
	return nil
}

////////////////////////////////////////////////////////////////
// DADD
////////////////////////////////////////////////////////////////

type DADD struct {
	ALUInstruction
}

func (i *DADD) ID() (err error) {

	i.t1, err = i.operandA.Value(i.cpu)
	if err != nil {
		return err
	}

	i.t2, err = i.operandB.Value(i.cpu)
	if err != nil {
		return err
	}
	i.AcquireDestintion()
	return nil
}

func (i *DADD) EX() error {
	//fmt.Println("DADD EX", i)
	// @todo consider overflow?
	i.value = i.t1 + i.t2

	if i.cpu.ForwardingEnabled == true {
		return i.performWB()
	}
	return nil
}

////////////////////////////////////////////////////////////////
// DADDI
////////////////////////////////////////////////////////////////

type DADDI struct {
	ALUInstruction
}

func (i *DADDI) ID() (err error) {

	i.t1, err = i.operandA.Value(i.cpu)
	if err != nil {
		return err
	}

	i.t2, err = i.operandB.Value(i.cpu)
	if err != nil {
		return err
	}
	i.AcquireDestintion()
	return nil
}

func (i *DADDI) EX() error {
	//fmt.Println("DADDI EX", i)
	i.value = i.t1 + i.t2
	// @todo consider overflow
	if i.cpu.ForwardingEnabled == true {
		return i.performWB()
	}
	return nil
}

////////////////////////////////////////////////////////////////
// BNEZ
////////////////////////////////////////////////////////////////

type BNEZ struct {
	instruction
	target  Word
	nextPC int
}

func (i *BNEZ) IF1() (err error) {
	//fmt.Println("BNEZ IF1")
	i.nextPC = i.cpu.InstructionPointer
	switch i.cpu.BranchMode {
	case branchModeFlush:
		return BranchResolving
	case branchModePredictNotTaken:
		return nil
	case branchModePredictTaken:
		return nil
	}
	return nil
}

func (i *BNEZ) IF2() (err error) {
	i.target, err = i.operandA.Value(i.cpu)
	if err != nil {
		return err
	}
	switch i.cpu.BranchMode {
	case branchModeFlush:
		return BranchResolving
	case branchModePredictNotTaken:
		return nil
	case branchModePredictTaken:
		//fmt.Println("Predicting taken, flushing and setting PC")
		i.cpu.InstructionPointer = int(i.target)
		return FlushPipeline
	}
	return nil
}

func (i *BNEZ) IF3() (err error) {
	//fmt.Println("BNEZ IF3")
	if i.cpu.BranchMode == branchModeFlush {
		return BranchResolving
	}
	return nil
}

func (i *BNEZ) ID() (err error) {
	//fmt.Println("BNEZ ID")
	// note, "destination" is a misnomer, the second argument, operandA is the target
	val, err := i.destination.Value(i.cpu)
	if err != nil {
		//fmt.Println("BNEZ ", err)
		return err
	}
	//fmt.Println("BNEZ GO")
	branchTaken := val != 0
	switch i.cpu.BranchMode {
	case branchModeFlush:
		if branchTaken {
			//fmt.Println("setting pc!", i.target, val)
			i.cpu.InstructionPointer = int(i.target)
			return FlushPipeline
		} else {
			//fmt.Println("setting pc to start!", i.nextPC)
			i.cpu.InstructionPointer = i.nextPC
			return FlushPipeline
		}

	case branchModePredictNotTaken:
		if branchTaken {
			//fmt.Println("prediction incorrect, setting pc and flushing!", i.target)
			i.cpu.InstructionPointer = int(i.target)
			return FlushPipeline
		} else {
			//fmt.Println("prediction correct! continuing normally", i.target)
			return nil
		}

	case branchModePredictTaken:
		if branchTaken {
			//fmt.Println("prediction correct, continuing normally!")
			return nil
		} else {
			//fmt.Println("prediction incorrect, setting pc and flushing!", i.target)
			i.cpu.InstructionPointer = int(i.nextPC)
			return FlushPipeline
		}
	}

	return nil
}
<|endoftext|>


<commit_before>// +build ignore

package main

import (
	"fmt"

	"github.com/mattn/go-tty"
	//"os"
	//"os/signal"
)

func main() {
	tty, err := tty.Open()
	defer tty.Close()

	fmt.Print("Password: ")
	s, err := tty.ReadPassword()
	if err != nil {
		println("canceled")
		return
	}
	fmt.Println(s)
}
<commit_msg>input username/password<commit_after>// +build ignore

package main

import (
	"encoding/base64"
	"fmt"

	"github.com/mattn/go-tty"
)

func main() {
	tty, err := tty.Open()
	defer tty.Close()

	fmt.Print("Username: ")
	username, err := tty.ReadString()
	if err != nil {
		println("canceled")
		return
	}
	fmt.Print("Password: ")
	password, err := tty.ReadPassword()
	if err != nil {
		println("canceled")
		return
	}
	fmt.Println(base64.StdEncoding.EncodeToString([]byte(username + ":" + password)))
}
<|endoftext|>


<commit_before>package echo

import (
	"bytes"
	"encoding/xml"
	"io"
	"net/http"
	"os"
	"path/filepath"
	"time"
	"unicode"

	"github.com/webx-top/echo/encoding/json"
	"github.com/webx-top/echo/engine"
)

// Response returns *Response.
func (c *xContext) Response() engine.Response {
	return c.response
}

// Render renders a template with data and sends a text/html response with status
// code. Templates can be registered using `Echo.SetRenderer()`.
func (c *xContext) Render(name string, data interface{}, codes ...int) (err error) {
	if c.auto {
		format := c.Format()
		if render, ok := c.echo.formatRenderers[format]; ok && render != nil {
			switch v := data.(type) {
			case Data: //Skip
			case error:
				c.dataEngine.SetError(v)
			case nil:
				if c.dataEngine.GetData() == nil {
					c.dataEngine.SetData(c.Stored(), c.dataEngine.GetCode().Int())
				}
			default:
				c.dataEngine.SetData(data, c.dataEngine.GetCode().Int())
			}
			if c.echo.renderDataWrapper != nil {
				data = c.echo.renderDataWrapper(c, data)
			}
			return render(c, data)
		}
	}
	c.dataEngine.SetTmplFuncs()
	if data == nil {
		data = c.dataEngine.GetData()
	}
	if c.echo.renderDataWrapper != nil {
		data = c.echo.renderDataWrapper(c, data)
	}
	b, err := c.Fetch(name, data)
	if err != nil {
		return
	}
	b = bytes.TrimLeftFunc(b, unicode.IsSpace)
	c.response.Header().Set(HeaderContentType, MIMETextHTMLCharsetUTF8)
	err = c.Blob(b, codes...)
	return
}

// HTML sends an HTTP response with status code.
func (c *xContext) HTML(html string, codes ...int) (err error) {
	c.response.Header().Set(HeaderContentType, MIMETextHTMLCharsetUTF8)
	err = c.Blob([]byte(html), codes...)
	return
}

// String sends a string response with status code.
func (c *xContext) String(s string, codes ...int) (err error) {
	c.response.Header().Set(HeaderContentType, MIMETextPlainCharsetUTF8)
	err = c.Blob([]byte(s), codes...)
	return
}

func (c *xContext) Blob(b []byte, codes ...int) (err error) {
	if len(codes) > 0 {
		c.code = codes[0]
	}
	if c.code == 0 {
		c.code = http.StatusOK
	}
	err = c.preResponse()
	if err != nil {
		return
	}
	c.response.WriteHeader(c.code)
	_, err = c.response.Write(b)
	return
}

// JSON sends a JSON response with status code.
func (c *xContext) JSON(i interface{}, codes ...int) (err error) {
	var b []byte
	if c.echo.Debug() {
		b, err = json.MarshalIndent(i, "", "  ")
	} else {
		b, err = json.Marshal(i)
	}
	if err != nil {
		return err
	}
	return c.JSONBlob(b, codes...)
}

// JSONBlob sends a JSON blob response with status code.
func (c *xContext) JSONBlob(b []byte, codes ...int) (err error) {
	c.response.Header().Set(HeaderContentType, MIMEApplicationJSONCharsetUTF8)
	err = c.Blob(b, codes...)
	return
}

// JSONP sends a JSONP response with status code. It uses `callback` to construct
// the JSONP payload.
func (c *xContext) JSONP(callback string, i interface{}, codes ...int) (err error) {
	b, err := json.Marshal(i)
	if err != nil {
		return err
	}
	c.response.Header().Set(HeaderContentType, MIMEApplicationJavaScriptCharsetUTF8)
	b = []byte(callback + "(" + string(b) + ");")
	err = c.Blob(b, codes...)
	return
}

// XML sends an XML response with status code.
func (c *xContext) XML(i interface{}, codes ...int) (err error) {
	var b []byte
	if c.echo.Debug() {
		b, err = xml.MarshalIndent(i, "", "  ")
	} else {
		b, err = xml.Marshal(i)
	}
	if err != nil {
		return err
	}
	return c.XMLBlob(b, codes...)
}

// XMLBlob sends a XML blob response with status code.
func (c *xContext) XMLBlob(b []byte, codes ...int) (err error) {
	c.response.Header().Set(HeaderContentType, MIMEApplicationXMLCharsetUTF8)
	b = []byte(xml.Header + string(b))
	err = c.Blob(b, codes...)
	return
}

func (c *xContext) Stream(step func(w io.Writer) bool) error {
	return c.response.Stream(step)
}

func (c *xContext) SSEvent(event string, data chan interface{}) (err error) {
	hdr := c.response.Header()
	hdr.Set(HeaderContentType, MIMEEventStream)
	hdr.Set(`Cache-Control`, `no-cache`)
	hdr.Set(`Connection`, `keep-alive`)
	hdr.Set(`Transfer-Encoding`, `chunked`)
	err = c.Stream(func(w io.Writer) bool {
		recv, ok := <-data
		if !ok {
			return ok
		}
		b, _err := c.Fetch(event, recv)
		if _err != nil {
			err = _err
			return false
		}
		//c.Logger().Debugf(`SSEvent: %s`, b)
		_, _err = w.Write(b)
		if _err != nil {
			err = _err
			return false
		}
		return true
	})
	return
}

func (c *xContext) Attachment(r io.Reader, name string, modtime time.Time, inline ...bool) (err error) {
	var typ string
	if len(inline) > 0 && inline[0] {
		typ = `inline`
	} else {
		typ = `attachment`
	}
	c.response.Header().Set(HeaderContentType, ContentTypeByExtension(name))
	encodedName := URLEncode(name, true)
	c.response.Header().Set(HeaderContentDisposition, typ+"; filename="+encodedName+"; filename*=utf-8''"+encodedName)
	return c.ServeContent(r, name, modtime)
}

func (c *xContext) File(file string, fs ...http.FileSystem) (err error) {
	var f http.File
	customFS := len(fs) > 0 && fs[0] != nil
	if customFS {
		f, err = fs[0].Open(file)
	} else {
		f, err = os.Open(file)
	}
	if err != nil {
		return ErrNotFound
	}
	defer func() {
		if f != nil {
			f.Close()
		}
	}()
	fi, err := f.Stat()
	if err != nil {
		return err
	}
	if fi.IsDir() {
		f.Close()
		file = filepath.Join(file, "index.html")
		if customFS {
			f, err = fs[0].Open(file)
		} else {
			f, err = os.Open(file)
		}
		if err != nil {
			return ErrNotFound
		}
		fi, err = f.Stat()
		if err != nil {
			return err
		}
	}
	c.Response().ServeContent(f, fi.Name(), fi.ModTime())
	return nil
}

func (c *xContext) ServeContent(content io.Reader, name string, modtime time.Time) error {
	if readSeeker, ok := content.(io.ReadSeeker); ok {
		c.Response().ServeContent(readSeeker, name, modtime)
		return nil
	}
	return c.ServeCallbackContent(func(_ Context) (io.Reader, error) {
		return content, nil
	}, name, modtime)
}

func (c *xContext) ServeCallbackContent(callback func(Context) (io.Reader, error), name string, modtime time.Time) error {
	rq := c.Request()
	rs := c.Response()

	if t, err := time.Parse(http.TimeFormat, rq.Header().Get(HeaderIfModifiedSince)); err == nil && modtime.Before(t.Add(1*time.Second)) {
		rs.Header().Del(HeaderContentType)
		rs.Header().Del(HeaderContentLength)
		return c.NoContent(http.StatusNotModified)
	}
	content, err := callback(c)
	if err != nil {
		return err
	}
	if readSeeker, ok := content.(io.ReadSeeker); ok {
		c.Response().ServeContent(readSeeker, name, modtime)
		return nil
	}
	rs.Header().Set(HeaderContentType, ContentTypeByExtension(name))
	rs.Header().Set(HeaderLastModified, modtime.UTC().Format(http.TimeFormat))
	rs.WriteHeader(http.StatusOK)
	rs.KeepBody(false)
	_, err = io.Copy(rs, content)
	return err
}

// NoContent sends a response with no body and a status code.
func (c *xContext) NoContent(codes ...int) error {
	if len(codes) > 0 {
		c.code = codes[0]
	}
	if c.code == 0 {
		c.code = http.StatusOK
	}
	c.response.WriteHeader(c.code)
	return nil
}

// Redirect redirects the request with status code.
func (c *xContext) Redirect(url string, codes ...int) error {
	code := http.StatusFound
	if len(codes) > 0 {
		code = codes[0]
	}
	if code < http.StatusMultipleChoices || code > http.StatusTemporaryRedirect {
		return ErrInvalidRedirectCode
	}
	err := c.preResponse()
	if err != nil {
		return err
	}
	format := c.Format()
	if format != `html` && c.auto {
		if render, ok := c.echo.formatRenderers[format]; ok && render != nil {
			if c.dataEngine.GetData() == nil {
				c.dataEngine.SetData(c.Stored(), c.dataEngine.GetCode().Int())
			}
			c.dataEngine.SetURL(url)
			return render(c, c.dataEngine.GetData())
		}
	}
	c.response.Redirect(url, code)
	return nil
}
<commit_msg>update<commit_after>package echo

import (
	"bytes"
	"encoding/xml"
	"io"
	"net/http"
	"os"
	"path/filepath"
	"time"
	"unicode"

	"github.com/webx-top/echo/encoding/json"
	"github.com/webx-top/echo/engine"
)

// Response returns *Response.
func (c *xContext) Response() engine.Response {
	return c.response
}

// Render renders a template with data and sends a text/html response with status
// code. Templates can be registered using `Echo.SetRenderer()`.
func (c *xContext) Render(name string, data interface{}, codes ...int) (err error) {
	if c.auto {
		format := c.Format()
		if render, ok := c.echo.formatRenderers[format]; ok && render != nil {
			switch v := data.(type) {
			case Data: //Skip
			case error:
				c.dataEngine.SetError(v)
			case nil:
				if c.dataEngine.GetData() == nil {
					c.dataEngine.SetData(c.Stored(), c.dataEngine.GetCode().Int())
				}
			default:
				c.dataEngine.SetData(data, c.dataEngine.GetCode().Int())
			}
			if c.renderDataWrapper != nil {
				data = c.renderDataWrapper(c, data)
			}
			return render(c, data)
		}
	}
	c.dataEngine.SetTmplFuncs()
	if data == nil {
		data = c.dataEngine.GetData()
	}
	if c.renderDataWrapper != nil {
		data = c.renderDataWrapper(c, data)
	}
	b, err := c.Fetch(name, data)
	if err != nil {
		return
	}
	b = bytes.TrimLeftFunc(b, unicode.IsSpace)
	c.response.Header().Set(HeaderContentType, MIMETextHTMLCharsetUTF8)
	err = c.Blob(b, codes...)
	return
}

// HTML sends an HTTP response with status code.
func (c *xContext) HTML(html string, codes ...int) (err error) {
	c.response.Header().Set(HeaderContentType, MIMETextHTMLCharsetUTF8)
	err = c.Blob([]byte(html), codes...)
	return
}

// String sends a string response with status code.
func (c *xContext) String(s string, codes ...int) (err error) {
	c.response.Header().Set(HeaderContentType, MIMETextPlainCharsetUTF8)
	err = c.Blob([]byte(s), codes...)
	return
}

func (c *xContext) Blob(b []byte, codes ...int) (err error) {
	if len(codes) > 0 {
		c.code = codes[0]
	}
	if c.code == 0 {
		c.code = http.StatusOK
	}
	err = c.preResponse()
	if err != nil {
		return
	}
	c.response.WriteHeader(c.code)
	_, err = c.response.Write(b)
	return
}

// JSON sends a JSON response with status code.
func (c *xContext) JSON(i interface{}, codes ...int) (err error) {
	var b []byte
	if c.echo.Debug() {
		b, err = json.MarshalIndent(i, "", "  ")
	} else {
		b, err = json.Marshal(i)
	}
	if err != nil {
		return err
	}
	return c.JSONBlob(b, codes...)
}

// JSONBlob sends a JSON blob response with status code.
func (c *xContext) JSONBlob(b []byte, codes ...int) (err error) {
	c.response.Header().Set(HeaderContentType, MIMEApplicationJSONCharsetUTF8)
	err = c.Blob(b, codes...)
	return
}

// JSONP sends a JSONP response with status code. It uses `callback` to construct
// the JSONP payload.
func (c *xContext) JSONP(callback string, i interface{}, codes ...int) (err error) {
	b, err := json.Marshal(i)
	if err != nil {
		return err
	}
	c.response.Header().Set(HeaderContentType, MIMEApplicationJavaScriptCharsetUTF8)
	b = []byte(callback + "(" + string(b) + ");")
	err = c.Blob(b, codes...)
	return
}

// XML sends an XML response with status code.
func (c *xContext) XML(i interface{}, codes ...int) (err error) {
	var b []byte
	if c.echo.Debug() {
		b, err = xml.MarshalIndent(i, "", "  ")
	} else {
		b, err = xml.Marshal(i)
	}
	if err != nil {
		return err
	}
	return c.XMLBlob(b, codes...)
}

// XMLBlob sends a XML blob response with status code.
func (c *xContext) XMLBlob(b []byte, codes ...int) (err error) {
	c.response.Header().Set(HeaderContentType, MIMEApplicationXMLCharsetUTF8)
	b = []byte(xml.Header + string(b))
	err = c.Blob(b, codes...)
	return
}

func (c *xContext) Stream(step func(w io.Writer) bool) error {
	return c.response.Stream(step)
}

func (c *xContext) SSEvent(event string, data chan interface{}) (err error) {
	hdr := c.response.Header()
	hdr.Set(HeaderContentType, MIMEEventStream)
	hdr.Set(`Cache-Control`, `no-cache`)
	hdr.Set(`Connection`, `keep-alive`)
	hdr.Set(`Transfer-Encoding`, `chunked`)
	err = c.Stream(func(w io.Writer) bool {
		recv, ok := <-data
		if !ok {
			return ok
		}
		b, _err := c.Fetch(event, recv)
		if _err != nil {
			err = _err
			return false
		}
		//c.Logger().Debugf(`SSEvent: %s`, b)
		_, _err = w.Write(b)
		if _err != nil {
			err = _err
			return false
		}
		return true
	})
	return
}

func (c *xContext) Attachment(r io.Reader, name string, modtime time.Time, inline ...bool) (err error) {
	var typ string
	if len(inline) > 0 && inline[0] {
		typ = `inline`
	} else {
		typ = `attachment`
	}
	c.response.Header().Set(HeaderContentType, ContentTypeByExtension(name))
	encodedName := URLEncode(name, true)
	c.response.Header().Set(HeaderContentDisposition, typ+"; filename="+encodedName+"; filename*=utf-8''"+encodedName)
	return c.ServeContent(r, name, modtime)
}

func (c *xContext) File(file string, fs ...http.FileSystem) (err error) {
	var f http.File
	customFS := len(fs) > 0 && fs[0] != nil
	if customFS {
		f, err = fs[0].Open(file)
	} else {
		f, err = os.Open(file)
	}
	if err != nil {
		return ErrNotFound
	}
	defer func() {
		if f != nil {
			f.Close()
		}
	}()
	fi, err := f.Stat()
	if err != nil {
		return err
	}
	if fi.IsDir() {
		f.Close()
		file = filepath.Join(file, "index.html")
		if customFS {
			f, err = fs[0].Open(file)
		} else {
			f, err = os.Open(file)
		}
		if err != nil {
			return ErrNotFound
		}
		fi, err = f.Stat()
		if err != nil {
			return err
		}
	}
	c.Response().ServeContent(f, fi.Name(), fi.ModTime())
	return nil
}

func (c *xContext) ServeContent(content io.Reader, name string, modtime time.Time) error {
	if readSeeker, ok := content.(io.ReadSeeker); ok {
		c.Response().ServeContent(readSeeker, name, modtime)
		return nil
	}
	return c.ServeCallbackContent(func(_ Context) (io.Reader, error) {
		return content, nil
	}, name, modtime)
}

func (c *xContext) ServeCallbackContent(callback func(Context) (io.Reader, error), name string, modtime time.Time) error {
	rq := c.Request()
	rs := c.Response()

	if t, err := time.Parse(http.TimeFormat, rq.Header().Get(HeaderIfModifiedSince)); err == nil && modtime.Before(t.Add(1*time.Second)) {
		rs.Header().Del(HeaderContentType)
		rs.Header().Del(HeaderContentLength)
		return c.NoContent(http.StatusNotModified)
	}
	content, err := callback(c)
	if err != nil {
		return err
	}
	if readSeeker, ok := content.(io.ReadSeeker); ok {
		c.Response().ServeContent(readSeeker, name, modtime)
		return nil
	}
	rs.Header().Set(HeaderContentType, ContentTypeByExtension(name))
	rs.Header().Set(HeaderLastModified, modtime.UTC().Format(http.TimeFormat))
	rs.WriteHeader(http.StatusOK)
	rs.KeepBody(false)
	_, err = io.Copy(rs, content)
	return err
}

// NoContent sends a response with no body and a status code.
func (c *xContext) NoContent(codes ...int) error {
	if len(codes) > 0 {
		c.code = codes[0]
	}
	if c.code == 0 {
		c.code = http.StatusOK
	}
	c.response.WriteHeader(c.code)
	return nil
}

// Redirect redirects the request with status code.
func (c *xContext) Redirect(url string, codes ...int) error {
	code := http.StatusFound
	if len(codes) > 0 {
		code = codes[0]
	}
	if code < http.StatusMultipleChoices || code > http.StatusTemporaryRedirect {
		return ErrInvalidRedirectCode
	}
	err := c.preResponse()
	if err != nil {
		return err
	}
	format := c.Format()
	if format != `html` && c.auto {
		if render, ok := c.echo.formatRenderers[format]; ok && render != nil {
			if c.dataEngine.GetData() == nil {
				c.dataEngine.SetData(c.Stored(), c.dataEngine.GetCode().Int())
			}
			c.dataEngine.SetURL(url)
			return render(c, c.dataEngine.GetData())
		}
	}
	c.response.Redirect(url, code)
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"sync"

	"github.com/CrowdSurge/banner"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/spf13/cobra"
)

// job var used as a central point for command data
var job = struct {
	cfgFile      string
	tplFile      string
	profile      string
	tplFiles     []string
	stacks       map[string]string
	terminateAll bool
	version      bool
	request      string
	debug        bool
	funcName     string
}{}

// Wait Group for handling goroutines
var wg sync.WaitGroup

// root command (calls all other commands)
var rootCmd = &cobra.Command{
	Use:   "qaz",
	Short: fmt.Sprintf("%s\n--> Shut up & deploy my templates...!", colorString(banner.PrintS("qaz"), "magenta")),
	Run: func(cmd *cobra.Command, args []string) {

		if job.version {
			fmt.Printf("qaz - Version %s"+"\n", version)
			return
		}

		cmd.Help()
	},
}

var initCmd = &cobra.Command{
	Use:   "init [target directory]",
	Short: "Creates a basic qaz project",
	Run: func(cmd *cobra.Command, args []string) {

		// Print Banner
		banner.Print("qaz")
		fmt.Printf("\n--\n")

		var target string
		switch len(args) {
		case 0:
			target, _ = os.Getwd()
		default:
			target = args[0]
		}

		// Get Project & AWS Region
		project = getInput("-> Enter your Project name", "MyqazProject")
		region = getInput("-> Enter AWS Region", "eu-west-1")

		// set target paths
		c := filepath.Join(target, "config.yml")
		t := filepath.Join(target, "templates")
		f := filepath.Join(target, "files")

		// Check if config file exists
		var overwrite string
		if _, err := os.Stat(c); err == nil {
			overwrite = getInput(
				fmt.Sprintf("%s [%s] already exist, Do you want to %s?(Y/N) ", colorString("->", "yellow"), c, colorString("Overwrite", "red")),
				"N",
			)

			if overwrite == "Y" {
				fmt.Println(fmt.Sprintf("%s Overwriting: [%s]..", colorString("->", "yellow"), c))
			}
		}

		// Create template file
		if overwrite != "N" {
			if err := ioutil.WriteFile(c, configTemplate(project, region), 0644); err != nil {
				fmt.Printf("%s Error, unable to create config.yml file: %s"+"\n", err, colorString("->", "red"))
				return
			}
		}

		// Create template folder
		for _, dir := range []string{t, f} {
			if err := os.Mkdir(dir, os.ModePerm); err != nil {
				fmt.Printf("%s [%s] folder not created: %s"+"\n--\n", colorString("->", "yellow"), dir, err)
				return
			}
		}

		fmt.Println("--")
	},
}

var generateCmd = &cobra.Command{
	Use:   "generate",
	Short: "Generates template from configuration values",
	Run: func(cmd *cobra.Command, args []string) {

		job.request = "generate"

		s, source, err := getSource(job.tplFile)
		if err != nil {
			handleError(err)
			return
		}

		job.tplFile = source
		err = configReader(job.cfgFile)
		if err != nil {
			handleError(err)
			return
		}

		name := fmt.Sprintf("%s-%s", project, s)
		Log(fmt.Sprintln("Generating a template for ", name), "debug")

		tpl, err := genTimeParser(job.tplFile)
		if err != nil {
			handleError(err)
			return
		}
		fmt.Println(tpl)
	},
}

var deployCmd = &cobra.Command{
	Use:   "deploy",
	Short: "Deploys stack(s) to AWS",
	Example: strings.Join([]string{
		"qaz deploy -c path/to/config -t path/to/template",
		"qaz deploy -c path/to/config -t stack::s3//bucket/key",
		"qaz deploy -c path/to/config -t stack::http://someurl",
	}, "\n"),
	Run: func(cmd *cobra.Command, args []string) {

		job.request = "deploy"

		job.stacks = make(map[string]string)

		sourceCopy := job.tplFiles

		// creating empty template list for re-population later
		job.tplFiles = []string{}

		for _, src := range sourceCopy {
			if strings.Contains(src, `*`) {
				glob, _ := filepath.Glob(src)

				for _, f := range glob {
					job.tplFiles = append(job.tplFiles, f)
				}
				continue
			}

			job.tplFiles = append(job.tplFiles, src)
		}

		for _, f := range job.tplFiles {
			s, source, err := getSource(f)
			if err != nil {
				handleError(err)
				return
			}
			job.stacks[s] = source
		}

		err := configReader(job.cfgFile)
		if err != nil {
			handleError(err)
			return
		}

		for s, f := range job.stacks {
			if v, err := genTimeParser(f); err != nil {
				handleError(err)
			} else {
				stacks[s].template = v
			}
		}

		// Deploy Stacks
		DeployHandler()

	},
}

var updateCmd = &cobra.Command{
	Use:   "update",
	Short: "Updates a given stack",
	Example: strings.Join([]string{
		"qaz update -c path/to/config -t stack::path/to/template",
		"qaz update -c path/to/config -t stack::s3//bucket/key",
		"qaz update -c path/to/config -t stack::http://someurl",
	}, "\n"),
	Run: func(cmd *cobra.Command, args []string) {

		job.request = "update"

		s, source, err := getSource(job.tplFile)
		if err != nil {
			handleError(err)
			return
		}

		fmt.Println(source)

		job.tplFile = source

		err = configReader(job.cfgFile)
		if err != nil {
			handleError(err)
			return
		}

		v, err := genTimeParser(job.tplFile)
		if err != nil {
			handleError(err)
			return
		}

		stacks[s].template = v

		// Update stack
		sess, err := awsSession()
		if err != nil {
			handleError(err)
			return
		}
		stacks[s].update(sess)

	},
}

var terminateCmd = &cobra.Command{
	Use:   "terminate [stacks]",
	Short: "Terminates stacks",
	Run: func(cmd *cobra.Command, args []string) {

		job.request = "terminate"

		if !job.terminateAll {
			job.stacks = make(map[string]string)
			for _, stk := range args {
				job.stacks[stk] = ""
			}

			if len(job.stacks) == 0 {
				Log("No stack specified for termination", "warn")
				return
			}
		}

		err := configReader(job.cfgFile)
		if err != nil {
			handleError(err)
			return
		}

		// Terminate Stacks
		TerminateHandler()
	},
}

var statusCmd = &cobra.Command{
	Use:   "status",
	Short: "Prints status of deployed/un-deployed stacks",
	Run: func(cmd *cobra.Command, args []string) {

		job.request = "status"

		err := configReader(job.cfgFile)
		if err != nil {
			handleError(err)
			return
		}

		sess, err := awsSession()
		if err != nil {
			handleError(err)
			return
		}

		for _, v := range stacks {
			wg.Add(1)
			go func(s *stack) {
				if err := s.status(sess); err != nil {
					handleError(err)
				}
				wg.Done()
			}(v)

		}
		wg.Wait()
	},
}

var outputsCmd = &cobra.Command{
	Use:     "outputs [stack]",
	Short:   "Prints stack outputs",
	Example: "qaz outputs vpc subnets --config path/to/config",
	Run: func(cmd *cobra.Command, args []string) {

		job.request = "outputs"

		if len(args) < 1 {
			fmt.Println("Please specify stack(s) to check, For details try --> qaz outputs --help")
			return
		}

		err := configReader(job.cfgFile)
		if err != nil {
			handleError(err)
			return
		}

		sess, err := awsSession()
		if err != nil {
			handleError(err)
			return
		}

		for _, s := range args {
			wg.Add(1)
			go func(s string) {
				outputs, err := StackOutputs(stacks[s].stackname, sess)
				if err != nil {
					handleError(err)
				}

				for _, i := range outputs.Stacks {
					fmt.Printf("\n"+"[%s]"+"\n", *i.StackName)
					for _, o := range i.Outputs {
						fmt.Printf("  Description: %s\n  %s: %s\n\n", *o.Description, colorString(*o.OutputKey, "magenta"), *o.OutputValue)
					}
				}
				wg.Done()
			}(s)
		}
		wg.Wait()

	},
}

var exportsCmd = &cobra.Command{
	Use:     "exports",
	Short:   "Prints stack exports",
	Example: "qaz exports",
	Run: func(cmd *cobra.Command, args []string) {

		job.request = "exports"

		sess, err := awsSession()
		if err != nil {
			handleError(err)
			return
		}

		Exports(sess)

	},
}

var checkCmd = &cobra.Command{
	Use:   "check",
	Short: "Validates Cloudformation Templates",
	Example: strings.Join([]string{
		"qaz check -c path/to/config.yml -t path/to/template -c path/to/config",
		"qaz check -c path/to/config.yml -t stack::http://someurl.example",
		"qaz check -c path/to/config.yml -t stack::s3://bucket/key",
	}, "\n"),
	Run: func(cmd *cobra.Command, args []string) {

		job.request = "validate"

		s, source, err := getSource(job.tplFile)
		if err != nil {
			handleError(err)
			return
		}

		job.tplFile = source

		err = configReader(job.cfgFile)
		if err != nil {
			handleError(err)
			return
		}

		name := fmt.Sprintf("%s-%s", project, s)
		fmt.Println("Validating template for", name)

		tpl, err := genTimeParser(job.tplFile)
		if err != nil {
			handleError(err)
			return
		}

		sess, err := awsSession()
		if err != nil {
			handleError(err)
			return
		}

		if err := Check(tpl, sess); err != nil {
			handleError(err)
			return
		}
	},
}

var invokeCmd = &cobra.Command{
	Use:   "invoke",
	Short: "Invoke AWS Lambda Functions",
	Run: func(cmd *cobra.Command, args []string) {
		job.request = "lambda_invoke"
		fmt.Println(colorString("Coming Soon!", "magenta"))
	},
}

var tailCmd = &cobra.Command{
	Use:     "tail",
	Short:   "Tail Real-Time AWS Cloudformation events",
	Example: "qaz tail -r eu-west-1",
	Run: func(cmd *cobra.Command, args []string) {
		job.request = "tail"

		err := configReader(job.cfgFile)
		if err != nil {
			handleError(err)
			return
		}

		sess, err := awsSession()
		if err != nil {
			handleError(err)
		}

		// Tail each stack on it's own goroutine.
		for _, s := range stacks {
			wg.Add(1)
			go func(s *stack, sess *session.Session) {
				verbose(s.stackname, "", sess)
				wg.Done()
			}(s, sess)
		}

		wg.Wait() // Will probably wait forevery
	},
}
<commit_msg>minor adjustment to commands.go<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"sync"

	"github.com/CrowdSurge/banner"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/spf13/cobra"
)

// job var used as a central point for command data
var job = struct {
	cfgFile      string
	tplFile      string
	profile      string
	tplFiles     []string
	stacks       map[string]string
	terminateAll bool
	version      bool
	request      string
	debug        bool
	funcName     string
}{}

// Wait Group for handling goroutines
var wg sync.WaitGroup

// root command (calls all other commands)
var rootCmd = &cobra.Command{
	Use:   "qaz",
	Short: fmt.Sprintf("%s\n--> Shut up & deploy my templates...!", colorString(banner.PrintS("qaz"), "magenta")),
	Run: func(cmd *cobra.Command, args []string) {

		if job.version {
			fmt.Printf("qaz - Version %s"+"\n", version)
			return
		}

		cmd.Help()
	},
}

var initCmd = &cobra.Command{
	Use:   "init [target directory]",
	Short: "Creates a basic qaz project",
	Run: func(cmd *cobra.Command, args []string) {

		// Print Banner
		banner.Print("qaz")
		fmt.Printf("\n--\n")

		var target string
		switch len(args) {
		case 0:
			target, _ = os.Getwd()
		default:
			target = args[0]
		}

		// Get Project & AWS Region
		project = getInput("-> Enter your Project name", "MyqazProject")
		region = getInput("-> Enter AWS Region", "eu-west-1")

		// set target paths
		c := filepath.Join(target, "config.yml")
		t := filepath.Join(target, "templates")
		f := filepath.Join(target, "files")

		// Check if config file exists
		var overwrite string
		if _, err := os.Stat(c); err == nil {
			overwrite = getInput(
				fmt.Sprintf("%s [%s] already exist, Do you want to %s?(Y/N) ", colorString("->", "yellow"), c, colorString("Overwrite", "red")),
				"N",
			)

			if overwrite == "Y" {
				fmt.Println(fmt.Sprintf("%s Overwriting: [%s]..", colorString("->", "yellow"), c))
			}
		}

		// Create template file
		if overwrite != "N" {
			if err := ioutil.WriteFile(c, configTemplate(project, region), 0644); err != nil {
				fmt.Printf("%s Error, unable to create config.yml file: %s"+"\n", err, colorString("->", "red"))
				return
			}
		}

		// Create template folder
		for _, dir := range []string{t, f} {
			if err := os.Mkdir(dir, os.ModePerm); err != nil {
				fmt.Printf("%s [%s] folder not created: %s"+"\n--\n", colorString("->", "yellow"), dir, err)
				return
			}
		}

		fmt.Println("--")
	},
}

var generateCmd = &cobra.Command{
	Use:   "generate",
	Short: "Generates template from configuration values",
	Run: func(cmd *cobra.Command, args []string) {

		job.request = "generate"

		s, source, err := getSource(job.tplFile)
		if err != nil {
			handleError(err)
			return
		}

		job.tplFile = source
		err = configReader(job.cfgFile)
		if err != nil {
			handleError(err)
			return
		}

		name := fmt.Sprintf("%s-%s", project, s)
		Log(fmt.Sprintln("Generating a template for ", name), "debug")

		tpl, err := genTimeParser(job.tplFile)
		if err != nil {
			handleError(err)
			return
		}
		fmt.Println(tpl)
	},
}

var deployCmd = &cobra.Command{
	Use:   "deploy",
	Short: "Deploys stack(s) to AWS",
	Example: strings.Join([]string{
		"qaz deploy -c path/to/config -t path/to/template",
		"qaz deploy -c path/to/config -t stack::s3//bucket/key",
		"qaz deploy -c path/to/config -t stack::http://someurl",
	}, "\n"),
	Run: func(cmd *cobra.Command, args []string) {

		job.request = "deploy"

		job.stacks = make(map[string]string)

		sourceCopy := job.tplFiles

		// creating empty template list for re-population later
		job.tplFiles = []string{}

		for _, src := range sourceCopy {
			if strings.Contains(src, `*`) {
				glob, _ := filepath.Glob(src)

				for _, f := range glob {
					job.tplFiles = append(job.tplFiles, f)
				}
				continue
			}

			job.tplFiles = append(job.tplFiles, src)
		}

		for _, f := range job.tplFiles {
			s, source, err := getSource(f)
			if err != nil {
				handleError(err)
				return
			}
			job.stacks[s] = source
		}

		err := configReader(job.cfgFile)
		if err != nil {
			handleError(err)
			return
		}

		for s, f := range job.stacks {
			if v, err := genTimeParser(f); err != nil {
				handleError(err)
			} else {
				stacks[s].template = v
			}
		}

		// Deploy Stacks
		DeployHandler()

	},
}

var updateCmd = &cobra.Command{
	Use:   "update",
	Short: "Updates a given stack",
	Example: strings.Join([]string{
		"qaz update -c path/to/config -t stack::path/to/template",
		"qaz update -c path/to/config -t stack::s3//bucket/key",
		"qaz update -c path/to/config -t stack::http://someurl",
	}, "\n"),
	Run: func(cmd *cobra.Command, args []string) {

		job.request = "update"

		s, source, err := getSource(job.tplFile)
		if err != nil {
			handleError(err)
			return
		}

		fmt.Println(source)

		job.tplFile = source

		err = configReader(job.cfgFile)
		if err != nil {
			handleError(err)
			return
		}

		v, err := genTimeParser(job.tplFile)
		if err != nil {
			handleError(err)
			return
		}

		stacks[s].template = v

		// Update stack
		sess, err := awsSession()
		if err != nil {
			handleError(err)
			return
		}
		stacks[s].update(sess)

	},
}

var terminateCmd = &cobra.Command{
	Use:   "terminate [stacks]",
	Short: "Terminates stacks",
	Run: func(cmd *cobra.Command, args []string) {

		job.request = "terminate"

		if !job.terminateAll {
			job.stacks = make(map[string]string)
			for _, stk := range args {
				job.stacks[stk] = ""
			}

			if len(job.stacks) == 0 {
				Log("No stack specified for termination", level.warn)
				return
			}
		}

		err := configReader(job.cfgFile)
		if err != nil {
			handleError(err)
			return
		}

		// Terminate Stacks
		TerminateHandler()
	},
}

var statusCmd = &cobra.Command{
	Use:   "status",
	Short: "Prints status of deployed/un-deployed stacks",
	Run: func(cmd *cobra.Command, args []string) {

		job.request = "status"

		err := configReader(job.cfgFile)
		if err != nil {
			handleError(err)
			return
		}

		sess, err := awsSession()
		if err != nil {
			handleError(err)
			return
		}

		for _, v := range stacks {
			wg.Add(1)
			go func(s *stack) {
				if err := s.status(sess); err != nil {
					handleError(err)
				}
				wg.Done()
			}(v)

		}
		wg.Wait()
	},
}

var outputsCmd = &cobra.Command{
	Use:     "outputs [stack]",
	Short:   "Prints stack outputs",
	Example: "qaz outputs vpc subnets --config path/to/config",
	Run: func(cmd *cobra.Command, args []string) {

		job.request = "outputs"

		if len(args) < 1 {
			fmt.Println("Please specify stack(s) to check, For details try --> qaz outputs --help")
			return
		}

		err := configReader(job.cfgFile)
		if err != nil {
			handleError(err)
			return
		}

		sess, err := awsSession()
		if err != nil {
			handleError(err)
			return
		}

		for _, s := range args {
			wg.Add(1)
			go func(s string) {
				outputs, err := StackOutputs(stacks[s].stackname, sess)
				if err != nil {
					handleError(err)
				}

				for _, i := range outputs.Stacks {
					fmt.Printf("\n"+"[%s]"+"\n", *i.StackName)
					for _, o := range i.Outputs {
						fmt.Printf("  Description: %s\n  %s: %s\n\n", *o.Description, colorString(*o.OutputKey, "magenta"), *o.OutputValue)
					}
				}
				wg.Done()
			}(s)
		}
		wg.Wait()

	},
}

var exportsCmd = &cobra.Command{
	Use:     "exports",
	Short:   "Prints stack exports",
	Example: "qaz exports",
	Run: func(cmd *cobra.Command, args []string) {

		job.request = "exports"

		sess, err := awsSession()
		if err != nil {
			handleError(err)
			return
		}

		Exports(sess)

	},
}

var checkCmd = &cobra.Command{
	Use:   "check",
	Short: "Validates Cloudformation Templates",
	Example: strings.Join([]string{
		"qaz check -c path/to/config.yml -t path/to/template -c path/to/config",
		"qaz check -c path/to/config.yml -t stack::http://someurl.example",
		"qaz check -c path/to/config.yml -t stack::s3://bucket/key",
	}, "\n"),
	Run: func(cmd *cobra.Command, args []string) {

		job.request = "validate"

		s, source, err := getSource(job.tplFile)
		if err != nil {
			handleError(err)
			return
		}

		job.tplFile = source

		err = configReader(job.cfgFile)
		if err != nil {
			handleError(err)
			return
		}

		name := fmt.Sprintf("%s-%s", project, s)
		fmt.Println("Validating template for", name)

		tpl, err := genTimeParser(job.tplFile)
		if err != nil {
			handleError(err)
			return
		}

		sess, err := awsSession()
		if err != nil {
			handleError(err)
			return
		}

		if err := Check(tpl, sess); err != nil {
			handleError(err)
			return
		}
	},
}

var invokeCmd = &cobra.Command{
	Use:   "invoke",
	Short: "Invoke AWS Lambda Functions",
	Run: func(cmd *cobra.Command, args []string) {
		job.request = "lambda_invoke"
		fmt.Println(colorString("Coming Soon!", "magenta"))
	},
}

var tailCmd = &cobra.Command{
	Use:     "tail",
	Short:   "Tail Real-Time AWS Cloudformation events",
	Example: "qaz tail -r eu-west-1",
	Run: func(cmd *cobra.Command, args []string) {
		job.request = "tail"

		err := configReader(job.cfgFile)
		if err != nil {
			handleError(err)
			return
		}

		sess, err := awsSession()
		if err != nil {
			handleError(err)
		}

		// Tail each stack on it's own goroutine.
		for _, s := range stacks {
			wg.Add(1)
			go func(s *stack, sess *session.Session) {
				verbose(s.stackname, "", sess)
				wg.Done()
			}(s, sess)
		}

		wg.Wait() // Will probably wait forevery
	},
}
<|endoftext|>


<commit_before>package adm

import (
	"log"
	"os"

	"github.com/codegangsta/cli"
)

var Commands = []cli.Command{
	commandInit,
	commandAdd,
	commandSync,
	commandDiscard,
	commandPush,
	commandStatus,
	commandInstall,
	commandSecret,
}

var commandInit = cli.Command{
	Name:  "init",
	Usage: "",
	Description: `
`,
	Action: doInit,
}

var commandAdd = cli.Command{
	Name:  "add",
	Usage: "",
	Description: `
`,
	Action: doAdd,
}

var commandSync = cli.Command{
	Name:  "sync",
	Usage: "",
	Description: `
`,
	Action: doSync,
}

var commandDiscard = cli.Command{
	Name:  "discard",
	Usage: "",
	Description: `
`,
	Action: doDiscard,
}

var commandPush = cli.Command{
	Name:  "push",
	Usage: "",
	Description: `
`,
	Action: doPush,
}

var commandStatus = cli.Command{
	Name:  "status",
	Usage: "",
	Description: `
`,
	Action: doStatus,
}

var commandInstall = cli.Command{
	Name:  "install",
	Usage: "",
	Description: `
`,
	Action: doInstall,
}

var commandSecret = cli.Command{
	Name:  "secret",
	Usage: "",
	Description: `
`,
	Action: doSecret,
}

func debug(v ...interface{}) {
	if os.Getenv("DEBUG") != "" {
		log.Println(v...)
	}
}

func assert(err error) {
	if err != nil {
		log.Fatal(err)
	}
}

func doInit(c *cli.Context) {
}

func doAdd(c *cli.Context) {
}

func doSync(c *cli.Context) {
}

func doDiscard(c *cli.Context) {
}

func doPush(c *cli.Context) {
}

func doStatus(c *cli.Context) {
}

func doInstall(c *cli.Context) {
}

func doSecret(c *cli.Context) {
}
<commit_msg>Write down usage, fill in funcs<commit_after>package adm

import (
	"log"
	"os"

	"github.com/codegangsta/cli"
)

var Commands = []cli.Command{
	commandInit,
	commandAdd,
	commandSync,
	commandDiscard,
	commandPush,
	commandStatus,
	commandInstall,
	commandSecret,
}

var commandInit = cli.Command{
	Name:  "init",
	Usage: "Initialize a dotfile manager",
	Description: `
	--repo specify repo name
`,
	Action: doInit,
}

var commandAdd = cli.Command{
	Name:  "add",
	Usage: "Add dotfiles to files managed",
	Description: `
`,
	Action: doAdd,
}

var commandSync = cli.Command{
	Name:  "sync",
	Usage: "Sync dotfiles current status to managed files",
	Description: `
`,
	Action: doSync,
}

var commandDiscard = cli.Command{
	Name:  "discard",
	Usage: "Discard dotfiles status and reset to be last saved one",
	Description: `
`,
	Action: doDiscard,
}

var commandPush = cli.Command{
	Name:  "push",
	Usage: "Push managed dotfiles to remote repositories",
	Description: `
`,
	Action: doPush,
}

var commandStatus = cli.Command{
	Name:  "status",
	Usage: "Show status of managed dotfiles",
	Description: `
`,
	Action: doStatus,
}

var commandInstall = cli.Command{
	Name:  "install",
	Usage: "Install dotfiles from remote config, load from `Dotfiles.source' by default",
	Description: `
`,
	Action: doInstall,
}

var commandSecret = cli.Command{
	Name:  "secret",
	Usage: "Register/unregister secret string values to file",
	Description: `
`,
	Action: doSecret,
}

func debug(v ...interface{}) {
	if os.Getenv("DEBUG") != "" {
		log.Println(v...)
	}
}

func assert(err error) {
	if err != nil {
		log.Fatal(err)
	}
}

func doInit(c *cli.Context) {
	log.Println("Going to implement first!")
}

func doAdd(c *cli.Context) {
	panic("Not yet implemented.")
}

func doSync(c *cli.Context) {
	panic("Not yet implemented.")
}

func doDiscard(c *cli.Context) {
	panic("Not yet implemented.")
}

func doPush(c *cli.Context) {
	panic("Not yet implemented.")
}

func doStatus(c *cli.Context) {
	panic("Not yet implemented.")
}

func doInstall(c *cli.Context) {
	panic("Not yet implemented.")
}

func doSecret(c *cli.Context) {
	panic("Not yet implemented.")
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/go-telegram-bot-api/telegram-bot-api"
	"strings"
)

func StartCommand(update tgbotapi.Update) {
	msg := tgbotapi.NewMessage(update.Message.Chat.ID, "Simple bot for Overwatch by @kraso\n\n"+
		"How to use:\n"+
		"1. Use /save to save your game profile.\n"+
		"2. Use /me to see your stats.\n"+
		"3. ???\n"+
		"4. PROFIT!\n\n"+
		"Features:\n"+
		"— Player profile (/me command)\n"+
		"— Small summary for heroes\n"+
		"— Reports after every game session\n")
	msg.ParseMode = "HTML"
	bot.Send(msg)

	log.Info("/start command executed successful")
}

func DonateCommand(update tgbotapi.Update) {
	msg := tgbotapi.NewMessage(update.Message.Chat.ID, "If you find this bot helpful, "+
		"you can make small donation to help me pay server bills!")
	msg.ParseMode = "HTML"
	bot.Send(msg)

	log.Info("donate command executed successful")
}

type Hero struct {
	Name                string
	TimePlayedInSeconds int
}

type Heroes []Hero

func (hero Heroes) Len() int {
	return len(hero)
}

func (hero Heroes) Less(i, j int) bool {
	return hero[i].TimePlayedInSeconds < hero[j].TimePlayedInSeconds
}

func (hero Heroes) Swap(i, j int) {
	hero[i], hero[j] = hero[j], hero[i]
}

func SaveCommand(update tgbotapi.Update) {
	info := strings.Split(update.Message.Text, " ")
	var text string

	if len(info) == 3 {
		if info[1] != "psn" && info[1] != "xbl" {
			info[2] = strings.Replace(info[2], "#", "-", -1)
		}

		profile, err := GetOverwatchProfile(info[1], info[2])
		if err != nil {
			log.Warn(err)
			text = "Player not found!"
		} else {
			_, err := InsertUser(User{
				Id:      fmt.Sprint(dbPKPrefix, update.Message.From.ID),
				Profile: profile,
				Region:  info[1],
				Nick:    info[2],
			})
			if err != nil {
				log.Warn(err)
				return
			}

			log.Info("/save command executed successful")
			text = "Saved!"
		}
	} else {
		text = "Example: /save eu|us|kr|psn|xbl BattleTag#1337|ConsoleLogin"
	}

	msg := tgbotapi.NewMessage(update.Message.Chat.ID, text)
	msg.ParseMode = "HTML"
	bot.Send(msg)
}

func AuthCommand(update tgbotapi.Update) {
	res, err := IncertAuth(fmt.Sprint(dbPKPrefix, update.Message.From.ID))
	if err != nil {
		log.Warn(err)
		return
	}
	text := fmt.Sprintf("Auth via Battle.Net", res.GeneratedKeys[0])

	msg := tgbotapi.NewMessage(update.Message.Chat.ID, text)
	msg.ParseMode = "HTML"
	bot.Send(msg)
}

func MeCommand(update tgbotapi.Update) {
	user, err := GetUser(fmt.Sprint(dbPKPrefix, update.Message.From.ID))
	if err != nil {
		log.Warn(err)
		return
	}

	place, err := GetRatingPlace(fmt.Sprint(dbPKPrefix, update.Message.From.ID))
	if err != nil {
		log.Warn(err)
		return
	}

	log.Info("/me command executed successful")

	var text string
	info := strings.Split(update.Message.Text, "_")

	if len(info) == 1 {
		text = MakeSummary(user, place, "CompetitiveStats")
	} else if len(info) == 2 && info[1] == "quick" {
		text = MakeSummary(user, place, "QuickPlayStats")
	}

	msg := tgbotapi.NewMessage(update.Message.Chat.ID, text)
	msg.ParseMode = "HTML"
	bot.Send(msg)
}

func HeroCommand(update tgbotapi.Update) {
	user, err := GetUser(fmt.Sprint(dbPKPrefix, update.Message.From.ID))
	if err != nil {
		log.Warn(err)
		return
	}

	log.Info("/h_ command executed successful")

	var text string
	info := strings.Split(update.Message.Text, "_")
	hero := info[1]

	if len(info) == 2 {
		text = MakeHeroSummary(hero, "CompetitiveStats", user)
	} else if len(info) == 3 && info[2] == "quick" {
		text = MakeHeroSummary(hero, "QuickPlayStats", user)
	}

	msg := tgbotapi.NewMessage(update.Message.Chat.ID, text)
	msg.ParseMode = "HTML"
	bot.Send(msg)
}

func RatingTopCommand(update tgbotapi.Update, platform string) {
	top, err := GetRatingTop(platform, 20)
	if err != nil {
		log.Warn(err)
		return
	}

	text := "Rating Top:\n"
	for i := range top {
		nick := top[i].Nick
		if top[i].Region != "psn" && top[i].Region != "xbl" {
			nick = strings.Replace(nick, "-", "#", -1)
		}
		text += fmt.Sprintf("%d. %s (%d)\n", i+1, nick, top[i].Profile.Rating)
	}

	msg := tgbotapi.NewMessage(update.Message.Chat.ID, text)
	msg.ParseMode = "HTML"
	bot.Send(msg)
}
<commit_msg>URL fix!<commit_after>package main

import (
	"fmt"
	"github.com/go-telegram-bot-api/telegram-bot-api"
	"strings"
)

func StartCommand(update tgbotapi.Update) {
	msg := tgbotapi.NewMessage(update.Message.Chat.ID, "Simple bot for Overwatch by @kraso\n\n"+
		"How to use:\n"+
		"1. Use /save to save your game profile.\n"+
		"2. Use /me to see your stats.\n"+
		"3. ???\n"+
		"4. PROFIT!\n\n"+
		"Features:\n"+
		"— Player profile (/me command)\n"+
		"— Small summary for heroes\n"+
		"— Reports after every game session\n")
	msg.ParseMode = "HTML"
	bot.Send(msg)

	log.Info("/start command executed successful")
}

func DonateCommand(update tgbotapi.Update) {
	msg := tgbotapi.NewMessage(update.Message.Chat.ID, "If you find this bot helpful, "+
		"you can make small donation to help me pay server bills!")
	msg.ParseMode = "HTML"
	bot.Send(msg)

	log.Info("donate command executed successful")
}

type Hero struct {
	Name                string
	TimePlayedInSeconds int
}

type Heroes []Hero

func (hero Heroes) Len() int {
	return len(hero)
}

func (hero Heroes) Less(i, j int) bool {
	return hero[i].TimePlayedInSeconds < hero[j].TimePlayedInSeconds
}

func (hero Heroes) Swap(i, j int) {
	hero[i], hero[j] = hero[j], hero[i]
}

func SaveCommand(update tgbotapi.Update) {
	info := strings.Split(update.Message.Text, " ")
	var text string

	if len(info) == 3 {
		if info[1] != "psn" && info[1] != "xbl" {
			info[2] = strings.Replace(info[2], "#", "-", -1)
		}

		profile, err := GetOverwatchProfile(info[1], info[2])
		if err != nil {
			log.Warn(err)
			text = "Player not found!"
		} else {
			_, err := InsertUser(User{
				Id:      fmt.Sprint(dbPKPrefix, update.Message.From.ID),
				Profile: profile,
				Region:  info[1],
				Nick:    info[2],
			})
			if err != nil {
				log.Warn(err)
				return
			}

			log.Info("/save command executed successful")
			text = "Saved!"
		}
	} else {
		text = "Example: /save eu|us|kr|psn|xbl BattleTag#1337|ConsoleLogin"
	}

	msg := tgbotapi.NewMessage(update.Message.Chat.ID, text)
	msg.ParseMode = "HTML"
	bot.Send(msg)
}

func AuthCommand(update tgbotapi.Update) {
	res, err := IncertAuth(fmt.Sprint(dbPKPrefix, update.Message.From.ID))
	if err != nil {
		log.Warn(err)
		return
	}
	text := fmt.Sprintf("Auth via Battle.Net", res.GeneratedKeys[0])

	msg := tgbotapi.NewMessage(update.Message.Chat.ID, text)
	msg.ParseMode = "HTML"
	bot.Send(msg)
}

func MeCommand(update tgbotapi.Update) {
	user, err := GetUser(fmt.Sprint(dbPKPrefix, update.Message.From.ID))
	if err != nil {
		log.Warn(err)
		return
	}

	place, err := GetRatingPlace(fmt.Sprint(dbPKPrefix, update.Message.From.ID))
	if err != nil {
		log.Warn(err)
		return
	}

	log.Info("/me command executed successful")

	var text string
	info := strings.Split(update.Message.Text, "_")

	if len(info) == 1 {
		text = MakeSummary(user, place, "CompetitiveStats")
	} else if len(info) == 2 && info[1] == "quick" {
		text = MakeSummary(user, place, "QuickPlayStats")
	}

	msg := tgbotapi.NewMessage(update.Message.Chat.ID, text)
	msg.ParseMode = "HTML"
	bot.Send(msg)
}

func HeroCommand(update tgbotapi.Update) {
	user, err := GetUser(fmt.Sprint(dbPKPrefix, update.Message.From.ID))
	if err != nil {
		log.Warn(err)
		return
	}

	log.Info("/h_ command executed successful")

	var text string
	info := strings.Split(update.Message.Text, "_")
	hero := info[1]

	if len(info) == 2 {
		text = MakeHeroSummary(hero, "CompetitiveStats", user)
	} else if len(info) == 3 && info[2] == "quick" {
		text = MakeHeroSummary(hero, "QuickPlayStats", user)
	}

	msg := tgbotapi.NewMessage(update.Message.Chat.ID, text)
	msg.ParseMode = "HTML"
	bot.Send(msg)
}

func RatingTopCommand(update tgbotapi.Update, platform string) {
	top, err := GetRatingTop(platform, 20)
	if err != nil {
		log.Warn(err)
		return
	}

	text := "Rating Top:\n"
	for i := range top {
		nick := top[i].Nick
		if top[i].Region != "psn" && top[i].Region != "xbl" {
			nick = strings.Replace(nick, "-", "#", -1)
		}
		text += fmt.Sprintf("%d. %s (%d)\n", i+1, nick, top[i].Profile.Rating)
	}

	msg := tgbotapi.NewMessage(update.Message.Chat.ID, text)
	msg.ParseMode = "HTML"
	bot.Send(msg)
}
<|endoftext|>


<commit_before>package channeldb

import (
	"io/ioutil"
	"os"
	"path/filepath"
	"testing"
)

func TestOpenWithCreate(t *testing.T) {
	t.Parallel()

	// First, create a temporary directory to be used for the duration of
	// this test.
	tempDirName, err := ioutil.TempDir("", "channeldb")
	if err != nil {
		t.Fatalf("unable to create temp dir: %v", err)
	}
	defer os.RemoveAll(tempDirName)

	// Next, open thereby creating channeldb for the first time.
	dbPath := filepath.Join(tempDirName, "cdb")
	cdb, err := Open(dbPath)
	if err != nil {
		t.Fatalf("unable to create channeldb: %v", err)
	}
	if err := cdb.Close(); err != nil {
		t.Fatalf("unable to close channeldb: %v", err)
	}

	// The path should have been successfully created.
	if !fileExists(dbPath) {
		t.Fatalf("channeldb failed to create data directory")
	}
}
<commit_msg>Add unit test for db Wipe.<commit_after>package channeldb

import (
	"io/ioutil"
	"os"
	"path/filepath"
	"testing"
)

func TestOpenWithCreate(t *testing.T) {
	t.Parallel()

	// First, create a temporary directory to be used for the duration of
	// this test.
	tempDirName, err := ioutil.TempDir("", "channeldb")
	if err != nil {
		t.Fatalf("unable to create temp dir: %v", err)
	}
	defer os.RemoveAll(tempDirName)

	// Next, open thereby creating channeldb for the first time.
	dbPath := filepath.Join(tempDirName, "cdb")
	cdb, err := Open(dbPath)
	if err != nil {
		t.Fatalf("unable to create channeldb: %v", err)
	}
	if err := cdb.Close(); err != nil {
		t.Fatalf("unable to close channeldb: %v", err)
	}

	// The path should have been successfully created.
	if !fileExists(dbPath) {
		t.Fatalf("channeldb failed to create data directory")
	}
}

// TestWipe tests that the database wipe operation completes successfully
// and that the buckets are deleted. It also checks that attempts to fetch
// information while the buckets are not set return the correct errors.
func TestWipe(t *testing.T) {
	t.Parallel()

	// First, create a temporary directory to be used for the duration of
	// this test.
	tempDirName, err := ioutil.TempDir("", "channeldb")
	if err != nil {
		t.Fatalf("unable to create temp dir: %v", err)
	}
	defer os.RemoveAll(tempDirName)

	// Next, open thereby creating channeldb for the first time.
	dbPath := filepath.Join(tempDirName, "cdb")
	cdb, err := Open(dbPath)
	if err != nil {
		t.Fatalf("unable to create channeldb: %v", err)
	}
	defer cdb.Close()

	if err := cdb.Wipe(); err != nil {
		t.Fatalf("unable to wipe channeldb: %v", err)
	}
	// Check correct errors are returned
	_, err = cdb.FetchAllOpenChannels()
	if err != ErrNoActiveChannels {
		t.Fatalf("fetching open channels: expected '%v' instead got '%v'",
			ErrNoActiveChannels, err)
	}
	_, err = cdb.FetchClosedChannels(false)
	if err != ErrNoClosedChannels {
		t.Fatalf("fetching closed channels: expected '%v' instead got '%v'",
			ErrNoClosedChannels, err)
	}
}
<|endoftext|>