Exemple #1
0
func startListen() {
	fmt.Println("Running reboot listener")
	libvirt.EventRegisterDefaultImpl()
	// EventRunDefaultImpl has to be run before register. or no events caught,
	// I do not know why
	go func() {
		for {
			ret := libvirt.EventRunDefaultImpl()
			if ret == -1 {
				fmt.Println("RuN failed")
				break
			}
		}
	}()

}
Exemple #2
0
//TODO move all sql to model.go
func main() {
	/* init database */
	db, err := sql.Open("sqlite3", "/tmp/post_db.bin")
	if err != nil {
		checkErr(err, "open database failed")
		return
	}
	defer db.Close()

	var scanning int32 = 0

	m := martini.Classic()
	m.Use(render.Renderer())

	m.Get("/", func(r render.Render) {
		r.Redirect("index.html")
	})

	//Install a new VM
	m.Get("/create", func(r render.Render) {
		var Name string
		var IpAddress string

		type HostInfo struct {
			Name      string
			IpAddress string
		}

		type Hosts struct {
			Hosts []HostInfo
		}

		//var hosts []HostInfo
		var hosts Hosts

		rows, err := db.Query("select Name,IpAddress from physicalmachine")
		if err != nil {
			reportError(r, err, "failed to find physicalmachine")
		}
		for rows.Next() {
			rows.Scan(&Name, &IpAddress)
			hosts.Hosts = append(hosts.Hosts, HostInfo{Name, IpAddress})
			//hosts = append(hosts, HostInfo{Name, IpAddress})
		}
		log.Println(hosts)
		r.JSON(200, hosts)
	})

	m.Post("/create", func(r render.Render, req *http.Request) {

		name := req.PostFormValue("Name")
		ip := req.PostFormValue("IpAddress")
		repo := req.PostFormValue("repo")
		diskSize := req.PostFormValue("disk")
		autoinst := req.PostFormValue("autoinst")
		//check input data
		imageSize, err := strconv.Atoi(diskSize)
		if err != nil {
			reportError(r, err, "convert failed")
			return
		}
		//convert to GB
		imageSize = imageSize << 30

		conn, err := getConnectionFromCacheByIP(ip)
		if err != nil {
			reportError(r, err, "no connections")
			return
		}
		log.Println(conn)

		ch := make(chan string, 100)
		go vminstall.VmInstall(conn, name, repo, autoinst, uint64(imageSize), ch)

		//map token_uuid <=> {channel,name,connection,ip}
		token := uuid.New()
		t := TokenContentForVMInstall{Ch: ch, Name: name, Conn: conn, IPAddress: ip}
		tokenMap.Set(token, t)

		type TokenJson struct {
			Token string
		}
		var tokenJson TokenJson
		tokenJson.Token = token
		r.JSON(200, tokenJson)
	})

	m.Get("/add", func(r render.Render) {
		r.HTML(200, "add", nil)
	})

	//missing validation
	//ADD new PhysicalMachine
	m.Post("/add", func(r render.Render, req *http.Request) {
		var existingname string
		name := req.PostFormValue("Name")
		description := req.PostFormValue("Description")
		IPAddress := req.PostFormValue("IPAddress")
		log.Println(name + description + IPAddress)
		//TODO: add more validations
		err := db.QueryRow("select name from physicalmachine where IpAddress = ?", IPAddress).Scan(&existingname)
		switch {
		case err == sql.ErrNoRows:
			// good to insert the PhysicalMachine
			db.Exec("insert into physicalmachine (Name, IpAddress, Description) values(?,?,?)", name, IPAddress, description)
			r.Redirect("/")
		case err != nil:
			//other error happens
			r.HTML(501, "error", err)
		default:
			//no error happens
			r.HTML(501, "error", fmt.Errorf("already has the physical machine %s", existingname))

		}

	})

	m.Get("/vm/(?P<id>[0-9]+)", func(r render.Render, params martini.Params) {
		id, _ := strconv.Atoi(params["id"])
		vm := getVirtualMachine(db, id)
		r.HTML(200, "vm", vm)
	})

	m.Post("/vm/delete/(?P<id>[0-9]+)", func(r render.Render, params martini.Params) {
		id, _ := strconv.Atoi(params["id"])
		vm := getVirtualMachine(db, id)
		err := vm.Delete(db)
		defer vm.Free()
		if err != nil {
			reportError(r, err, "I can not delete the vm")
		}
		r.HTML(200, "vm", vm)

	})

	m.Post("/rescan", func(req *http.Request) {
		if atomic.LoadInt32(&scanning) == 0 {
			go func() {
				atomic.StoreInt32(&scanning, 1)
				RescanIPAddress(db)
				atomic.StoreInt32(&scanning, 0)

			}()
		}
	})

	m.Post("/vm/(?P<id>[0-9]+)", func(r render.Render, params martini.Params, req *http.Request) {
		req.ParseForm()
		submitType := req.PostFormValue("submit")
		id, _ := strconv.Atoi(params["id"])
		vm := getVirtualMachine(db, id)
		var err error
		switch submitType {
		case "Start":
			err = vm.Start()
			vm.Free()
		case "Stop":
			err = vm.Stop()
			//TODO: wait a while
			vm.Free()
		case "ForceStop":
			err = vm.ForceStop()
			vm.Free()
		case "Update":
			owner := req.PostForm["Owner"][0]
			description := req.PostForm["Description"][0]
			err = vm.UpdateDatabase(db, owner, description)
		}

		if err != nil {
			//error page
			r.HTML(501, "error", err)
			log.Println(err)
		} else {
			//redirect page
			r.Redirect("/")
		}
	})

	//API part
	m.Get("/api/list", func(r render.Render) {
		pm := getListofPhysicalMachineAndVirtualMachine(db)
		r.JSON(200, pm)
	})

	m.Get("/api/vm/(?P<id>[0-9]+)", func(r render.Render, params martini.Params) {
		id, _ := strconv.Atoi(params["id"])
		vm := getVirtualMachine(db, id)
		r.JSON(200, vm)
	})

	vncProxy := websocket.Server{Handler: proxyHandler,
		Handshake: func(ws *websocket.Config, req *http.Request) error {
			ws.Protocol = []string{"base64"}
			return nil
		}}

	m.Get("/websockify", vncProxy.ServeHTTP)

	installState := websocket.Server{Handler: stateReportHandler}

	m.Get("/installsockify", installState.ServeHTTP)

	// rescan IP address every 6 hour
	go func() {
		for {
			time.Sleep(time.Hour * 6)
			if atomic.LoadInt32(&scanning) == 0 {
				log.Println("start planed rescan IP address")
				atomic.StoreInt32(&scanning, 1)
				RescanIPAddress(db)
				atomic.StoreInt32(&scanning, 0)
			}
		}

	}()

	//EventRunDefault
	//this must be before any connection
	libvirt.EventRegisterDefaultImpl()
	go func() {
		for {
			ret := libvirt.EventRunDefaultImpl()
			if ret == -1 {
				fmt.Println("RuN failed")
				break
			}
		}
	}()

	//start web server
	http.ListenAndServe(":3000", m)
}