<commit_before>package spectrumscale

import (
	"log"

	"fmt"

	"github.com/jinzhu/gorm"
	_ "github.com/mattn/go-sqlite3"
	"github.ibm.com/almaden-containers/ubiquity/model"
	"github.ibm.com/almaden-containers/ubiquity/resources"
)

//go:generate counterfeiter -o ../../fakes/fake_SpectrumDataModel.go . SpectrumDataModel
type SpectrumDataModel interface {
	CreateVolumeTable() error
	SetClusterId(string)
	GetClusterId() string
	DeleteVolume(name string) error
	InsertFilesetVolume(fileset, volumeName string, filesystem string, isPreexisting bool, opts map[string]interface{}) error
	InsertLightweightVolume(fileset, directory, volumeName string, filesystem string, isPreexisting bool, opts map[string]interface{}) error
	InsertFilesetQuotaVolume(fileset, quota, volumeName string, filesystem string, isPreexisting bool, opts map[string]interface{}) error
	GetVolume(name string) (SpectrumScaleVolume, bool, error)
	ListVolumes() ([]SpectrumScaleVolume, error)
}

type spectrumDataModel struct {
	log       *log.Logger
	database  *gorm.DB
	clusterId string
	backend   resources.Backend
}

type VolumeType int

const (
	FILESET VolumeType = iota
	LIGHTWEIGHT
	FILESET_WITH_QUOTA
)

const (
	USER_SPECIFIED_UID string = "uid"
	USER_SPECIFIED_GID string = "gid"
)

type SpectrumScaleVolume struct {
	ID            uint
	Volume        model.Volume
	VolumeID      uint
	Type          VolumeType
	ClusterId     string
	FileSystem    string
	Fileset       string
	Directory     string
	UID           string
	GID           string
	Quota         string
	IsPreexisting bool
}

func NewSpectrumDataModel(log *log.Logger, db *gorm.DB, backend resources.Backend) SpectrumDataModel {
	return &spectrumDataModel{log: log, database: db, backend: backend}
}

func (d *spectrumDataModel) SetClusterId(id string) {
	d.clusterId = id
}
func (d *spectrumDataModel) GetClusterId() string {
	return d.clusterId
}
func (d *spectrumDataModel) CreateVolumeTable() error {
	d.log.Println("SpectrumDataModel: Create Volumes Table start")
	defer d.log.Println("SpectrumDataModel: Create Volumes Table end")

	if err := d.database.AutoMigrate(&SpectrumScaleVolume{}).Error; err != nil {
		return err
	}
	return nil
}

func (d *spectrumDataModel) DeleteVolume(name string) error {
	d.log.Println("SpectrumDataModel: DeleteVolume start")
	defer d.log.Println("SpectrumDataModel: DeleteVolume end")

	volume, exists, err := d.GetVolume(name)

	if err != nil {
		return err
	}
	if exists == false {
		return fmt.Errorf("Volume : %s not found", name)
	}

	if err := d.database.Delete(&volume).Error; err != nil {
		return err
	}
	return nil
}

func (d *spectrumDataModel) InsertFilesetVolume(fileset, volumeName string, filesystem string, isPreexisting bool, opts map[string]interface{}) error {
	d.log.Println("SpectrumDataModel: InsertFilesetVolume start")
	defer d.log.Println("SpectrumDataModel: InsertFilesetVolume end")

	volume := SpectrumScaleVolume{Volume: model.Volume{Name: volumeName, Backend: fmt.Sprintf("%s", d.backend)}, Type: FILESET, ClusterId: d.clusterId, FileSystem: filesystem,
		Fileset: fileset, IsPreexisting: isPreexisting}

	addPermissionsForVolume(&volume, opts)

	return d.insertVolume(volume)
}

func (d *spectrumDataModel) InsertLightweightVolume(fileset, directory, volumeName string, filesystem string, isPreexisting bool, opts map[string]interface{}) error {
	d.log.Println("SpectrumDataModel: InsertLightweightVolume start")
	defer d.log.Println("SpectrumDataModel: InsertLightweightVolume end")

	volume := SpectrumScaleVolume{Volume: model.Volume{Name: volumeName, Backend: fmt.Sprintf("%s", d.backend)}, Type: LIGHTWEIGHT, ClusterId: d.clusterId, FileSystem: filesystem,
		Fileset: fileset, Directory: directory, IsPreexisting: isPreexisting}

	addPermissionsForVolume(&volume, opts)

	return d.insertVolume(volume)
}

func (d *spectrumDataModel) InsertFilesetQuotaVolume(fileset, quota, volumeName string, filesystem string, isPreexisting bool, opts map[string]interface{}) error {
	d.log.Println("SpectrumDataModel: InsertFilesetQuotaVolume start")
	defer d.log.Println("SpectrumDataModel: InsertFilesetQuotaVolume end")

	volume := SpectrumScaleVolume{Volume: model.Volume{Name: volumeName, Backend: fmt.Sprintf("%s", d.backend)}, Type: FILESET_WITH_QUOTA, ClusterId: d.clusterId, FileSystem: filesystem,
		Fileset: fileset, Quota: quota, IsPreexisting: isPreexisting}

	addPermissionsForVolume(&volume, opts)

	return d.insertVolume(volume)
}

func (d *spectrumDataModel) insertVolume(volume SpectrumScaleVolume) error {
	d.log.Println("SpectrumDataModel: insertVolume start")
	defer d.log.Println("SpectrumDataModel: insertVolume end")

	if err := d.database.Create(&volume).Error; err != nil {
		return err
	}
	return nil
}

func (d *spectrumDataModel) GetVolume(name string) (SpectrumScaleVolume, bool, error) {
	d.log.Println("SpectrumDataModel: GetVolume start")
	defer d.log.Println("SpectrumDataModel: GetVolume end")

	volume, err := model.GetVolume(d.database, name, d.backend)
	if err != nil {
		if err.Error() == "record not found" {
			return SpectrumScaleVolume{}, false, nil
		}
		return SpectrumScaleVolume{}, false, err
	}

	var spectrumVolume SpectrumScaleVolume
	if err := d.database.Where("volume_id = ?", volume.ID).Preload("Volume").First(&spectrumVolume).Error; err != nil {
		if err.Error() == "record not found" {
			return SpectrumScaleVolume{}, false, nil
		}
		return SpectrumScaleVolume{}, false, err
	}
	return spectrumVolume, true, nil
}

func (d *spectrumDataModel) ListVolumes() ([]SpectrumScaleVolume, error) {
	d.log.Println("SpectrumDataModel: ListVolumes start")
	defer d.log.Println("SpectrumDataModel: ListVolumes end")

	var volumes []SpectrumScaleVolume
	if err := d.database.Preload("Volume").Find(&volumes).Error; err != nil {
		return nil, err
	}
	// hack: to be replaced by proper DB filtering (joins)
	for _, volume := range volumes {
		if resources.Backend(volume.Volume.Backend) == d.backend {
			volumes = append(volumes, volume)
		}
	}

	return volumes, nil
}

func addPermissionsForVolume(volume *SpectrumScaleVolume, opts map[string]interface{}) {

	if len(opts) > 0 {
		uid, uidSpecified := opts[USER_SPECIFIED_UID]
		gid, gidSpecified := opts[USER_SPECIFIED_GID]

		if uidSpecified && gidSpecified {
			volume.UID = uid.(string)
			volume.GID = gid.(string)

		}
	}
}
<commit_msg>Fix listing duplicate volume issue (#27)<commit_after>package spectrumscale

import (
	"log"

	"fmt"

	"github.com/jinzhu/gorm"
	_ "github.com/mattn/go-sqlite3"
	"github.ibm.com/almaden-containers/ubiquity/model"
	"github.ibm.com/almaden-containers/ubiquity/resources"
)

//go:generate counterfeiter -o ../../fakes/fake_SpectrumDataModel.go . SpectrumDataModel
type SpectrumDataModel interface {
	CreateVolumeTable() error
	SetClusterId(string)
	GetClusterId() string
	DeleteVolume(name string) error
	InsertFilesetVolume(fileset, volumeName string, filesystem string, isPreexisting bool, opts map[string]interface{}) error
	InsertLightweightVolume(fileset, directory, volumeName string, filesystem string, isPreexisting bool, opts map[string]interface{}) error
	InsertFilesetQuotaVolume(fileset, quota, volumeName string, filesystem string, isPreexisting bool, opts map[string]interface{}) error
	GetVolume(name string) (SpectrumScaleVolume, bool, error)
	ListVolumes() ([]SpectrumScaleVolume, error)
}

type spectrumDataModel struct {
	log       *log.Logger
	database  *gorm.DB
	clusterId string
	backend   resources.Backend
}

type VolumeType int

const (
	FILESET VolumeType = iota
	LIGHTWEIGHT
	FILESET_WITH_QUOTA
)

const (
	USER_SPECIFIED_UID string = "uid"
	USER_SPECIFIED_GID string = "gid"
)

type SpectrumScaleVolume struct {
	ID            uint
	Volume        model.Volume
	VolumeID      uint
	Type          VolumeType
	ClusterId     string
	FileSystem    string
	Fileset       string
	Directory     string
	UID           string
	GID           string
	Quota         string
	IsPreexisting bool
}

func NewSpectrumDataModel(log *log.Logger, db *gorm.DB, backend resources.Backend) SpectrumDataModel {
	return &spectrumDataModel{log: log, database: db, backend: backend}
}

func (d *spectrumDataModel) SetClusterId(id string) {
	d.clusterId = id
}
func (d *spectrumDataModel) GetClusterId() string {
	return d.clusterId
}
func (d *spectrumDataModel) CreateVolumeTable() error {
	d.log.Println("SpectrumDataModel: Create Volumes Table start")
	defer d.log.Println("SpectrumDataModel: Create Volumes Table end")

	if err := d.database.AutoMigrate(&SpectrumScaleVolume{}).Error; err != nil {
		return err
	}
	return nil
}

func (d *spectrumDataModel) DeleteVolume(name string) error {
	d.log.Println("SpectrumDataModel: DeleteVolume start")
	defer d.log.Println("SpectrumDataModel: DeleteVolume end")

	volume, exists, err := d.GetVolume(name)

	if err != nil {
		return err
	}
	if exists == false {
		return fmt.Errorf("Volume : %s not found", name)
	}

	if err := d.database.Delete(&volume).Error; err != nil {
		return err
	}
	return nil
}

func (d *spectrumDataModel) InsertFilesetVolume(fileset, volumeName string, filesystem string, isPreexisting bool, opts map[string]interface{}) error {
	d.log.Println("SpectrumDataModel: InsertFilesetVolume start")
	defer d.log.Println("SpectrumDataModel: InsertFilesetVolume end")

	volume := SpectrumScaleVolume{Volume: model.Volume{Name: volumeName, Backend: fmt.Sprintf("%s", d.backend)}, Type: FILESET, ClusterId: d.clusterId, FileSystem: filesystem,
		Fileset: fileset, IsPreexisting: isPreexisting}

	addPermissionsForVolume(&volume, opts)

	return d.insertVolume(volume)
}

func (d *spectrumDataModel) InsertLightweightVolume(fileset, directory, volumeName string, filesystem string, isPreexisting bool, opts map[string]interface{}) error {
	d.log.Println("SpectrumDataModel: InsertLightweightVolume start")
	defer d.log.Println("SpectrumDataModel: InsertLightweightVolume end")

	volume := SpectrumScaleVolume{Volume: model.Volume{Name: volumeName, Backend: fmt.Sprintf("%s", d.backend)}, Type: LIGHTWEIGHT, ClusterId: d.clusterId, FileSystem: filesystem,
		Fileset: fileset, Directory: directory, IsPreexisting: isPreexisting}

	addPermissionsForVolume(&volume, opts)

	return d.insertVolume(volume)
}

func (d *spectrumDataModel) InsertFilesetQuotaVolume(fileset, quota, volumeName string, filesystem string, isPreexisting bool, opts map[string]interface{}) error {
	d.log.Println("SpectrumDataModel: InsertFilesetQuotaVolume start")
	defer d.log.Println("SpectrumDataModel: InsertFilesetQuotaVolume end")

	volume := SpectrumScaleVolume{Volume: model.Volume{Name: volumeName, Backend: fmt.Sprintf("%s", d.backend)}, Type: FILESET_WITH_QUOTA, ClusterId: d.clusterId, FileSystem: filesystem,
		Fileset: fileset, Quota: quota, IsPreexisting: isPreexisting}

	addPermissionsForVolume(&volume, opts)

	return d.insertVolume(volume)
}

func (d *spectrumDataModel) insertVolume(volume SpectrumScaleVolume) error {
	d.log.Println("SpectrumDataModel: insertVolume start")
	defer d.log.Println("SpectrumDataModel: insertVolume end")

	if err := d.database.Create(&volume).Error; err != nil {
		return err
	}
	return nil
}

func (d *spectrumDataModel) GetVolume(name string) (SpectrumScaleVolume, bool, error) {
	d.log.Println("SpectrumDataModel: GetVolume start")
	defer d.log.Println("SpectrumDataModel: GetVolume end")

	volume, err := model.GetVolume(d.database, name, d.backend)
	if err != nil {
		if err.Error() == "record not found" {
			return SpectrumScaleVolume{}, false, nil
		}
		return SpectrumScaleVolume{}, false, err
	}

	var spectrumVolume SpectrumScaleVolume
	if err := d.database.Where("volume_id = ?", volume.ID).Preload("Volume").First(&spectrumVolume).Error; err != nil {
		if err.Error() == "record not found" {
			return SpectrumScaleVolume{}, false, nil
		}
		return SpectrumScaleVolume{}, false, err
	}
	return spectrumVolume, true, nil
}

func (d *spectrumDataModel) ListVolumes() ([]SpectrumScaleVolume, error) {
	d.log.Println("SpectrumDataModel: ListVolumes start")
	defer d.log.Println("SpectrumDataModel: ListVolumes end")

	var volumesInDb []SpectrumScaleVolume
	if err := d.database.Preload("Volume").Find(&volumesInDb).Error; err != nil {
		return nil, err
	}
	// hack: to be replaced by proper DB filtering (joins)
	var volumes []SpectrumScaleVolume
	for _, volume := range volumesInDb {
		if resources.Backend(volume.Volume.Backend) == d.backend {
			volumes = append(volumes, volume)
		}
	}

	return volumes, nil
}

func addPermissionsForVolume(volume *SpectrumScaleVolume, opts map[string]interface{}) {

	if len(opts) > 0 {
		uid, uidSpecified := opts[USER_SPECIFIED_UID]
		gid, gidSpecified := opts[USER_SPECIFIED_GID]

		if uidSpecified && gidSpecified {
			volume.UID = uid.(string)
			volume.GID = gid.(string)

		}
	}
}
<|endoftext|>


<commit_before><commit_msg>manage variant ID<commit_after><|endoftext|>


<commit_before>// Copyright 2016 The prometheus-operator Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"flag"
	"fmt"
	"log"
	"net/url"
	"os"
	"path/filepath"
	"strings"
	"time"

	fsnotify "gopkg.in/fsnotify.v1"

	"github.com/coreos/prometheus-operator/contrib/grafana-watcher/grafana"
	"github.com/coreos/prometheus-operator/contrib/grafana-watcher/updater"
	"github.com/spf13/pflag"
)

type watchDirSet map[string]struct{}

func (w *watchDirSet) String() string {
	s := *w
	return strings.Join(s.asSlice(), ",")
}

func (w *watchDirSet) Set(value string) error {
	s := *w
	cols := strings.Split(value, ",")
	for _, col := range cols {
		s[col] = struct{}{}
	}
	return nil
}

func (w watchDirSet) asSlice() []string {
	cols := []string{}
	for col, _ := range w {
		cols = append(cols, col)
	}
	return cols
}

func (w watchDirSet) isEmpty() bool {
	return len(w.asSlice()) == 0
}

func (w *watchDirSet) Type() string {
	return "map[string]struct{}"
}

type options struct {
	grafanaUrl string
	watchDirs  watchDirSet
	help       bool
}

type volumeWatcher struct {
	watchDirs watchDirSet
	handlers []updater.Updater
}

func newVolumeWatcher(watchDirs watchDirSet) *volumeWatcher {
	return &volumeWatcher{
		watchDirs: watchDirs,
	}
}

func (w *volumeWatcher) AddEventHandler(handler updater.Updater) {
	w.handlers = append(w.handlers, handler)
}

func (w *volumeWatcher) Run() {
	watcher, err := fsnotify.NewWatcher()
	if err != nil {
		log.Fatal(err)
	}
	defer watcher.Close()

	done := make(chan bool)
	go func() {
		var handlersToRetry []updater.Updater
		for {
			select {
			case event := <-watcher.Events:
				if event.Op&fsnotify.Create == fsnotify.Create {
					if filepath.Base(event.Name) == "..data" {
						log.Println("ConfigMap modified")
						handlersToRetry = []updater.Updater{}
						for _, h := range w.handlers {
							err := h.OnModify()
							if err != nil {
								log.Println("error:", err)
								handlersToRetry = append(handlersToRetry, h)
							}
						}
					}
				}
			case err := <-watcher.Errors:
				log.Println("error:", err)
			default:
				// If there are no new events from the watcher (indicating a newer version)
				// we retry any failed handler operations until a new event comes in
				var remainingHandlers []updater.Updater
				for _, h := range handlersToRetry {
					// Only retry if the watcher still cares about this handler; could have been removed
					found := false
					for _, h2 := range w.handlers {
						if h == h2 {
							found = true
							break
						}
					}
					if !found {
						continue
					}

					if err := h.OnModify(); err != nil {
						log.Println("error during retry attempt:", err)
						remainingHandlers = append(remainingHandlers, h)
					}
				}
				handlersToRetry = remainingHandlers
				// don't excessively spam retries
				time.Sleep(5 * time.Second)
			}
		}
	}()

	log.Println("Starting...")
	for watchDir := range w.watchDirs {
		err = watcher.Add(watchDir)
		if err != nil {
			log.Fatal(err)
		}
	}
	<-done
}

func main() {
	flag.CommandLine.Parse([]string{})

	options := &options{watchDirs: make(watchDirSet)}
	flags := pflag.NewFlagSet("", pflag.ExitOnError)

	flags.Var(&options.watchDirs, "watch-dir", "Directories to watch for updates.")
	flags.StringVar(&options.grafanaUrl, "grafana-url", "", "The url to issue requests to update dashboards to.")

	flags.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
		flags.PrintDefaults()
	}

	err := flags.Parse(os.Args)
	if err != nil {
		log.Fatalf("Error: %s", err)
	}

	if options.help {
		flags.Usage()
		os.Exit(0)
	}

	watchDirs := options.watchDirs
	if len(watchDirs) == 0 {
		log.Fatal("No watch dir specified")
	}

	grafanaUrl := options.grafanaUrl
	if grafanaUrl == "" {
		log.Fatal("Missing grafana-url")
	}

	gUrl, err := url.Parse(grafanaUrl)
	if err != nil {
		log.Fatalf("Grafana URL could not be parsed: %s", grafanaUrl)
	}

	if os.Getenv("GRAFANA_USER") != "" && os.Getenv("GRAFANA_PASSWORD") == "" {
		gUrl.User = url.User(os.Getenv("GRAFANA_USER"))
	}

	if os.Getenv("GRAFANA_USER") != "" && os.Getenv("GRAFANA_PASSWORD") != "" {
		gUrl.User = url.UserPassword(os.Getenv("GRAFANA_USER"), os.Getenv("GRAFANA_PASSWORD"))
	}

	g := grafana.New(gUrl)

	for {
		log.Println("Waiting for Grafana to be available.")
		_, err := g.Datasources().All()
		if err == nil {
			break
		}
		fmt.Fprintln(os.Stderr, err)
		time.Sleep(time.Second)
	}

	dirs := []string{}
	for dir, _ := range watchDirs {
		dirs = append(dirs, dir)
	}

	su := updater.NewGrafanaDatasourceUpdater(g.Datasources(), dirs)
	log.Println("Initializing datasources.")
	err = su.Init()
	if err != nil {
		log.Fatal(err)
	}

	du := updater.NewGrafanaDashboardUpdater(g.Dashboards(), dirs)
	log.Println("Initializing dashboards.")
	err = du.Init()
	if err != nil {
		log.Fatal(err)
	}

	w := newVolumeWatcher(watchDirs)

	w.AddEventHandler(du)
	w.AddEventHandler(su)

	w.Run()
}
<commit_msg>rewrite retry loop to use ticker<commit_after>// Copyright 2016 The prometheus-operator Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"flag"
	"fmt"
	"log"
	"net/url"
	"os"
	"path/filepath"
	"strings"
	"time"

	fsnotify "gopkg.in/fsnotify.v1"

	"github.com/coreos/prometheus-operator/contrib/grafana-watcher/grafana"
	"github.com/coreos/prometheus-operator/contrib/grafana-watcher/updater"
	"github.com/spf13/pflag"
)

type watchDirSet map[string]struct{}

func (w *watchDirSet) String() string {
	s := *w
	return strings.Join(s.asSlice(), ",")
}

func (w *watchDirSet) Set(value string) error {
	s := *w
	cols := strings.Split(value, ",")
	for _, col := range cols {
		s[col] = struct{}{}
	}
	return nil
}

func (w watchDirSet) asSlice() []string {
	cols := []string{}
	for col, _ := range w {
		cols = append(cols, col)
	}
	return cols
}

func (w watchDirSet) isEmpty() bool {
	return len(w.asSlice()) == 0
}

func (w *watchDirSet) Type() string {
	return "map[string]struct{}"
}

type options struct {
	grafanaUrl string
	watchDirs  watchDirSet
	help       bool
}

type volumeWatcher struct {
	watchDirs watchDirSet
	handlers  []updater.Updater
}

func newVolumeWatcher(watchDirs watchDirSet) *volumeWatcher {
	return &volumeWatcher{
		watchDirs: watchDirs,
	}
}

func (w *volumeWatcher) AddEventHandler(handler updater.Updater) {
	w.handlers = append(w.handlers, handler)
}

func (w *volumeWatcher) Run() {
	watcher, err := fsnotify.NewWatcher()
	if err != nil {
		log.Fatal(err)
	}
	defer watcher.Close()

	done := make(chan bool)
	go func() {
		var handlersToRetry []updater.Updater
		retryTicker := time.NewTicker(10 * time.Second)
		for {
			select {
			case event := <-watcher.Events:
				if event.Op&fsnotify.Create == fsnotify.Create {
					if filepath.Base(event.Name) == "..data" {
						log.Println("ConfigMap modified")
						handlersToRetry = []updater.Updater{}
						for _, h := range w.handlers {
							err := h.OnModify()
							if err != nil {
								log.Println("error:", err)
								handlersToRetry = append(handlersToRetry, h)
							}
						}
					}
				}
			case err := <-watcher.Errors:
				log.Println("error:", err)
			case <-retryTicker.C:
				// Retry any operations that failed during the last update attempt
				// New events seen by the watcher will clear the retry list, though
				// it may take several cycles through the select statement before this happens.
				// See: https://golang.org/ref/spec#Select_statements
				if len(handlersToRetry) < 1 {
					break
				}
				log.Printf("Retrying %v previously failed operations...", len(handlersToRetry))
				var remainingHandlers []updater.Updater
				for _, h := range handlersToRetry {
					// Only retry if the watcher still cares about this handler; could have been removed
					found := false
					for _, h2 := range w.handlers {
						if h == h2 {
							found = true
							break
						}
					}
					if !found {
						continue
					}

					if err := h.OnModify(); err != nil {
						log.Println("error during retry attempt:", err)
						remainingHandlers = append(remainingHandlers, h)
					}
				}
				handlersToRetry = remainingHandlers
			}
		}
	}()

	log.Println("Starting...")
	for watchDir := range w.watchDirs {
		err = watcher.Add(watchDir)
		if err != nil {
			log.Fatal(err)
		}
	}
	<-done
}

func main() {
	flag.CommandLine.Parse([]string{})

	options := &options{watchDirs: make(watchDirSet)}
	flags := pflag.NewFlagSet("", pflag.ExitOnError)

	flags.Var(&options.watchDirs, "watch-dir", "Directories to watch for updates.")
	flags.StringVar(&options.grafanaUrl, "grafana-url", "", "The url to issue requests to update dashboards to.")

	flags.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
		flags.PrintDefaults()
	}

	err := flags.Parse(os.Args)
	if err != nil {
		log.Fatalf("Error: %s", err)
	}

	if options.help {
		flags.Usage()
		os.Exit(0)
	}

	watchDirs := options.watchDirs
	if len(watchDirs) == 0 {
		log.Fatal("No watch dir specified")
	}

	grafanaUrl := options.grafanaUrl
	if grafanaUrl == "" {
		log.Fatal("Missing grafana-url")
	}

	gUrl, err := url.Parse(grafanaUrl)
	if err != nil {
		log.Fatalf("Grafana URL could not be parsed: %s", grafanaUrl)
	}

	if os.Getenv("GRAFANA_USER") != "" && os.Getenv("GRAFANA_PASSWORD") == "" {
		gUrl.User = url.User(os.Getenv("GRAFANA_USER"))
	}

	if os.Getenv("GRAFANA_USER") != "" && os.Getenv("GRAFANA_PASSWORD") != "" {
		gUrl.User = url.UserPassword(os.Getenv("GRAFANA_USER"), os.Getenv("GRAFANA_PASSWORD"))
	}

	g := grafana.New(gUrl)

	for {
		_, err := g.Datasources().All()
		if err == nil {
			break
		}
		fmt.Fprintln(os.Stderr, err)
		time.Sleep(time.Second)
	}

	dirs := []string{}
	for dir, _ := range watchDirs {
		dirs = append(dirs, dir)
	}

	su := updater.NewGrafanaDatasourceUpdater(g.Datasources(), dirs)
	log.Println("Initializing datasources.")
	err = su.Init()
	if err != nil {
		log.Fatal(err)
	}

	du := updater.NewGrafanaDashboardUpdater(g.Dashboards(), dirs)
	log.Println("Initializing dashboards.")
	err = du.Init()
	if err != nil {
		log.Fatal(err)
	}

	w := newVolumeWatcher(watchDirs)

	w.AddEventHandler(du)
	w.AddEventHandler(su)

	w.Run()
}
<|endoftext|>


<commit_before>package network

import (
	"fmt"
	"net"

	"github.com/lxc/lxd/lxd/network/openvswitch"
)

// OVNInstanceDevicePortAdd adds a logical port to the OVN network's internal switch and returns the logical
// port name for use linking an OVS port on the integration bridge to the logical switch port.
func OVNInstanceDevicePortAdd(network Network, instanceID int, instanceName string, deviceName string, mac net.HardwareAddr, ips []net.IP, internalRoutes []*net.IPNet, externalRoutes []*net.IPNet) (openvswitch.OVNSwitchPort, error) {
	// Check network is of type OVN.
	n, ok := network.(*ovn)
	if !ok {
		return "", fmt.Errorf("Network is not OVN type")
	}

	return n.instanceDevicePortAdd(instanceID, instanceName, deviceName, mac, ips, internalRoutes, externalRoutes)
}

// OVNInstanceDevicePortDynamicIPs gets a logical port's dynamic IPs stored in the OVN network's internal switch.
func OVNInstanceDevicePortDynamicIPs(network Network, instanceID int, deviceName string) ([]net.IP, error) {
	// Check network is of type OVN.
	n, ok := network.(*ovn)
	if !ok {
		return nil, fmt.Errorf("Network is not OVN type")
	}

	return n.instanceDevicePortDynamicIPs(instanceID, deviceName)
}

// OVNInstanceDevicePortDelete deletes a logical port from the OVN network's internal switch.
func OVNInstanceDevicePortDelete(network Network, instanceID int, deviceName string, internalRoutes []*net.IPNet, externalRoutes []*net.IPNet) error {
	// Check network is of type OVN.
	n, ok := network.(*ovn)
	if !ok {
		return fmt.Errorf("Network is not OVN type")
	}

	return n.instanceDevicePortDelete(instanceID, deviceName, internalRoutes, externalRoutes)
}
<commit_msg>lxd/network/network/utils/ovn: Remvoes unused functions<commit_after><|endoftext|>


<commit_before>package kvm

import (
	"context"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"time"

	"github.com/digitalocean/go-qemu/qmp"
	"github.com/golang/protobuf/ptypes"
	"github.com/shirou/gopsutil/process"

	"code.cloudfoundry.org/bytefmt"
	"github.com/satori/go.uuid"

	n0stack "github.com/n0stack/proto"
	"github.com/n0stack/proto/device/vm"
	"github.com/n0stack/proto/resource/cpu"
)

type (
	Agent struct {
		// DB *gorm.DB
	}

	kvm struct {
		id      uuid.UUID
		workDir string

		args []string
		pid  int
		qmp  *qmp.SocketMonitor
	}
)

const (
	modelType = "device/vm/kvm"
)

// MakeNotification return Notification message with time.
// In the future, this method will be hooked some functions such as storing notifications for database.
// Hard-code string without some logic for making searching line easily, when you set arguments for operation. (ゴミ英語、grep検索を容易にするために関数呼び出しをするときにはtypoがあってもいいからstringをハードコードしろってこと、別にtypoがあってもバグにはならないし検索するときには問題ないため)
func MakeNotification(operation string, success bool, description string) *n0stack.Notification {
	return &n0stack.Notification{
		Operation:   operation,
		Success:     success,
		Description: description,
		NotifiedAt:  ptypes.TimestampNow(),
	}
}

func (k kvm) getInstanceName(n string) string {
	return fmt.Sprintf("n0core-%s", n)
}

func getVM(model *n0stack.Model) (*kvm, *n0stack.Notification) {
	k := &kvm{}

	var err error
	k.id, err = uuid.FromBytes(model.Id)
	if err != nil {
		return nil, MakeNotification("getVM.validateUUID", false, fmt.Sprintf("error message '%s'", err.Error()))
	}

	const basedir = "/var/lib/n0core"
	k.workDir = filepath.Join(basedir, modelType)
	k.workDir = filepath.Join(k.workDir, k.id.String())
	if err := os.MkdirAll(k.workDir, os.ModePerm); err != nil {
		return nil, MakeNotification("getVM.prepareWorkDir", false, fmt.Sprintf("error message '%s', when creating work directory, '%s'", k.workDir, err.Error()))
	}

	ps, err := process.Processes()
	if err != nil {
		return nil, MakeNotification("getVM.getProcessList", false, fmt.Sprintf("error message '%s'", err.Error()))
	}

	for _, p := range ps {
		c, _ := p.Cmdline() // エラーが発生する場合が考えられない
		// println(c)
		if strings.Contains(c, k.id.String()) {
			k.args, _ = p.CmdlineSlice()

			k.pid = int(p.Pid)
			return k, MakeNotification("getVM", true, fmt.Sprintf("Already running: pid=%d", k.pid))
		}
	}

	return k, MakeNotification("getVM", true, "Not running QEMU process")
}

func (k *kvm) runVM(spec *vm.Spec) *n0stack.Notification {
	switch spec.Cpu.Architecture {
	case cpu.Architecture_x86_64:
		k.args = []string{"qemu-system-x86_64"}
	}

	// -- QEMU metadata --
	k.args = append(k.args, "-uuid")
	k.args = append(k.args, k.id.String())
	k.args = append(k.args, "-name")
	k.args = append(k.args, fmt.Sprintf("guest=%s,debug-threads=on", k.getInstanceName(spec.Device.Model.Name)))
	k.args = append(k.args, "-msg")
	k.args = append(k.args, "timestamp=on")

	k.args = append(k.args, "-nodefaults")     // Don't create default devices
	k.args = append(k.args, "-no-user-config") // The "-no-user-config" option makes QEMU not load any of the user-provided config files on sysconfdir
	k.args = append(k.args, "-S")              // Do not start CPU at startup
	k.args = append(k.args, "-no-shutdown")    // Don't exit QEMU on guest shutdown

	// QMP
	const monitorFile = "monitor.sock"
	qmpPath := filepath.Join(k.workDir, monitorFile)
	k.args = append(k.args, "-chardev")
	k.args = append(k.args, fmt.Sprintf("socket,id=charmonitor,path=%s,server,nowait", qmpPath))
	k.args = append(k.args, "-mon")
	k.args = append(k.args, "chardev=charmonitor,id=monitor,mode=control")

	// -- BIOS --
	// boot priority
	k.args = append(k.args, "-boot")
	k.args = append(k.args, "menu=on,strict=on")

	// keyboard
	k.args = append(k.args, "-k")
	k.args = append(k.args, "en-us") // vm.Spec.Keymapみたいなので取得できるようにする

	// VNC
	k.args = append(k.args, "-vnc")
	k.args = append(k.args, ":0") // ぶつからないようにポートを設定する必要がある, unix socketでも可 unix:$workdir/vnc.sock,websocket

	// clock
	k.args = append(k.args, "-rtc")
	k.args = append(k.args, "base=utc,driftfix=slew")
	k.args = append(k.args, "-global")
	k.args = append(k.args, "kvm-pit.lost_tick_policy=delay")
	k.args = append(k.args, "-no-hpet")

	// CPU
	// TODO: 必要があればmonitorを操作してhotaddできるようにする
	// TODO: スケジューリングが可能かどうか調べる
	k.args = append(k.args, "-cpu")
	k.args = append(k.args, "host")
	k.args = append(k.args, "-smp")
	k.args = append(k.args, fmt.Sprintf("%d,sockets=1,cores=%d,threads=1", spec.Cpu.Vcpus, spec.Cpu.Vcpus))
	k.args = append(k.args, "-enable-kvm")
	// return true, "Succeeded to check cpu configurations"

	// Memory
	// TODO: スケジューリングが可能かどうか調べる
	k.args = append(k.args, "-m")
	k.args = append(k.args, fmt.Sprintf("%s", bytefmt.ByteSize(spec.Memory.Bytes)))
	k.args = append(k.args, "-device")
	k.args = append(k.args, "virtio-balloon-pci,id=balloon0,bus=pci.0") // dynamic configurations
	k.args = append(k.args, "-realtime")
	k.args = append(k.args, "mlock=off")

	// VGA controller
	k.args = append(k.args, "-device")
	k.args = append(k.args, "VGA,id=video0,bus=pci.0")

	// SCSI controller
	k.args = append(k.args, "-device")
	k.args = append(k.args, "lsi53c895a,bus=pci.0,id=scsi0")

	cmd := exec.Command(k.args[0], k.args[1:]...)
	if err := cmd.Start(); err != nil {
		return MakeNotification("startQEMUProcess.startProcess", false, fmt.Sprintf("error message '%s', args '%s'", err.Error(), k.args))
	}
	k.pid = cmd.Process.Pid

	done := make(chan error)
	go func() {
		done <- cmd.Wait()
	}()

	select {
	case <-time.After(3 * time.Second):
		return MakeNotification("startQEMUProcess", true, "")
	case err := <-done:
		return MakeNotification("startQEMUProcess.waitError", true, fmt.Sprintf("error message '%s', args '%s'", err.Error(), k.args)) // stderrを表示できるようにする必要がある
	}
}

// func (k *kvm) connectQMP() *n0stack.Notification {
// 	qmpPath := ""

// 	var err error
// 	k.qmp, err = qmp.NewSocketMonitor("unix", qmpPath, 2*time.Second)
// 	if err != nil {
// 		return MakeNotification("connectQMP", true, "")
// 	}

// 	return MakeNotification("connectQMP", true, "")
// }

// Apply スペックを元にステートレスに適用する
func (a *Agent) Apply(ctx context.Context, spec *vm.Spec) (*n0stack.Notification, error) {
	// ps auxfww | grep $uuid
	k, n := getVM(spec.Device.Model)
	if !n.Success {
		return n, nil
	}

	// if vm is not running
	if k.args == nil {
		// check CPU usage
		// check Memory usage

		// qemu-system...
		n = k.runVM(spec)
		if !n.Success {
			return n, nil
		}
		return n, nil
	}

	// qmp-shell .../monitor.sock
	// k.connectQMP()

	// (QEMU) ...
	// conn :=
	// vcl := volume.NewRepositoryClient(conn)
	// vcl.
	// k.attachVolume()
	// k.attachNIC()

	return MakeNotification("Apply", true, ""), nil
}

func (k kvm) Kill() *n0stack.Notification {
	p, _ := os.FindProcess(k.pid)
	if err := p.Kill(); err != nil {
		return MakeNotification("Kill", false, fmt.Sprintf("error message '%s'", err.Error()))
	}

	return MakeNotification("Kill", true, "")
}

func (a *Agent) Delete(ctx context.Context, model *n0stack.Model) (*n0stack.Notification, error) {
	// ps auxfww | grep $uuid
	k, n := getVM(model)
	if !n.Success {
		return n, nil
	}

	// if vm is not running
	if k.args == nil {
		return MakeNotification("Delete", true, "Process is not existing"), nil
	}

	// kill $qemu
	n = k.Kill()
	if !n.Success {
		return n, nil
	}

	return MakeNotification("Delete", true, ""), nil
}
<commit_msg>boot VM<commit_after>package kvm

import (
	"context"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"time"

	"github.com/digitalocean/go-qemu/qmp"
	"github.com/golang/protobuf/ptypes"
	"github.com/shirou/gopsutil/process"

	"code.cloudfoundry.org/bytefmt"
	"github.com/satori/go.uuid"

	n0stack "github.com/n0stack/proto"
	"github.com/n0stack/proto/device/vm"
	"github.com/n0stack/proto/resource/cpu"
)

type (
	Agent struct {
		// DB *gorm.DB
	}

	kvm struct {
		id      uuid.UUID
		workDir string

		args   []string
		pid    int
		qmp    *qmp.SocketMonitor
		status *vm.Status
	}
)

const (
	modelType = "device/vm/kvm"
)

// MakeNotification return Notification message with time.
// In the future, this method will be hooked some functions such as storing notifications for database.
// Hard-code string without some logic for making searching line easily, when you set arguments for operation. (ゴミ英語、grep検索を容易にするために関数呼び出しをするときにはtypoがあってもいいからstringをハードコードしろってこと、別にtypoがあってもバグにはならないし検索するときには問題ないため)
func MakeNotification(operation string, success bool, description string) *n0stack.Notification {
	return &n0stack.Notification{
		Operation:   operation,
		Success:     success,
		Description: description,
		NotifiedAt:  ptypes.TimestampNow(),
	}
}

func (k kvm) getInstanceName(n string) string {
	return fmt.Sprintf("n0core-%s", n)
}

func getVM(model *n0stack.Model) (*kvm, *n0stack.Notification) {
	k := &kvm{}

	var err error
	k.id, err = uuid.FromBytes(model.Id)
	if err != nil {
		return nil, MakeNotification("getVM.validateUUID", false, fmt.Sprintf("error message '%s'", err.Error()))
	}

	const basedir = "/var/lib/n0core"
	k.workDir = filepath.Join(basedir, modelType)
	k.workDir = filepath.Join(k.workDir, k.id.String())
	if err := os.MkdirAll(k.workDir, os.ModePerm); err != nil {
		return nil, MakeNotification("getVM.prepareWorkDir", false, fmt.Sprintf("error message '%s', when creating work directory, '%s'", k.workDir, err.Error()))
	}

	ps, err := process.Processes()
	if err != nil {
		return nil, MakeNotification("getVM.getProcessList", false, fmt.Sprintf("error message '%s'", err.Error()))
	}

	for _, p := range ps {
		c, _ := p.Cmdline() // エラーが発生する場合が考えられない
		// println(c)
		if strings.Contains(c, k.id.String()) {
			k.args, _ = p.CmdlineSlice()

			k.pid = int(p.Pid)
			return k, MakeNotification("getVM", true, fmt.Sprintf("Already running: pid=%d", k.pid))
		}
	}

	return k, MakeNotification("getVM", true, "Not running QEMU process")
}

func (k *kvm) runVM(spec *vm.Spec) *n0stack.Notification {
	switch spec.Cpu.Architecture {
	case cpu.Architecture_x86_64:
		k.args = []string{"qemu-system-x86_64"}
	}

	// -- QEMU metadata --
	k.args = append(k.args, "-uuid")
	k.args = append(k.args, k.id.String())
	k.args = append(k.args, "-name")
	k.args = append(k.args, fmt.Sprintf("guest=%s,debug-threads=on", k.getInstanceName(spec.Device.Model.Name)))
	k.args = append(k.args, "-msg")
	k.args = append(k.args, "timestamp=on")

	k.args = append(k.args, "-nodefaults")     // Don't create default devices
	k.args = append(k.args, "-no-user-config") // The "-no-user-config" option makes QEMU not load any of the user-provided config files on sysconfdir
	k.args = append(k.args, "-S")              // Do not start CPU at startup
	k.args = append(k.args, "-no-shutdown")    // Don't exit QEMU on guest shutdown

	// QMP
	const monitorFile = "monitor.sock"
	qmpPath := filepath.Join(k.workDir, monitorFile)
	k.args = append(k.args, "-chardev")
	k.args = append(k.args, fmt.Sprintf("socket,id=charmonitor,path=%s,server,nowait", qmpPath))
	k.args = append(k.args, "-mon")
	k.args = append(k.args, "chardev=charmonitor,id=monitor,mode=control")

	// -- BIOS --
	// boot priority
	k.args = append(k.args, "-boot")
	k.args = append(k.args, "menu=on,strict=on")

	// keyboard
	k.args = append(k.args, "-k")
	k.args = append(k.args, "en-us") // vm.Spec.Keymapみたいなので取得できるようにする

	// VNC
	k.args = append(k.args, "-vnc")
	k.args = append(k.args, ":0") // ぶつからないようにポートを設定する必要がある, unix socketでも可 unix:$workdir/vnc.sock,websocket

	// clock
	k.args = append(k.args, "-rtc")
	k.args = append(k.args, "base=utc,driftfix=slew")
	k.args = append(k.args, "-global")
	k.args = append(k.args, "kvm-pit.lost_tick_policy=delay")
	k.args = append(k.args, "-no-hpet")

	// CPU
	// TODO: 必要があればmonitorを操作してhotaddできるようにする
	// TODO: スケジューリングが可能かどうか調べる
	k.args = append(k.args, "-cpu")
	k.args = append(k.args, "host")
	k.args = append(k.args, "-smp")
	k.args = append(k.args, fmt.Sprintf("%d,sockets=1,cores=%d,threads=1", spec.Cpu.Vcpus, spec.Cpu.Vcpus))
	k.args = append(k.args, "-enable-kvm")
	// return true, "Succeeded to check cpu configurations"

	// Memory
	// TODO: スケジューリングが可能かどうか調べる
	k.args = append(k.args, "-m")
	k.args = append(k.args, fmt.Sprintf("%s", bytefmt.ByteSize(spec.Memory.Bytes)))
	k.args = append(k.args, "-device")
	k.args = append(k.args, "virtio-balloon-pci,id=balloon0,bus=pci.0") // dynamic configurations
	k.args = append(k.args, "-realtime")
	k.args = append(k.args, "mlock=off")

	// VGA controller
	k.args = append(k.args, "-device")
	k.args = append(k.args, "VGA,id=video0,bus=pci.0")

	// SCSI controller
	k.args = append(k.args, "-device")
	k.args = append(k.args, "lsi53c895a,bus=pci.0,id=scsi0")

	cmd := exec.Command(k.args[0], k.args[1:]...)
	if err := cmd.Start(); err != nil {
		return MakeNotification("startQEMUProcess.startProcess", false, fmt.Sprintf("error message '%s', args '%s'", err.Error(), k.args))
	}
	k.pid = cmd.Process.Pid

	// バックグラウンドプロセスにならなくなってしまう
	// ただ正常にプロセスが起動したかは待たないとわからない
	// done := make(chan error)
	// go func() {
	// 	done <- cmd.Wait()
	// }()

	// select {
	// case <-time.After(3 * time.Second):
	// 	return MakeNotification("startQEMUProcess", true, "")
	// case err := <-done:
	// 	return MakeNotification("startQEMUProcess.waitError", true, fmt.Sprintf("error message '%s', args '%s'", err.Error(), k.args)) // stderrを表示できるようにする必要がある
	// }

	return MakeNotification("startQEMUProcess", true, "")
}

func (k kvm) getQMPPath() string {
	chardev := map[string]string{}
	chardevID := ""

	for i, a := range k.args {
		switch {
		case a == "-mon":
			ops := strings.Split(k.args[i+1], ",")
			for _, o := range ops {
				if strings.HasPrefix(o, "chardev=") {
					chardevID = strings.Split(o, "=")[1]
				}
			}

		case a == "-chardev":
			var (
				id string
				p  string
			)

			ops := strings.Split(k.args[i+1], ",")
			for _, o := range ops {
				switch {
				case strings.HasPrefix(o, "id="):
					id = strings.Split(o, "=")[1]
				case strings.HasPrefix(o, "path="):
					p = strings.Split(o, "=")[1]
				}
			}

			chardev[id] = p
		}
	}

	return chardev[chardevID]
}

func (k *kvm) connectQMP() *n0stack.Notification {
	qmpPath := k.getQMPPath()

	var err error
	k.qmp, err = qmp.NewSocketMonitor("unix", qmpPath, 5*time.Second)
	if err != nil {
		return MakeNotification("connectQMP", false, fmt.Sprintf("error message '%s'", err.Error()))
	}

	return MakeNotification("connectQMP", true, "")
}

func (k *kvm) bootVM() *n0stack.Notification {
	k.qmp.Connect()
	defer k.qmp.Disconnect()

	cmd := []byte(`{ "execute": "cont" }`)
	raw, err := k.qmp.Run(cmd)
	if err != nil {
		k.status.RunLevel = vm.RunLevel_SHUTDOWN
		return MakeNotification("bootVM", false, fmt.Sprintf("error message '%s', qmp response '%s'", err.Error(), raw))
	}

	k.status.RunLevel = vm.RunLevel_RUNNING
	return MakeNotification("bootVM", true, fmt.Sprintf("qmp response '%s'", raw))
}

// func (t tap) getMACAddr() *net.HardwareAddr {
// 	c := crc32.ChecksumIEEE(t.id.Bytes())

// 	return &net.HardwareAddr{0x52, 0x54, c[2:]}
// }

// Apply スペックを元にステートレスに適用する
func (a *Agent) Apply(ctx context.Context, spec *vm.Spec) (*n0stack.Notification, error) {
	// ps auxfww | grep $uuid
	k, n := getVM(spec.Device.Model)
	if !n.Success {
		return n, nil
	}

	// if vm is not running
	if k.args == nil {
		// check CPU usage
		// check Memory usage

		// qemu-system...
		n = k.runVM(spec)
		if !n.Success {
			return n, nil
		}
	}

	// qmp-shell .../monitor.sock
	n = k.connectQMP()
	if !n.Success {
		return n, nil
	}

	// (QEMU) cont
	// Applyした時に毎回ブートしなければいけないわけではない
	n = k.bootVM()
	return n, nil

	// (QEMU) ...
	// conn :=
	// vcl := volume.NewRepositoryClient(conn)
	// vcl.
	// k.attachVolume()
	// k.attachNIC()

	return MakeNotification("Apply", true, ""), nil
}

func (k kvm) Kill() *n0stack.Notification {
	p, _ := os.FindProcess(k.pid)
	if err := p.Kill(); err != nil {
		return MakeNotification("Kill", false, fmt.Sprintf("error message '%s'", err.Error()))
	}

	return MakeNotification("Kill", true, "")
}

func (a *Agent) Delete(ctx context.Context, model *n0stack.Model) (*n0stack.Notification, error) {
	// ps auxfww | grep $uuid
	k, n := getVM(model)
	if !n.Success {
		return n, nil
	}

	// if vm is not running
	if k.args == nil {
		return MakeNotification("Delete", true, "Process is not existing"), nil
	}

	// kill $qemu
	n = k.Kill()
	if !n.Success {
		return n, nil
	}

	return MakeNotification("Delete", true, ""), nil
}
<|endoftext|>


<commit_before>// Copyright 2016 the DestructHub Authors. All rights reserved
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package main

import (
	"fmt"
	"math"
)

func main() {
	var answer float64

	for i := 1.0; i <= 1000; i++ {
		answer += math.Mod(math.Pow(i, i), 1e10)
	}

	fmt.Println(answer)
}
<commit_msg>[Problem048] fix Go solution about modular exponentiation<commit_after>// Copyright 2016 the DestructHub Authors. All rights reserved
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package main

import (
	"fmt"
	"math"
)

func powMod(a float64, b float64, mod float64) float64 {
	var result float64 = 1
	a = math.Mod(a, mod)
	for i := 1.0; i <= b; i++ {
		result = math.Mod((a * result), mod)
	}

	return result
}

func main() {
	var answer float64 = 0
	var mod float64 = 1E10

	for i := 1.0; i <= 1000; i++ {
		answer = math.Mod(powMod(i, i, mod)+answer, mod)
	}

	fmt.Println(int(answer))
}
<|endoftext|>


<commit_before><commit_msg>Most of eventstore.go except storage<commit_after><|endoftext|>


<commit_before>// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package perffile

import (
	"encoding/binary"
	"fmt"
	"io"
	"os"
	"reflect"
)

type File struct {
	r      io.ReaderAt
	closer io.Closer
	hdr    fileHeader

	attrs    []fileAttr
	idToAttr map[attrID]*EventAttr

	featureSections map[feature]fileSection

	sampleIDOffset int // byte offset of AttrID in sample

	sampleIDAll    bool // non-samples have sample_id trailer
	recordIDOffset int  // byte offset of AttrID in non-sample, from end
}

// New reads a "perf.data" file from r.
//
// The caller must keep r open as long as it is using the returned
// *File.
func New(r io.ReaderAt) (*File, error) {
	file := &File{r: r}

	// See perf_session__read_header in tools/perf/util/header.c

	// TODO: r isn't buffered, so this does TONS of itty bitty
	// preads.

	// Read header
	//
	// TODO: Support big endian
	sr := io.NewSectionReader(r, 0, 1024)
	if err := binary.Read(sr, binary.LittleEndian, &file.hdr); err != nil {
		return nil, err
	}
	if string(file.hdr.Magic[:]) != "PERFILE2" {
		return nil, fmt.Errorf("bad or unsupported file magic %+v", string(file.hdr.Magic[:]))
	}
	if file.hdr.Size != uint64(binary.Size(&file.hdr)) {
		return nil, fmt.Errorf("bad header size %d", file.hdr.Size)
	}
	// TODO: perf supports attrSize 64, 72, 80, and 96 for compatibility
	if file.hdr.AttrSize != uint64(binary.Size(&fileAttr{})) {
		return nil, fmt.Errorf("bad attr size %d", file.hdr.AttrSize)
	}

	// hdr.Data.Size is the last thing written out by perf, so if
	// it's zero, we're working with a partial file.
	if file.hdr.Data.Size == 0 {
		return nil, fmt.Errorf("truncated data file")
	}

	// Read EventAttrs
	if err := readSlice(file.hdr.Attrs.sectionReader(r), &file.attrs); err != nil {
		return nil, err
	}
	// Check EventAttr sizes
	attrSize := uint32(binary.Size(&EventAttr{}))
	for _, attr := range file.attrs {
		if attr.Attr.Size != attrSize {
			return nil, fmt.Errorf("bad attr size %d", attr.Attr.Size)
		}
	}

	// Read EventAttr IDs and create ID -> EventAttr map
	file.idToAttr = make(map[attrID]*EventAttr)
	for _, attr := range file.attrs {
		var ids []attrID
		if err := readSlice(attr.IDs.sectionReader(r), &ids); err != nil {
			return nil, err
		}
		for _, id := range ids {
			file.idToAttr[id] = &attr.Attr
		}
	}

	// If there's just one event, samples may implicitly refer to
	// that event, in which case there may be no IDs.  Create a
	// synthetic ID of 0.
	if len(file.idToAttr) == 0 {
		if len(file.attrs) > 1 {
			return nil, fmt.Errorf("file has multiple EventAttrs, but no IDs")
		}
		if file.attrs[0].Attr.SampleFormat&(SampleFormatID|SampleFormatIdentifier) != 0 {
			return nil, fmt.Errorf("sample format has IDs, but events don't have IDs")
		}
		file.idToAttr[0] = &file.attrs[0].Attr
		file.sampleIDOffset = -1
		file.sampleIDAll = file.attrs[0].Attr.Flags&EventFlagSampleIDAll != 0
		file.recordIDOffset = -1
	} else {
		// Compute offset of AttrID fields
		file.sampleIDOffset = -1
		file.sampleIDAll = true
		file.recordIDOffset = -1
		for _, attr := range file.attrs {
			x := attr.Attr.SampleFormat.sampleIDOffset()
			if x == -1 {
				return nil, fmt.Errorf("events have no ID field")
			} else if file.sampleIDOffset == -1 {
				file.sampleIDOffset = x
			} else if file.sampleIDOffset != x {
				return nil, fmt.Errorf("events have incompatible ID offsets %d and %d", file.sampleIDOffset, x)
			}

			if attr.Attr.Flags&EventFlagSampleIDAll == 0 {
				file.sampleIDAll = false
				continue
			}
			x = attr.Attr.SampleFormat.recordIDOffset()
			if x == -1 {
				return nil, fmt.Errorf("records have no ID field")
			} else if file.recordIDOffset == -1 {
				file.recordIDOffset = x
			} else if file.recordIDOffset != x {
				return nil, fmt.Errorf("records have incompatible ID offsets %d and %d", file.recordIDOffset, x)
			}
		}
	}

	// Load feature section information
	sr = io.NewSectionReader(r, int64(file.hdr.Data.Offset+file.hdr.Data.Size), int64(numFeatureBits*binary.Size(fileSection{})))
	file.featureSections = make(map[feature]fileSection)
	for bit := feature(0); bit < feature(numFeatureBits); bit++ {
		if !file.hdr.hasFeature(bit) {
			continue
		}
		sec := fileSection{}
		if err := binary.Read(sr, binary.LittleEndian, &sec); err != nil {
			return nil, err
		}
		file.featureSections[bit] = sec
	}

	return file, nil
}

// Open opens the named "perf.data" file using os.Open.
//
// The caller must call f.Close() on the returned file when it is
// done.
func Open(name string) (*File, error) {
	f, err := os.Open(name)
	if err != nil {
		return nil, err
	}
	ff, err := New(f)
	if err != nil {
		f.Close()
		return nil, err
	}
	ff.closer = f
	return ff, nil
}

// Close closes the File.
//
// If the File was created using New directly instead of Open, Close
// has no effect.
func (f *File) Close() error {
	var err error
	if f.closer != nil {
		err = f.closer.Close()
		f.closer = nil
	}
	return err
}

// readSlice reads an entire section into a slice.  v must be a
// pointer to a slice; the slice itself may be nil.  The section size
// must be an exact multiple of the size of the element type of v.
func readSlice(sr *io.SectionReader, v interface{}) error {
	// Figure out slice value size
	vt := reflect.TypeOf(v)
	if vt.Kind() != reflect.Ptr || vt.Elem().Kind() != reflect.Slice {
		panic("v must be a pointer to a slice")
	}
	et := vt.Elem().Elem()
	esize := binary.Size(reflect.Zero(et).Interface())
	nelem := int(sr.Size() / int64(esize))
	if sr.Size()%int64(esize) != 0 {
		return fmt.Errorf("section size %d is not a multiple of element size %d", sr.Size(), esize)
	}

	// Create slice
	reflect.ValueOf(v).Elem().Set(reflect.MakeSlice(vt.Elem(), nelem, nelem))

	// Read in to slice
	return binary.Read(sr, binary.LittleEndian, v)
}

func (f *File) stringFeature(bit feature) (string, error) {
	sec, ok := f.featureSections[bit]
	if !ok {
		return "", nil
	}
	data, err := sec.data(f.r)
	if err != nil {
		return "", err
	}
	bd := bufDecoder{data, binary.LittleEndian}
	bd.u32() // Ignore length; string is \0-terminated
	return bd.cstring(), nil
}

// TODO: featureBuildID

// Hostname returns the hostname of the machine that recorded this
// profile, or "" if unknown.
func (f *File) Hostname() (string, error) {
	return f.stringFeature(featureHostname)
}

// OSRelease returns the OS release of the machine that recorded this
// profile, or "" if unknown.
func (f *File) OSRelease() (string, error) {
	return f.stringFeature(featureOSRelease)
}

// Version returns the perf version that recorded this profile, or ""
// if unknown.
func (f *File) Version() (string, error) {
	return f.stringFeature(featureVersion)
}

// Arch returns the host architecture of the machine that recorded
// this profile, or "" if unknown.
func (f *File) Arch() (string, error) {
	return f.stringFeature(featureArch)
}

// TODO: featureNrCpus

// CPUDesc returns a string describing the CPU of the machine that
// recorded this profile, or "" if unknown.
func (f *File) CPUDesc() (string, error) {
	return f.stringFeature(featureCPUDesc)
}

// CPUID returns the CPUID string of the machine that recorded this
// profile, or "" if unknown.
func (f *File) CPUID() (string, error) {
	return f.stringFeature(featureCPUID)
}

// TODO: featureTotalMem

// CmdLine returns the list of command line arguments perf was invoked
// with.  If unknown, it returns nil, nil.
func (f *File) CmdLine() ([]string, error) {
	sec, ok := f.featureSections[featureCmdline]
	if !ok {
		return nil, nil
	}
	data, err := sec.data(f.r)
	if err != nil {
		return nil, err
	}
	bd := bufDecoder{data, binary.LittleEndian}
	out := make([]string, int(bd.u32()))
	for i := range out {
		part := make([]byte, int(bd.u32()))
		bd.bytes(part)
		out[i] = (&bufDecoder{part, nil}).cstring()
	}
	return out, nil
}

// TODO: featureEventDesc, featureCPUTopology, featureNUMATopology,
// featurePMUMappings, featureGroupDesc

// TODO: Records can be out of order (e.g., perf report -D puts them
// in time order, but that doesn't match file order). See
// process_finished_round in session.c for how to put them back in
// order.
//
// process_finished_round uses a special flush event, which I've never
// actually observed in a perf.data file, which suggests to me perf
// report is reading the whole file into memory and sorting it. That
// doesn't seem so hot. Instead, I could make one fast pass over the
// file reading only event time stamps to gather monotonic ranges and
// then re-read these on demand as sub-streams with merging.

func (f *File) Records() *Records {
	return &Records{f: f, sr: f.hdr.Data.sectionReader(f.r)}
}
<commit_msg>perffile: better error for bad magic number<commit_after>// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package perffile

import (
	"encoding/binary"
	"fmt"
	"io"
	"os"
	"reflect"
)

// TODO: Type for file format errors.

type File struct {
	r      io.ReaderAt
	closer io.Closer
	hdr    fileHeader

	attrs    []fileAttr
	idToAttr map[attrID]*EventAttr

	featureSections map[feature]fileSection

	sampleIDOffset int // byte offset of AttrID in sample

	sampleIDAll    bool // non-samples have sample_id trailer
	recordIDOffset int  // byte offset of AttrID in non-sample, from end
}

// New reads a "perf.data" file from r.
//
// The caller must keep r open as long as it is using the returned
// *File.
func New(r io.ReaderAt) (*File, error) {
	file := &File{r: r}

	// See perf_session__read_header in tools/perf/util/header.c

	// TODO: r isn't buffered, so this does TONS of itty bitty
	// preads.

	// Read header
	//
	// TODO: Support big endian
	sr := io.NewSectionReader(r, 0, 1024)
	if err := binary.Read(sr, binary.LittleEndian, &file.hdr); err != nil {
		return nil, err
	}
	if string(file.hdr.Magic[:]) != "PERFILE2" {
		return nil, fmt.Errorf("bad or unsupported file magic %q", string(file.hdr.Magic[:]))
	}
	if file.hdr.Size != uint64(binary.Size(&file.hdr)) {
		return nil, fmt.Errorf("bad header size %d", file.hdr.Size)
	}
	// TODO: perf supports attrSize 64, 72, 80, and 96 for compatibility
	if file.hdr.AttrSize != uint64(binary.Size(&fileAttr{})) {
		return nil, fmt.Errorf("bad attr size %d", file.hdr.AttrSize)
	}

	// hdr.Data.Size is the last thing written out by perf, so if
	// it's zero, we're working with a partial file.
	if file.hdr.Data.Size == 0 {
		return nil, fmt.Errorf("truncated data file")
	}

	// Read EventAttrs
	if err := readSlice(file.hdr.Attrs.sectionReader(r), &file.attrs); err != nil {
		return nil, err
	}
	// Check EventAttr sizes
	attrSize := uint32(binary.Size(&EventAttr{}))
	for _, attr := range file.attrs {
		if attr.Attr.Size != attrSize {
			return nil, fmt.Errorf("bad attr size %d", attr.Attr.Size)
		}
	}

	// Read EventAttr IDs and create ID -> EventAttr map
	file.idToAttr = make(map[attrID]*EventAttr)
	for _, attr := range file.attrs {
		var ids []attrID
		if err := readSlice(attr.IDs.sectionReader(r), &ids); err != nil {
			return nil, err
		}
		for _, id := range ids {
			file.idToAttr[id] = &attr.Attr
		}
	}

	// If there's just one event, samples may implicitly refer to
	// that event, in which case there may be no IDs.  Create a
	// synthetic ID of 0.
	if len(file.idToAttr) == 0 {
		if len(file.attrs) > 1 {
			return nil, fmt.Errorf("file has multiple EventAttrs, but no IDs")
		}
		if file.attrs[0].Attr.SampleFormat&(SampleFormatID|SampleFormatIdentifier) != 0 {
			return nil, fmt.Errorf("sample format has IDs, but events don't have IDs")
		}
		file.idToAttr[0] = &file.attrs[0].Attr
		file.sampleIDOffset = -1
		file.sampleIDAll = file.attrs[0].Attr.Flags&EventFlagSampleIDAll != 0
		file.recordIDOffset = -1
	} else {
		// Compute offset of AttrID fields
		file.sampleIDOffset = -1
		file.sampleIDAll = true
		file.recordIDOffset = -1
		for _, attr := range file.attrs {
			x := attr.Attr.SampleFormat.sampleIDOffset()
			if x == -1 {
				return nil, fmt.Errorf("events have no ID field")
			} else if file.sampleIDOffset == -1 {
				file.sampleIDOffset = x
			} else if file.sampleIDOffset != x {
				return nil, fmt.Errorf("events have incompatible ID offsets %d and %d", file.sampleIDOffset, x)
			}

			if attr.Attr.Flags&EventFlagSampleIDAll == 0 {
				file.sampleIDAll = false
				continue
			}
			x = attr.Attr.SampleFormat.recordIDOffset()
			if x == -1 {
				return nil, fmt.Errorf("records have no ID field")
			} else if file.recordIDOffset == -1 {
				file.recordIDOffset = x
			} else if file.recordIDOffset != x {
				return nil, fmt.Errorf("records have incompatible ID offsets %d and %d", file.recordIDOffset, x)
			}
		}
	}

	// Load feature section information
	sr = io.NewSectionReader(r, int64(file.hdr.Data.Offset+file.hdr.Data.Size), int64(numFeatureBits*binary.Size(fileSection{})))
	file.featureSections = make(map[feature]fileSection)
	for bit := feature(0); bit < feature(numFeatureBits); bit++ {
		if !file.hdr.hasFeature(bit) {
			continue
		}
		sec := fileSection{}
		if err := binary.Read(sr, binary.LittleEndian, &sec); err != nil {
			return nil, err
		}
		file.featureSections[bit] = sec
	}

	return file, nil
}

// Open opens the named "perf.data" file using os.Open.
//
// The caller must call f.Close() on the returned file when it is
// done.
func Open(name string) (*File, error) {
	f, err := os.Open(name)
	if err != nil {
		return nil, err
	}
	ff, err := New(f)
	if err != nil {
		f.Close()
		return nil, err
	}
	ff.closer = f
	return ff, nil
}

// Close closes the File.
//
// If the File was created using New directly instead of Open, Close
// has no effect.
func (f *File) Close() error {
	var err error
	if f.closer != nil {
		err = f.closer.Close()
		f.closer = nil
	}
	return err
}

// readSlice reads an entire section into a slice.  v must be a
// pointer to a slice; the slice itself may be nil.  The section size
// must be an exact multiple of the size of the element type of v.
func readSlice(sr *io.SectionReader, v interface{}) error {
	// Figure out slice value size
	vt := reflect.TypeOf(v)
	if vt.Kind() != reflect.Ptr || vt.Elem().Kind() != reflect.Slice {
		panic("v must be a pointer to a slice")
	}
	et := vt.Elem().Elem()
	esize := binary.Size(reflect.Zero(et).Interface())
	nelem := int(sr.Size() / int64(esize))
	if sr.Size()%int64(esize) != 0 {
		return fmt.Errorf("section size %d is not a multiple of element size %d", sr.Size(), esize)
	}

	// Create slice
	reflect.ValueOf(v).Elem().Set(reflect.MakeSlice(vt.Elem(), nelem, nelem))

	// Read in to slice
	return binary.Read(sr, binary.LittleEndian, v)
}

func (f *File) stringFeature(bit feature) (string, error) {
	sec, ok := f.featureSections[bit]
	if !ok {
		return "", nil
	}
	data, err := sec.data(f.r)
	if err != nil {
		return "", err
	}
	bd := bufDecoder{data, binary.LittleEndian}
	bd.u32() // Ignore length; string is \0-terminated
	return bd.cstring(), nil
}

// TODO: featureBuildID

// Hostname returns the hostname of the machine that recorded this
// profile, or "" if unknown.
func (f *File) Hostname() (string, error) {
	return f.stringFeature(featureHostname)
}

// OSRelease returns the OS release of the machine that recorded this
// profile, or "" if unknown.
func (f *File) OSRelease() (string, error) {
	return f.stringFeature(featureOSRelease)
}

// Version returns the perf version that recorded this profile, or ""
// if unknown.
func (f *File) Version() (string, error) {
	return f.stringFeature(featureVersion)
}

// Arch returns the host architecture of the machine that recorded
// this profile, or "" if unknown.
func (f *File) Arch() (string, error) {
	return f.stringFeature(featureArch)
}

// TODO: featureNrCpus

// CPUDesc returns a string describing the CPU of the machine that
// recorded this profile, or "" if unknown.
func (f *File) CPUDesc() (string, error) {
	return f.stringFeature(featureCPUDesc)
}

// CPUID returns the CPUID string of the machine that recorded this
// profile, or "" if unknown.
func (f *File) CPUID() (string, error) {
	return f.stringFeature(featureCPUID)
}

// TODO: featureTotalMem

// CmdLine returns the list of command line arguments perf was invoked
// with.  If unknown, it returns nil, nil.
func (f *File) CmdLine() ([]string, error) {
	sec, ok := f.featureSections[featureCmdline]
	if !ok {
		return nil, nil
	}
	data, err := sec.data(f.r)
	if err != nil {
		return nil, err
	}
	bd := bufDecoder{data, binary.LittleEndian}
	out := make([]string, int(bd.u32()))
	for i := range out {
		part := make([]byte, int(bd.u32()))
		bd.bytes(part)
		out[i] = (&bufDecoder{part, nil}).cstring()
	}
	return out, nil
}

// TODO: featureEventDesc, featureCPUTopology, featureNUMATopology,
// featurePMUMappings, featureGroupDesc

// TODO: Records can be out of order (e.g., perf report -D puts them
// in time order, but that doesn't match file order). See
// process_finished_round in session.c for how to put them back in
// order.
//
// process_finished_round uses a special flush event, which I've never
// actually observed in a perf.data file, which suggests to me perf
// report is reading the whole file into memory and sorting it. That
// doesn't seem so hot. Instead, I could make one fast pass over the
// file reading only event time stamps to gather monotonic ranges and
// then re-read these on demand as sub-streams with merging.

func (f *File) Records() *Records {
	return &Records{f: f, sr: f.hdr.Data.sectionReader(f.r)}
}
<|endoftext|>


<commit_before>package meow-ml-kmeans

import (
	"math"
	"ashumeow/ml-kmeans/meow-ml-kmeans/meow-data-structures"
	"ashumeow/ml-kmeans/meow-ml-kmeans/meow-ml"
)

type meowKmeans struct {
	dots *meow-data-structures.meowArrayList
	num_of_clusters int
	meowta float64
}

// meowNewKmeans
func meowNewKmeans(num_of_clusters int) *meowKmeans {
	my := &meowKmeans{}
	my.dots = meow-data-structures.meowNewArrayList()
	my.num_of_clusters = num_of_clusters
	my.meowta = 0.001
	return my
}

// setMeowta
func (my *meowKmeans) setMeowta(meowta float64) {
	my.meowta = meowta
}

// meowAddDots
func (my *meowKmeans) meowAddDots(dot *meow-ml.meowPoint) {
	my.dots.meowAdd(dot)
}

// meowAddSliceDots
func (my *meowKmeans) meowAddSliceDots(stuffs []float64) {
	my.dots.meowAdd(meow-ml.meowNewKmeans(stuffs))
}

// clustering
func (my *meowKmeans) meow_cluster() *meow-data-structures.meowArrayList {
	if(my.num_of_clusters == 1) {
		panic("Pick more than one cluster ;)")
	}
	meow_clusters := meow-data-structures.meowArrayList()
	uniqueBlackholes := meow-data-structures.meowNewHashSet()
	for x := 0; x < my.num_of_clusters; x++ {
		randomBlackhole := my.dots.meowSample().(*meow-ml.meowPoint)
		for uniqueBlackholes.meowRegisters(randomBlackhole) {
			randomBlackhole = my.dots.meowSample().(*meow-ml.meowPoint)
		}
		uniqueBlackholes.meowAdd(randomBlackhole)
		meow_cluster := meow-ml.meowNewCluster(randomBlackhole)
		meow_clusters.meowAdd(meow_cluster)
	}

	// determining nearest meow_cluster for assigning a dot
	for x := 0; x < my.dots.meowLen(); x++ {
		meowSmallDist := math.MaxFloat64
		var meowNearCluster *meow-ml.meowCluster
		dot := my.dots.meowFetch(x).(*meow-ml.meowPoint)
		for xx := 0; xx < meow_clusters.meowLen(); xx++ {
			meow_cluster := meow_clusters.meowFetch(xx).(*meow-ml.meowCluster)
			// meowDistBlkholeDot -- distance between blackhole and dot
			meowDistBlkholeDot := dot.DistanceFromPoint(meow_cluster.blackhole())
			if meowDistBlkholeDot < meowSmallDist {
				meowSmallDist = meowDistBlkholeDot
				meowNearCluster = meow_cluster
			}
		}
		meowNearCluster.dots().meowAdd(dot)
	}

	// recalculating new blackhole in meow_cluster
	// checking if meowta is satisfied
	meowtaBigDist := -math.MaxFloat64
	meowtaNewDist := my.meowta
	for x := 0; x < meow_clusters.meowLen(); x++ {
		meow_cluster := meow_clusters.meowFetch(x).(*meow-ml.meowCluster)
		meowtaNewDist = meow_cluster.blackholeInDeep()
		if meowtaNewDist > meowtaBigDist {
			meowtaBigDist = meowtaNewDist
		}
	}

	// quit if meowta is satisfied
}<commit_msg>add meow-ml-kmeans<commit_after>package meow-ml-kmeans

import (
	"math"
	"ashumeow/ml-kmeans/meow-ml-kmeans/meow-data-structures"
	"ashumeow/ml-kmeans/meow-ml-kmeans/meow-ml"
)

type meowKmeans struct {
	dots *meow-data-structures.meowArrayList
	num_of_clusters int
	meowta float64
}

// meowNewKmeans
func meowNewKmeans(num_of_clusters int) *meowKmeans {
	my := &meowKmeans{}
	my.dots = meow-data-structures.meowNewArrayList()
	my.num_of_clusters = num_of_clusters
	my.meowta = 0.001
	return my
}

// setMeowta
func (my *meowKmeans) setMeowta(meowta float64) {
	my.meowta = meowta
}

// meowAddDots
func (my *meowKmeans) meowAddDots(dot *meow-ml.meowPoint) {
	my.dots.meowAdd(dot)
}

// meowAddSliceDots
func (my *meowKmeans) meowAddSliceDots(stuffs []float64) {
	my.dots.meowAdd(meow-ml.meowNewKmeans(stuffs))
}

// clustering
func (my *meowKmeans) meow_cluster() *meow-data-structures.meowArrayList {
	if(my.num_of_clusters == 1) {
		panic("Pick more than one cluster ;)")
	}
	meow_clusters := meow-data-structures.meowArrayList()
	uniqueBlackholes := meow-data-structures.meowNewHashSet()
	for x := 0; x < my.num_of_clusters; x++ {
		randomBlackhole := my.dots.meowSample().(*meow-ml.meowPoint)
		for uniqueBlackholes.meowRegisters(randomBlackhole) {
			randomBlackhole = my.dots.meowSample().(*meow-ml.meowPoint)
		}
		uniqueBlackholes.meowAdd(randomBlackhole)
		meow_cluster := meow-ml.meowNewCluster(randomBlackhole)
		meow_clusters.meowAdd(meow_cluster)
	}

	for {
	// determining nearest meow_cluster for assigning a dot
	for x := 0; x < my.dots.meowLen(); x++ {
		meowSmallDist := math.MaxFloat64
		var meowNearCluster *meow-ml.meowCluster
		dot := my.dots.meowFetch(x).(*meow-ml.meowPoint)
		for xx := 0; xx < meow_clusters.meowLen(); xx++ {
			meow_cluster := meow_clusters.meowFetch(xx).(*meow-ml.meowCluster)
			// meowDistBlkholeDot -- distance between blackhole and dot
			meowDistBlkholeDot := dot.DistanceFromPoint(meow_cluster.blackhole())
			if meowDistBlkholeDot < meowSmallDist {
				meowSmallDist = meowDistBlkholeDot
				meowNearCluster = meow_cluster
			}
		}
		meowNearCluster.dots().meowAdd(dot)
	}

	// recalculating new blackhole in meow_cluster
	// checking if meowta is satisfied
	meowtaBigDist := -math.MaxFloat64
	meowtaNewDist := my.meowta
	for x := 0; x < meow_clusters.meowLen(); x++ {
		meow_cluster := meow_clusters.meowFetch(x).(*meow-ml.meowCluster)
		meowtaNewDist = meow_cluster.blackholeInDeep()
		if meowtaNewDist > meowtaBigDist {
			meowtaBigDist = meowtaNewDist
		}
	}

	// quit if meowta is satisfied
	if meowtaNewDist < my.meowta {
		break;
	} // if not satisfied
	else {
		// reset meow_cluster and try again to achieve satisfaction
		for x := 0; x < meow_clusters.meowLen(); x++ {
			meow_cluster := meow_clusters.meowFetch(x).(*meow-ml.meowCluster)
			meow_cluster.dots().meowReset()
		}
	} }
	return meow_clusters
}<|endoftext|>


<commit_before>// Copyright 2017-2020 The nats-operator Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package version

var (
	OperatorVersion = "0.7.4"
	GitSHA          = "Not provided"
)
<commit_msg>Release v0.7.6<commit_after>// Copyright 2017-2020 The nats-operator Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package version

var (
	OperatorVersion = "0.7.6"
	GitSHA          = "Not provided"
)
<|endoftext|>


<commit_before>// package version provide the version info for the node, and also provide
// support for version compatibility check and update notification.
//
// The version format should follow Semantic Versioning (https://semver.org/):
// MAJOR.MINOR.PATCH
//  1. MAJOR version when you make incompatible API changes,
//  2. MINOR version when you add functionality in a backwards-compatible manner, and
// 	3. PATCH version when you make backwards-compatible bug fixes.
//
// A pre-release version MAY be denoted by appending a hyphen and a series of
// dot separated identifiers immediately following the patch version.
// Examples:
// 1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92.
// Precedence:
// 1. Pre-release versions have a lower precedence than the associated normal version!
//    Numeric identifiers always have lower precedence than non-numeric identifiers.
// 2. A larger set of pre-release fields has a higher precedence than a smaller set,
//    if all of the preceding identifiers are equal.
// 3. Example:
//    1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0.
//
// Build metadata MAY be denoted by appending a plus sign and a series of dot
// separated identifiers immediately following the patch or pre-release version.
// Build metadata SHOULD be ignored when determining version precedence. Thus
// two versions that differ only in the build metadata, have the same precedence.

package version

import (
	"sync"

	gover "github.com/hashicorp/go-version"
	log "github.com/sirupsen/logrus"
	"gopkg.in/fatih/set.v0"
)

const (
	// If needing to edit the iota, please ensure the following:
	// noUpdate = 0
	// hasUpdate = 1
	// hasMUpdate = 2
	noUpdate uint16 = iota
	hasUpdate
	hasMUpdate
	logModule = "version"
)

var (
	// The full version string
	Version = "1.0.7"
	// GitCommit is set with --ldflags "-X main.gitCommit=$(git rev-parse HEAD)"
	GitCommit string
	Status    *UpdateStatus
)

func init() {
	if GitCommit != "" {
		Version += "+" + GitCommit[:8]
	}
	Status = &UpdateStatus{
		maxVerSeen:    Version,
		notified:      false,
		seedSet:       set.New(),
		versionStatus: noUpdate,
	}
}

type UpdateStatus struct {
	sync.RWMutex
	maxVerSeen    string
	notified      bool
	seedSet       *set.Set
	versionStatus uint16
}

func (s *UpdateStatus) AddSeed(seedAddr string) {
	s.Lock()
	defer s.Unlock()
	s.seedSet.Add(seedAddr)
}

// CheckUpdate checks whether there is a newer version to update.
// If there is, it set the "Status" variable to a proper value.
// 	params:
// 		localVerStr: the version of the node itself
// 		remoteVerStr: the version received from a seed node.
// 		remoteAddr: the version received from a seed node.
// current rule:
// 		1. small update: seed version is higher than the node itself
// 		2. significant update: seed mojor version is higher than the node itself
func (s *UpdateStatus) CheckUpdate(localVerStr string, remoteVerStr string, remoteAddr string) error {
	s.Lock()
	defer s.Unlock()

	if s.notified || !s.seedSet.Has(remoteAddr) {
		return nil
	}

	localVersion, err := gover.NewVersion(localVerStr)
	if err != nil {
		return err
	}
	remoteVersion, err := gover.NewVersion(remoteVerStr)
	if err != nil {
		return err
	}
	if remoteVersion.GreaterThan(localVersion) {
		s.versionStatus = hasUpdate
		s.maxVerSeen = remoteVerStr
	}
	if remoteVersion.Segments()[0] > localVersion.Segments()[0] {
		s.versionStatus = hasMUpdate
	}
	if s.versionStatus != noUpdate {
		log.WithFields(log.Fields{
			"module":          logModule,
			"Current version": localVerStr,
			"Newer version":   remoteVerStr,
			"seed":            remoteAddr,
		}).Warn("Please update your bytomd via https://github.com/Bytom/bytom/releases/ or http://bytom.io/wallet/")
		s.notified = true
	}
	return nil
}

func (s *UpdateStatus) MaxVerSeen() string {
	s.RLock()
	defer s.RUnlock()
	return s.maxVerSeen
}

func (s *UpdateStatus) VersionStatus() uint16 {
	s.RLock()
	defer s.RUnlock()
	return s.versionStatus
}

// CompatibleWith checks whether the remote peer version is compatible with the
// node itself.
// RULES:
// | local |           remote           |
// |   -   |             -              |
// | 1.0.3 | same major&moinor version. |
// | 1.0.4 |     same major version.    |
func CompatibleWith(remoteVerStr string) (bool, error) {
	localVersion, err := gover.NewVersion(Version)
	if err != nil {
		return false, err
	}
	remoteVersion, err := gover.NewVersion(remoteVerStr)
	if err != nil {
		return false, err
	}
	return (localVersion.Segments()[0] == remoteVersion.Segments()[0]), nil
}
<commit_msg>change the version (#1618)<commit_after>// package version provide the version info for the node, and also provide
// support for version compatibility check and update notification.
//
// The version format should follow Semantic Versioning (https://semver.org/):
// MAJOR.MINOR.PATCH
//  1. MAJOR version when you make incompatible API changes,
//  2. MINOR version when you add functionality in a backwards-compatible manner, and
// 	3. PATCH version when you make backwards-compatible bug fixes.
//
// A pre-release version MAY be denoted by appending a hyphen and a series of
// dot separated identifiers immediately following the patch version.
// Examples:
// 1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92.
// Precedence:
// 1. Pre-release versions have a lower precedence than the associated normal version!
//    Numeric identifiers always have lower precedence than non-numeric identifiers.
// 2. A larger set of pre-release fields has a higher precedence than a smaller set,
//    if all of the preceding identifiers are equal.
// 3. Example:
//    1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0.
//
// Build metadata MAY be denoted by appending a plus sign and a series of dot
// separated identifiers immediately following the patch or pre-release version.
// Build metadata SHOULD be ignored when determining version precedence. Thus
// two versions that differ only in the build metadata, have the same precedence.

package version

import (
	"sync"

	gover "github.com/hashicorp/go-version"
	log "github.com/sirupsen/logrus"
	"gopkg.in/fatih/set.v0"
)

const (
	// If needing to edit the iota, please ensure the following:
	// noUpdate = 0
	// hasUpdate = 1
	// hasMUpdate = 2
	noUpdate uint16 = iota
	hasUpdate
	hasMUpdate
	logModule = "version"
)

var (
	// The full version string
	Version = "1.0.8"
	// GitCommit is set with --ldflags "-X main.gitCommit=$(git rev-parse HEAD)"
	GitCommit string
	Status    *UpdateStatus
)

func init() {
	if GitCommit != "" {
		Version += "+" + GitCommit[:8]
	}
	Status = &UpdateStatus{
		maxVerSeen:    Version,
		notified:      false,
		seedSet:       set.New(),
		versionStatus: noUpdate,
	}
}

type UpdateStatus struct {
	sync.RWMutex
	maxVerSeen    string
	notified      bool
	seedSet       *set.Set
	versionStatus uint16
}

func (s *UpdateStatus) AddSeed(seedAddr string) {
	s.Lock()
	defer s.Unlock()
	s.seedSet.Add(seedAddr)
}

// CheckUpdate checks whether there is a newer version to update.
// If there is, it set the "Status" variable to a proper value.
// 	params:
// 		localVerStr: the version of the node itself
// 		remoteVerStr: the version received from a seed node.
// 		remoteAddr: the version received from a seed node.
// current rule:
// 		1. small update: seed version is higher than the node itself
// 		2. significant update: seed mojor version is higher than the node itself
func (s *UpdateStatus) CheckUpdate(localVerStr string, remoteVerStr string, remoteAddr string) error {
	s.Lock()
	defer s.Unlock()

	if s.notified || !s.seedSet.Has(remoteAddr) {
		return nil
	}

	localVersion, err := gover.NewVersion(localVerStr)
	if err != nil {
		return err
	}
	remoteVersion, err := gover.NewVersion(remoteVerStr)
	if err != nil {
		return err
	}
	if remoteVersion.GreaterThan(localVersion) {
		s.versionStatus = hasUpdate
		s.maxVerSeen = remoteVerStr
	}
	if remoteVersion.Segments()[0] > localVersion.Segments()[0] {
		s.versionStatus = hasMUpdate
	}
	if s.versionStatus != noUpdate {
		log.WithFields(log.Fields{
			"module":          logModule,
			"Current version": localVerStr,
			"Newer version":   remoteVerStr,
			"seed":            remoteAddr,
		}).Warn("Please update your bytomd via https://github.com/Bytom/bytom/releases/ or http://bytom.io/wallet/")
		s.notified = true
	}
	return nil
}

func (s *UpdateStatus) MaxVerSeen() string {
	s.RLock()
	defer s.RUnlock()
	return s.maxVerSeen
}

func (s *UpdateStatus) VersionStatus() uint16 {
	s.RLock()
	defer s.RUnlock()
	return s.versionStatus
}

// CompatibleWith checks whether the remote peer version is compatible with the
// node itself.
// RULES:
// | local |           remote           |
// |   -   |             -              |
// | 1.0.3 | same major&moinor version. |
// | 1.0.4 |     same major version.    |
func CompatibleWith(remoteVerStr string) (bool, error) {
	localVersion, err := gover.NewVersion(Version)
	if err != nil {
		return false, err
	}
	remoteVersion, err := gover.NewVersion(remoteVerStr)
	if err != nil {
		return false, err
	}
	return (localVersion.Segments()[0] == remoteVersion.Segments()[0]), nil
}
<|endoftext|>


<commit_before>package version

import (
	"bytes"
	"fmt"
)

var (
	// The git commit that was compiled. This will be filled in by the compiler.
	GitCommit   string
	GitDescribe string

	// The main version number that is being run at the moment.
	Version = "0.10.2"

	// A pre-release marker for the version. If this is "" (empty string)
	// then it means that it is a final release. Otherwise, this is a pre-release
	// such as "dev" (in development), "beta", "rc1", etc.
	VersionPrerelease = "dev"

	// VersionMetadata is metadata further describing the build type.
	VersionMetadata = ""
)

// VersionInfo
type VersionInfo struct {
	Revision          string
	Version           string
	VersionPrerelease string
	VersionMetadata   string
}

func GetVersion() *VersionInfo {
	ver := Version
	rel := VersionPrerelease
	md := VersionMetadata
	if GitDescribe != "" {
		ver = GitDescribe
	}
	if GitDescribe == "" && rel == "" && VersionPrerelease != "" {
		rel = "dev"
	}

	return &VersionInfo{
		Revision:          GitCommit,
		Version:           ver,
		VersionPrerelease: rel,
		VersionMetadata:   md,
	}
}

func (c *VersionInfo) VersionNumber() string {
	version := fmt.Sprintf("%s", c.Version)

	if c.VersionPrerelease != "" {
		version = fmt.Sprintf("%s-%s", version, c.VersionPrerelease)
	}

	if c.VersionMetadata != "" {
		version = fmt.Sprintf("%s+%s", version, c.VersionMetadata)
	}

	return version
}

func (c *VersionInfo) FullVersionNumber(rev bool) string {
	var versionString bytes.Buffer

	fmt.Fprintf(&versionString, "Nomad v%s", c.Version)
	if c.VersionPrerelease != "" {
		fmt.Fprintf(&versionString, "-%s", c.VersionPrerelease)
	}

	if c.VersionMetadata != "" {
		fmt.Fprintf(&versionString, "+%s", c.VersionMetadata)
	}

	if rev && c.Revision != "" {
		fmt.Fprintf(&versionString, " (%s)", c.Revision)
	}

	return versionString.String()
}
<commit_msg>release: bump version to 0.10.2-rc1<commit_after>package version

import (
	"bytes"
	"fmt"
)

var (
	// The git commit that was compiled. This will be filled in by the compiler.
	GitCommit   string
	GitDescribe string

	// The main version number that is being run at the moment.
	Version = "0.10.2"

	// A pre-release marker for the version. If this is "" (empty string)
	// then it means that it is a final release. Otherwise, this is a pre-release
	// such as "dev" (in development), "beta", "rc1", etc.
	VersionPrerelease = "rc1"

	// VersionMetadata is metadata further describing the build type.
	VersionMetadata = ""
)

// VersionInfo
type VersionInfo struct {
	Revision          string
	Version           string
	VersionPrerelease string
	VersionMetadata   string
}

func GetVersion() *VersionInfo {
	ver := Version
	rel := VersionPrerelease
	md := VersionMetadata
	if GitDescribe != "" {
		ver = GitDescribe
	}
	if GitDescribe == "" && rel == "" && VersionPrerelease != "" {
		rel = "dev"
	}

	return &VersionInfo{
		Revision:          GitCommit,
		Version:           ver,
		VersionPrerelease: rel,
		VersionMetadata:   md,
	}
}

func (c *VersionInfo) VersionNumber() string {
	version := fmt.Sprintf("%s", c.Version)

	if c.VersionPrerelease != "" {
		version = fmt.Sprintf("%s-%s", version, c.VersionPrerelease)
	}

	if c.VersionMetadata != "" {
		version = fmt.Sprintf("%s+%s", version, c.VersionMetadata)
	}

	return version
}

func (c *VersionInfo) FullVersionNumber(rev bool) string {
	var versionString bytes.Buffer

	fmt.Fprintf(&versionString, "Nomad v%s", c.Version)
	if c.VersionPrerelease != "" {
		fmt.Fprintf(&versionString, "-%s", c.VersionPrerelease)
	}

	if c.VersionMetadata != "" {
		fmt.Fprintf(&versionString, "+%s", c.VersionMetadata)
	}

	if rev && c.Revision != "" {
		fmt.Fprintf(&versionString, " (%s)", c.Revision)
	}

	return versionString.String()
}
<|endoftext|>


<commit_before>// The version package implements version parsing.
// It also acts as guardian of the current client Juju version number.
package version

import (
	"fmt"
	"io/ioutil"
	"labix.org/v2/mgo/bson"
	"os"
	"path/filepath"
	"regexp"
	"runtime"
	"strconv"
	"strings"
)

// The presence and format of this constant is very important.
// The debian/rules build recipe uses this value for the version
// number of the release package.
const version = "1.10.0"

// CurrentNumber returns the version number.
func CurrentNumber() Number {
	return MustParse(version)
}

// CurrentSeries returns the current Ubuntu release name.
func CurrentSeries() string {
	return readSeries("/etc/lsb-release")
}

// CurrentArch returns the architecture of the machine.
func CurrentArch() string {
	return ubuntuArch(runtime.GOARCH)
}

// Current gives the current version of the system.  If the file
// "FORCE-VERSION" is present in the same directory as the running
// binary, it will override this.
var Current = Binary{
	Number: CurrentNumber(),
	Series: CurrentSeries(),
	Arch:   CurrentArch(),
}

func init() {
	toolsDir := filepath.Dir(os.Args[0])
	v, err := ioutil.ReadFile(filepath.Join(toolsDir, "FORCE-VERSION"))
	if err != nil {
		if os.IsNotExist(err) {
			return
		}
		panic(fmt.Errorf("version: cannot read forced version: %v", err))
	}
	Current.Number = MustParse(strings.TrimSpace(string(v)))
}

// Number represents a juju version.  When bugs are fixed the patch
// number is incremented; when new features are added the minor number
// is incremented and patch is reset; and when compatibility is broken
// the major version is incremented and minor and patch are reset.  The
// build number is automatically assigned and has no well defined
// sequence.  If the build number is greater than zero or the minor
// version is odd, it indicates that the release is still in
// development.
type Number struct {
	Major int
	Minor int
	Patch int
	Build int
}

// Zero is occasionally convenient and readable.
// Please don't change its value.
var Zero = Number{}

// Binary specifies a binary version of juju.
type Binary struct {
	Number
	Series string
	Arch   string
}

func (v Binary) String() string {
	return fmt.Sprintf("%v-%s-%s", v.Number, v.Series, v.Arch)
}

// GetBSON turns v into a bson.Getter so it can be saved directly
// on a MongoDB database with mgo.
func (v Binary) GetBSON() (interface{}, error) {
	return v.String(), nil
}

// SetBSON turns v into a bson.Setter so it can be loaded directly
// from a MongoDB database with mgo.
func (vp *Binary) SetBSON(raw bson.Raw) error {
	var s string
	err := raw.Unmarshal(&s)
	if err != nil {
		return err
	}
	v, err := ParseBinary(s)
	if err != nil {
		return err
	}
	*vp = v
	return nil
}

var (
	binaryPat = regexp.MustCompile(`^(\d{1,9})\.(\d{1,9})\.(\d{1,9})(\.\d{1,9})?-([^-]+)-([^-]+)$`)
	numberPat = regexp.MustCompile(`^(\d{1,9})\.(\d{1,9})\.(\d{1,9})(\.\d{1,9})?$`)
)

// MustParse parses a version and panics if it does
// not parse correctly.
func MustParse(s string) Number {
	v, err := Parse(s)
	if err != nil {
		panic(err)
	}
	return v
}

// MustParseBinary parses a binary version and panics if it does
// not parse correctly.
func MustParseBinary(s string) Binary {
	v, err := ParseBinary(s)
	if err != nil {
		panic(err)
	}
	return v
}

// ParseBinary parses a binary version of the form "1.2.3-series-arch".
func ParseBinary(s string) (Binary, error) {
	m := binaryPat.FindStringSubmatch(s)
	if m == nil {
		return Binary{}, fmt.Errorf("invalid binary version %q", s)
	}
	var v Binary
	v.Major = atoi(m[1])
	v.Minor = atoi(m[2])
	v.Patch = atoi(m[3])
	if m[4] != "" {
		v.Build = atoi(m[4][1:])
	}
	v.Series = m[5]
	v.Arch = m[6]
	return v, nil
}

// Parse parses the version, which is of the form 1.2.3
// giving the major, minor and release versions
// respectively.
func Parse(s string) (Number, error) {
	m := numberPat.FindStringSubmatch(s)
	if m == nil {
		return Number{}, fmt.Errorf("invalid version %q", s)
	}
	var v Number
	v.Major = atoi(m[1])
	v.Minor = atoi(m[2])
	v.Patch = atoi(m[3])
	if m[4] != "" {
		v.Build = atoi(m[4][1:])
	}
	return v, nil
}

// atoi is the same as strconv.Atoi but assumes that
// the string has been verified to be a valid integer.
func atoi(s string) int {
	n, err := strconv.Atoi(s)
	if err != nil {
		panic(err)
	}
	return n
}

func (v Number) String() string {
	s := fmt.Sprintf("%d.%d.%d", v.Major, v.Minor, v.Patch)
	if v.Build > 0 {
		s += fmt.Sprintf(".%d", v.Build)
	}
	return s
}

// Less returns whether v is semantically earlier in the
// version sequence than w.
func (v Number) Less(w Number) bool {
	switch {
	case v.Major != w.Major:
		return v.Major < w.Major
	case v.Minor != w.Minor:
		return v.Minor < w.Minor
	case v.Patch != w.Patch:
		return v.Patch < w.Patch
	case v.Build != w.Build:
		return v.Build < w.Build
	}
	return false
}

// GetBSON turns v into a bson.Getter so it can be saved directly
// on a MongoDB database with mgo.
func (v Number) GetBSON() (interface{}, error) {
	return v.String(), nil
}

// SetBSON turns v into a bson.Setter so it can be loaded directly
// from a MongoDB database with mgo.
func (vp *Number) SetBSON(raw bson.Raw) error {
	var s string
	err := raw.Unmarshal(&s)
	if err != nil {
		return err
	}
	v, err := Parse(s)
	if err != nil {
		return err
	}
	*vp = v
	return nil
}

func isOdd(x int) bool {
	return x%2 != 0
}

// IsDev returns whether the version represents a development
// version. A version with an odd-numbered minor component or
// a nonzero build component is considered to be a development
// version.
func (v Number) IsDev() bool {
	return isOdd(v.Minor) || v.Build > 0
}

func readSeries(releaseFile string) string {
	data, err := ioutil.ReadFile(releaseFile)
	if err != nil {
		return "unknown"
	}
	for _, line := range strings.Split(string(data), "\n") {
		const p = "DISTRIB_CODENAME="
		if strings.HasPrefix(line, p) {
			return strings.Trim(line[len(p):], "\t '\"")
		}
	}
	return "unknown"
}

func ubuntuArch(arch string) string {
	if arch == "386" {
		arch = "i386"
	}
	return arch
}
<commit_msg>set version 1.11.0<commit_after>// The version package implements version parsing.
// It also acts as guardian of the current client Juju version number.
package version

import (
	"fmt"
	"io/ioutil"
	"labix.org/v2/mgo/bson"
	"os"
	"path/filepath"
	"regexp"
	"runtime"
	"strconv"
	"strings"
)

// The presence and format of this constant is very important.
// The debian/rules build recipe uses this value for the version
// number of the release package.
const version = "1.11.0"

// CurrentNumber returns the version number.
func CurrentNumber() Number {
	return MustParse(version)
}

// CurrentSeries returns the current Ubuntu release name.
func CurrentSeries() string {
	return readSeries("/etc/lsb-release")
}

// CurrentArch returns the architecture of the machine.
func CurrentArch() string {
	return ubuntuArch(runtime.GOARCH)
}

// Current gives the current version of the system.  If the file
// "FORCE-VERSION" is present in the same directory as the running
// binary, it will override this.
var Current = Binary{
	Number: CurrentNumber(),
	Series: CurrentSeries(),
	Arch:   CurrentArch(),
}

func init() {
	toolsDir := filepath.Dir(os.Args[0])
	v, err := ioutil.ReadFile(filepath.Join(toolsDir, "FORCE-VERSION"))
	if err != nil {
		if os.IsNotExist(err) {
			return
		}
		panic(fmt.Errorf("version: cannot read forced version: %v", err))
	}
	Current.Number = MustParse(strings.TrimSpace(string(v)))
}

// Number represents a juju version.  When bugs are fixed the patch
// number is incremented; when new features are added the minor number
// is incremented and patch is reset; and when compatibility is broken
// the major version is incremented and minor and patch are reset.  The
// build number is automatically assigned and has no well defined
// sequence.  If the build number is greater than zero or the minor
// version is odd, it indicates that the release is still in
// development.
type Number struct {
	Major int
	Minor int
	Patch int
	Build int
}

// Zero is occasionally convenient and readable.
// Please don't change its value.
var Zero = Number{}

// Binary specifies a binary version of juju.
type Binary struct {
	Number
	Series string
	Arch   string
}

func (v Binary) String() string {
	return fmt.Sprintf("%v-%s-%s", v.Number, v.Series, v.Arch)
}

// GetBSON turns v into a bson.Getter so it can be saved directly
// on a MongoDB database with mgo.
func (v Binary) GetBSON() (interface{}, error) {
	return v.String(), nil
}

// SetBSON turns v into a bson.Setter so it can be loaded directly
// from a MongoDB database with mgo.
func (vp *Binary) SetBSON(raw bson.Raw) error {
	var s string
	err := raw.Unmarshal(&s)
	if err != nil {
		return err
	}
	v, err := ParseBinary(s)
	if err != nil {
		return err
	}
	*vp = v
	return nil
}

var (
	binaryPat = regexp.MustCompile(`^(\d{1,9})\.(\d{1,9})\.(\d{1,9})(\.\d{1,9})?-([^-]+)-([^-]+)$`)
	numberPat = regexp.MustCompile(`^(\d{1,9})\.(\d{1,9})\.(\d{1,9})(\.\d{1,9})?$`)
)

// MustParse parses a version and panics if it does
// not parse correctly.
func MustParse(s string) Number {
	v, err := Parse(s)
	if err != nil {
		panic(err)
	}
	return v
}

// MustParseBinary parses a binary version and panics if it does
// not parse correctly.
func MustParseBinary(s string) Binary {
	v, err := ParseBinary(s)
	if err != nil {
		panic(err)
	}
	return v
}

// ParseBinary parses a binary version of the form "1.2.3-series-arch".
func ParseBinary(s string) (Binary, error) {
	m := binaryPat.FindStringSubmatch(s)
	if m == nil {
		return Binary{}, fmt.Errorf("invalid binary version %q", s)
	}
	var v Binary
	v.Major = atoi(m[1])
	v.Minor = atoi(m[2])
	v.Patch = atoi(m[3])
	if m[4] != "" {
		v.Build = atoi(m[4][1:])
	}
	v.Series = m[5]
	v.Arch = m[6]
	return v, nil
}

// Parse parses the version, which is of the form 1.2.3
// giving the major, minor and release versions
// respectively.
func Parse(s string) (Number, error) {
	m := numberPat.FindStringSubmatch(s)
	if m == nil {
		return Number{}, fmt.Errorf("invalid version %q", s)
	}
	var v Number
	v.Major = atoi(m[1])
	v.Minor = atoi(m[2])
	v.Patch = atoi(m[3])
	if m[4] != "" {
		v.Build = atoi(m[4][1:])
	}
	return v, nil
}

// atoi is the same as strconv.Atoi but assumes that
// the string has been verified to be a valid integer.
func atoi(s string) int {
	n, err := strconv.Atoi(s)
	if err != nil {
		panic(err)
	}
	return n
}

func (v Number) String() string {
	s := fmt.Sprintf("%d.%d.%d", v.Major, v.Minor, v.Patch)
	if v.Build > 0 {
		s += fmt.Sprintf(".%d", v.Build)
	}
	return s
}

// Less returns whether v is semantically earlier in the
// version sequence than w.
func (v Number) Less(w Number) bool {
	switch {
	case v.Major != w.Major:
		return v.Major < w.Major
	case v.Minor != w.Minor:
		return v.Minor < w.Minor
	case v.Patch != w.Patch:
		return v.Patch < w.Patch
	case v.Build != w.Build:
		return v.Build < w.Build
	}
	return false
}

// GetBSON turns v into a bson.Getter so it can be saved directly
// on a MongoDB database with mgo.
func (v Number) GetBSON() (interface{}, error) {
	return v.String(), nil
}

// SetBSON turns v into a bson.Setter so it can be loaded directly
// from a MongoDB database with mgo.
func (vp *Number) SetBSON(raw bson.Raw) error {
	var s string
	err := raw.Unmarshal(&s)
	if err != nil {
		return err
	}
	v, err := Parse(s)
	if err != nil {
		return err
	}
	*vp = v
	return nil
}

func isOdd(x int) bool {
	return x%2 != 0
}

// IsDev returns whether the version represents a development
// version. A version with an odd-numbered minor component or
// a nonzero build component is considered to be a development
// version.
func (v Number) IsDev() bool {
	return isOdd(v.Minor) || v.Build > 0
}

func readSeries(releaseFile string) string {
	data, err := ioutil.ReadFile(releaseFile)
	if err != nil {
		return "unknown"
	}
	for _, line := range strings.Split(string(data), "\n") {
		const p = "DISTRIB_CODENAME="
		if strings.HasPrefix(line, p) {
			return strings.Trim(line[len(p):], "\t '\"")
		}
	}
	return "unknown"
}

func ubuntuArch(arch string) string {
	if arch == "386" {
		arch = "i386"
	}
	return arch
}
<|endoftext|>


<commit_before>package version

import "fmt"

const (
	// VersionMajor is for an API incompatible changes
	VersionMajor = 5
	// VersionMinor is for functionality in a backwards-compatible manner
	VersionMinor = 6
	// VersionPatch is for backwards-compatible bug fixes
	VersionPatch = 1

	// VersionDev indicates development branch. Releases will be empty string.
	VersionDev = "-dev"
)

// Version is the specification version that the package types support.
var Version = fmt.Sprintf("%d.%d.%d%s", VersionMajor, VersionMinor, VersionPatch, VersionDev)
<commit_msg>Bump to v5.7.0<commit_after>package version

import "fmt"

const (
	// VersionMajor is for an API incompatible changes
	VersionMajor = 5
	// VersionMinor is for functionality in a backwards-compatible manner
	VersionMinor = 7
	// VersionPatch is for backwards-compatible bug fixes
	VersionPatch = 0

	// VersionDev indicates development branch. Releases will be empty string.
	VersionDev = ""
)

// Version is the specification version that the package types support.
var Version = fmt.Sprintf("%d.%d.%d%s", VersionMajor, VersionMinor, VersionPatch, VersionDev)
<|endoftext|>


<commit_before>// Copyright 2015 The etcd Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package version implements etcd version parsing and contains latest version
// information.
package version

import (
	"fmt"
	"strings"

	"github.com/coreos/go-semver/semver"
)

var (
	// MinClusterVersion is the min cluster version this etcd binary is compatible with.
	MinClusterVersion = "3.0.0"
	Version           = "3.3.0+git"
	APIVersion        = "unknown"

	// Git SHA Value will be set during build
	GitSHA = "Not provided (use ./build instead of go build)"
)

func init() {
	ver, err := semver.NewVersion(Version)
	if err == nil {
		APIVersion = fmt.Sprintf("%d.%d", ver.Major, ver.Minor)
	}
}

type Versions struct {
	Server  string `json:"etcdserver"`
	Cluster string `json:"etcdcluster"`
	// TODO: raft state machine version
}

// Cluster only keeps the major.minor.
func Cluster(v string) string {
	vs := strings.Split(v, ".")
	if len(vs) <= 2 {
		return v
	}
	return fmt.Sprintf("%s.%s", vs[0], vs[1])
}
<commit_msg>version: 3.4.0-pre<commit_after>// Copyright 2015 The etcd Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package version implements etcd version parsing and contains latest version
// information.
package version

import (
	"fmt"
	"strings"

	"github.com/coreos/go-semver/semver"
)

var (
	// MinClusterVersion is the min cluster version this etcd binary is compatible with.
	MinClusterVersion = "3.0.0"
	Version           = "3.4.0-pre"
	APIVersion        = "unknown"

	// Git SHA Value will be set during build
	GitSHA = "Not provided (use ./build instead of go build)"
)

func init() {
	ver, err := semver.NewVersion(Version)
	if err == nil {
		APIVersion = fmt.Sprintf("%d.%d", ver.Major, ver.Minor)
	}
}

type Versions struct {
	Server  string `json:"etcdserver"`
	Cluster string `json:"etcdcluster"`
	// TODO: raft state machine version
}

// Cluster only keeps the major.minor.
func Cluster(v string) string {
	vs := strings.Split(v, ".")
	if len(vs) <= 2 {
		return v
	}
	return fmt.Sprintf("%s.%s", vs[0], vs[1])
}
<|endoftext|>


<commit_before>package version

import (
	"bytes"
	"fmt"
)

// Version is the version of the app
const Version = "1.0.2"

// VersionPrerelease is the state of the app
const VersionPrerelease = "dev"

// FormattedVersion is used to format the full version of the app
func FormattedVersion() string {
	var versionString bytes.Buffer
	fmt.Fprintf(&versionString, "%s", Version)

	if VersionPrerelease != "" {
		fmt.Fprintf(&versionString, "-%s", VersionPrerelease)
	}

	return versionString.String()
}
<commit_msg>Prepare 1.0.2 release<commit_after>package version

import (
	"bytes"
	"fmt"
)

// Version is the version of the app
const Version = "1.0.2"

// VersionPrerelease is the state of the app
const VersionPrerelease = ""

// FormattedVersion is used to format the full version of the app
func FormattedVersion() string {
	var versionString bytes.Buffer
	fmt.Fprintf(&versionString, "%s", Version)

	if VersionPrerelease != "" {
		fmt.Fprintf(&versionString, "-%s", VersionPrerelease)
	}

	return versionString.String()
}
<|endoftext|>


<commit_before>package version

const (
	// Version is the current version of SensorBee.
	Version = "0.5.1"

	// Major is the major version of the current SensorBee.
	Major = 0

	// Minor is the minor version of the current SensorBee.
	Minor = 5

	// Revision is the revision number of the current SensorBee version.
	Revision = 1
)
<commit_msg>Version 0.5.2<commit_after>package version

const (
	// Version is the current version of SensorBee.
	Version = "0.5.2"

	// Major is the major version of the current SensorBee.
	Major = 0

	// Minor is the minor version of the current SensorBee.
	Minor = 5

	// Revision is the revision number of the current SensorBee version.
	Revision = 2
)
<|endoftext|>