Пример #1
0
func (c *chaninterface) onModel(address, path string) error {
	// read model file and remove it
	data, err := ioutil.ReadFile(path)
	if err != nil {
		return err
	}
	err = os.Remove(path)
	if err != nil {
		log.Println("Failed to remove temp model file:", err)
		// not strictly critical so no return here
	}
	// unmarshal
	foreignModel := &shared.ObjectInfo{}
	err = json.Unmarshal(data, foreignModel)
	if err != nil {
		return err
	}
	// make a model of the local stuff
	storePath := c.boot.path + "/" + shared.TINZENITEDIR + "/" + shared.LOCALDIR
	m, err := model.Create(c.boot.path, c.boot.peer.Identification, storePath)
	if err != nil {
		return err
	}
	c.model = m
	// apply what is already here
	err = c.model.Update()
	if err != nil {
		return err
	}
	// get difference in updates
	var updateLists []*shared.UpdateMessage
	updateLists, err = c.model.Bootstrap(foreignModel)
	if err != nil {
		return err
	}
	log.Println("Need to apply", len(updateLists), "updates.")
	// pretend that the updatemessage came from outside here
	for _, um := range updateLists {
		// directories can be applied directly
		if um.Object.Directory {
			dirPath := m.RootPath + "/" + um.Object.Path
			// if the dir doesn't exist, make it
			if exists, _ := shared.DirectoryExists(dirPath); !exists {
				err := shared.MakeDirectory(dirPath)
				if err != nil {
					log.Println("Failed applying dir:", err)
				}
			}
			// apply to model
			err = c.model.ApplyUpdateMessage(um)
			// ignore merge conflicts as they are to be overwritten anyway
			if err != nil && err != shared.ErrConflict {
				return err
			}
			continue
		}
		// write update messages which must be fetched
		c.messages[um.Object.Identification] = um
	}
	return nil
}
Пример #2
0
func main() {
	log.Println(tag, "starting server.")
	// define required flags
	var path string
	var commandString string
	var useHadoop bool
	var address string
	var user string
	flag.StringVar(&path, "path", "", "File directory path in which to run the server.")
	flag.StringVar(&commandString, "cmd", "load", "Command for the path: create or load. Default is load.")
	flag.BoolVar(&useHadoop, "hadoop", false, "Flag to enable Hadoop storage.")
	flag.StringVar(&address, "address", "127.0.0.1", "Address of HDFS to connect to.")
	flag.StringVar(&user, "user", "root", "User of HDFS to connect as.")
	// parse flags
	flag.Parse()

	// prepare command
	command := shared.CmdParse(commandString)
	// if command isn't load or create, quit
	if command != shared.CmdLoad && command != shared.CmdCreate {
		log.Println(tag, "invalid command given!")
		return
	}
	// prepare path
	if path == "" {
		path = shared.GetString("Enter path for Server directory:")
	}
	// make sure the path is clean and absolute
	path, _ = filepath.Abs(filepath.Clean(path))
	// path may not be empty OR only contain '.' (which means error in filepath)
	if path == "" || path == "." {
		log.Println(tag, "no path given!")
		return
	}
	// create it if required and desired
	if exists, _ := shared.DirectoryExists(path); !exists {
		// if command is load we're not going to offer creating the path
		if command == shared.CmdLoad {
			log.Println(tag, "Can not run Server without valid path.")
			return
		}
		useQuestion := shared.CreateYesNo("Path <" + path + "> doesn't exist. Create it?")
		if useQuestion.Ask() < 0 {
			log.Println(tag, "Can not run Server without valid path.")
			return
		}
		// if yes, create it
		shared.MakeDirectory(path)
	}

	// prepare storage
	var store encrypted.Storage
	if useHadoop {
		var err error
		store, err = createHDFSStorage(address, user)
		if err != nil {
			log.Println("Failed to connect to HDFS:", err)
			return
		}
	} else {
		// disk storage writes data to disk
		store = createDiskStorage(path)
	}

	var enc *encrypted.Encrypted
	var err error
	switch command {
	case shared.CmdLoad:
		enc, err = encrypted.Load(path, store)
		if err != nil {
			log.Println(tag, "failed to load encrypted:", err)
			return
		}
	case shared.CmdCreate:
		peerName := shared.GetString("Please enter a peer name for this instance:")
		enc, err = encrypted.Create(path, peerName, store)
		if err != nil {
			log.Println(tag, "failed to create encrypted:", err)
			return
		}
		// store first version for future loads
		err = enc.Store()
		if err != nil {
			log.Println(tag, "failed to store initially:", err)
		}
	default:
		log.Println(tag, "No valid command was chosen, so we'll do nothing.")
		return
	}

	// run encrypted
	// print important info
	toxAddress, _ := enc.Address()
	fmt.Printf("%s Running server <%s>.\nID: %s\n", tag, enc.Name(), toxAddress)
	// prepare quitting via ctrl-c
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	// loop until close
	for {
		select {
		case <-c:
			// store before closing
			_ = enc.Store()
			enc.Close()
			log.Println(tag, "quitting.")
			return
		} // select
	} // for
}