예제 #1
0
func (zk *zkf) GetServiceStates(poolID string, states *[]servicestate.ServiceState, serviceIDs ...string) error {
	conn, err := zzk.GetLocalConnection(zzk.GeneratePoolPath(poolID))
	if err != nil {
		return err
	}

	*states, err = zkservice.GetServiceStates(conn, serviceIDs...)
	return err
}
예제 #2
0
/* This method assumes that if a service instance exists, it has not yet been terminated */
func (this *ControlPlaneDao) getNonTerminatedServiceStates(serviceId string, serviceStates *[]servicestate.ServiceState) error {
	glog.V(2).Infof("ControlPlaneDao.getNonTerminatedServiceStates: serviceId=%s", serviceId)

	poolBasedConn, err := this.getPoolBasedConnection(serviceId)
	if err != nil {
		return err
	}

	*serviceStates, err = zkservice.GetServiceStates(poolBasedConn, serviceId)
	return err
}
예제 #3
0
func (dfs *DistributedFilesystem) desynchronize(image *docker.Image) error {
	// inspect the image
	dImg, err := image.Inspect()
	if err != nil {
		glog.Errorf("Could not inspect image %s (%s): %s", image.ID, image.UUID, err)
		return err
	}

	// look up services for that tenant
	svcs, err := dfs.facade.GetServices(datastore.Get(), dao.ServiceRequest{TenantID: image.ID.User})
	if err != nil {
		glog.Errorf("Could not get services for tenant %s from %s (%s): %s", image.ID.User, image.ID, image.UUID, err)
		return err
	}

	for _, svc := range svcs {
		// figure out which services are using the provided image
		svcImageID, err := commons.ParseImageID(svc.ImageID)
		if err != nil {
			glog.Warningf("Could not parse image %s for %s (%s): %s", svc.ImageID, svc.Name, svc.ID)
			continue
		} else if !svcImageID.Equals(image.ID) {
			continue
		}

		// TODO: we need to switch to using dao.ControlPlane
		conn, err := zzk.GetLocalConnection(zzk.GeneratePoolPath(svc.PoolID))
		if err != nil {
			glog.Warningf("Could not acquire connection to the coordinator (%s): %s", svc.PoolID, err)
			continue
		}

		states, err := zkservice.GetServiceStates(conn, svc.ID)
		if err != nil {
			glog.Warningf("Could not get running services for %s (%s): %s", svc.Name, svc.ID)
			continue
		}

		for _, state := range states {
			// check if the instance has been running since before the commit
			if state.IsRunning() && state.Started.Before(dImg.Created) {
				state.InSync = false
				if err := zkservice.UpdateServiceState(conn, &state); err != nil {
					glog.Warningf("Could not update service state %s for %s (%s) as out of sync: %s", state.ID, svc.Name, svc.ID, err)
					continue
				}
			}
		}
	}
	return nil
}
예제 #4
0
func (this *ControlPlaneDao) GetServiceStates(serviceId string, states *[]servicestate.ServiceState) error {
	glog.V(2).Infof("ControlPlaneDao.GetServiceStates: serviceId=%s", serviceId)
	*states = make([]servicestate.ServiceState, 0)

	poolBasedConn, err := this.getPoolBasedConnection(serviceId)
	if err != nil {
		return err
	}

	serviceStates, err := zkservice.GetServiceStates(poolBasedConn, serviceId)
	if serviceStates != nil {
		*states = serviceStates
	}
	return err
}
예제 #5
0
func (dfs *DistributedFilesystem) Restore(filename string) error {
	// fail if any services are running
	dfs.log("Checking running services")
	svcs, err := dfs.facade.GetServices(datastore.Get(), dao.ServiceRequest{})
	if err != nil {
		glog.Errorf("Could not acquire the list of all services: %s", err)
		return err
	}

	for _, svc := range svcs {
		conn, err := zzk.GetLocalConnection(zzk.GeneratePoolPath(svc.PoolID))
		if err != nil {
			glog.Errorf("Could not acquire connection to coordinator (%s): %s", svc.PoolID, err)
			return err
		}
		if states, err := zkservice.GetServiceStates(conn, svc.ID); err != nil {
			glog.Errorf("Could not look up running instances for %s (%s): %s", svc.Name, svc.ID, err)
			return err
		} else if running := len(states); running > 0 {
			err := fmt.Errorf("service %s (%s) has %d running instances", svc.Name, svc.ID, running)
			glog.Errorf("Cannot restore to %s: %s", filename, err)
			return err
		}
	}

	var reloadLogstashContainer bool
	defer func() {
		if reloadLogstashContainer {
			go facade.LogstashContainerReloader(datastore.Get(), dfs.facade) // don't block main thread
		}
	}()

	dirpath := filepath.Join(utils.BackupDir(dfs.varpath), "restore")
	if err := os.RemoveAll(dirpath); err != nil {
		glog.Errorf("Could not remove %s: %s", dirpath, err)
		return err
	}

	if err := mkdir(dirpath); err != nil {
		glog.Errorf("Could neither find nor create %s: %s", dirpath, err)
		return err
	}

	defer func() {
		if err := os.RemoveAll(dirpath); err != nil {
			glog.Warningf("Could not remove %s: %s", dirpath, err)
		}
	}()

	dfs.log("Extracting backup file %s", filename)
	if err := importTGZ(dirpath, filename); err != nil {
		glog.Errorf("Could not expand %s to %s: %s", filename, dirpath, err)
		return err
	}

	var metadata metadata
	if err := importJSON(filepath.Join(dirpath, meta), &metadata); err != nil {
		glog.Errorf("Could not import %s: %s", meta, err)
		return err
	} else if metadata.FSType != dfs.fsType {
		err = fmt.Errorf("this backup can only be run on %s", metadata.FSType)
		glog.Errorf("Could not extract backup %s: %s", filename, err)
		return err
	}

	var pools []pool.ResourcePool
	if err := importJSON(filepath.Join(dirpath, poolJSON), &pools); err != nil {
		glog.Errorf("Could not read resource pools from %s: %s", filename, err)
		return err
	}

	// restore the resource pools (and virtual ips)
	dfs.log("Loading resource pools")
	for _, pool := range pools {
		pool.DatabaseVersion = 0

		glog.V(1).Infof("Restoring resource pool %s", pool.ID)
		var err error
		if err = dfs.facade.AddResourcePool(datastore.Get(), &pool); err == facade.ErrPoolExists {
			err = dfs.facade.UpdateResourcePool(datastore.Get(), &pool)
		}
		if err != nil {
			glog.Errorf("Could not restore resource pool %s: %s", pool.ID, err)
			return err
		}
	}
	dfs.log("Resource pool load successful")

	var hosts []host.Host
	if err := importJSON(filepath.Join(dirpath, hostJSON), &hosts); err != nil {
		glog.Errorf("Could not read hosts from %s: %s", filename, err)
		return err
	}

	// restore the hosts (add it if it doesn't exist; assume hosts don't need to be updated from backup)
	dfs.log("Loading static ips")
	for _, host := range hosts {
		host.DatabaseVersion = 0
		glog.V(1).Infof("Restoring host %s (%s)", host.ID, host.IPAddr)
		if exists, err := dfs.facade.HasIP(datastore.Get(), host.PoolID, host.IPAddr); err != nil {
			glog.Errorf("Could not check IP %s for pool %s: %s", host.IPAddr, host.PoolID, err)
			return err
		} else if exists {
			glog.Warningf("Could not restore host %s (%s): ip already exists", host.ID, host.IPAddr)
		} else if err := dfs.facade.AddHost(datastore.Get(), &host); err != nil {
			glog.Errorf("Could not add host %s: %s", host.ID, err)
			return err
		}
	}
	dfs.log("Static ip load successful")

	var templates map[string]servicetemplate.ServiceTemplate
	if err := importJSON(filepath.Join(dirpath, templateJSON), &templates); err != nil {
		glog.Errorf("Could not read templates from %s: %s", filename, err)
		return err
	}

	// restore the service templates
	dfs.log("Loading service templates")
	for templateID, template := range templates {
		template.DatabaseVersion = 0

		glog.V(1).Infof("Restoring service template %s", templateID)
		template.ID = templateID
		if err := dfs.facade.UpdateServiceTemplate(datastore.Get(), template); err != nil {
			glog.Errorf("Could not restore template %s: %s", templateID, err)
			return err
		}
		reloadLogstashContainer = true
	}
	dfs.log("Service template load successful")

	// Get the tenant of all the services to be restored
	snapshotFiles, err := ls(filepath.Join(dirpath, snapshotDir))
	tenantIDs := make(map[string]struct{})
	for _, f := range snapshotFiles {
		tenantIDs[strings.TrimSuffix(f, ".tgz")] = struct{}{}
	}

	// restore docker images
	dfs.log("Loading docker images")
	var images []imagemeta
	if err := importJSON(filepath.Join(dirpath, imageJSON), &images); err != nil {
		glog.Errorf("Could not read images from %s: %s", filename, err)
		return err
	}

	if err := dfs.importImages(filepath.Join(dirpath, imageDir), images, tenantIDs); err != nil {
		glog.Errorf("Could not import images from %s: %s", filename, err)
		return err
	}
	dfs.log("Docker image load successful")

	// restore snapshots
	glog.V(1).Infof("Restoring services and snapshots")
	for _, f := range snapshotFiles {
		dfs.log("Loading %s", f)
		if err := dfs.loadSnapshots(strings.TrimSuffix(f, ".tgz"), filepath.Join(dirpath, snapshotDir, f)); err != nil {
			glog.Errorf("Could not import snapshot from %s: %s", f, err)
			return err
		}
		dfs.log("Successfully loaded %s", f)
	}

	glog.Infof("Restore succeeded with fsType:%s from file:%s", dfs.fsType, filename)
	return nil
}
예제 #6
0
// getServiceState gets the service states for a serviceID
func getServiceStates(conn coordclient.Connection, serviceID string) ([]servicestate.ServiceState, error) {
	return zkservice.GetServiceStates(conn, serviceID)
}