// olderVersionTerminalAllocs returns terminal allocations whose job create index
// is older than the job's create index
504160
func olderVersionTerminalAllocs(allocs []*structs.Allocation, job *structs.Job) []string {
	var ret []string
	for _, alloc := range allocs {
		if alloc.Job != nil && alloc.Job.CreateIndex < job.CreateIndex && alloc.TerminalStatus() {
			ret = append(ret, alloc.ID)
		}
	}
	return ret
}
1099443
func (g *KubeVersionGetter) KubeletVersions() (map[string]uint16, error) {
	nodes, err := g.client.CoreV1().Nodes().List(metav1.ListOptions{})
	if err != nil {
		return nil, errors.New("couldn't list all nodes in cluster")
	}
	return computeKubeletVersions(nodes.Items), nil
}
1339128
func Versions(url, migrationsPath string) (versions file.Versions, err error) {
	d, err := driver.New(url)
	if err != nil {
		return file.Versions{}, err
	}
	return d.Versions()
}
163940
func (ndb *nodeDB) deleteOrphans(version int64) {
	// Will be zero if there is no previous version.
	predecessor := ndb.getPreviousVersion(version)

	// Traverse orphans with a lifetime ending at the version specified.
	// TODO optimize.
	ndb.traverseOrphansVersion(version, func(key, hash []byte) {
		var fromVersion, toVersion int64

		// See comment on `orphanKeyFmt`. Note that here, `version` and
		// `toVersion` are always equal.
		orphanKeyFormat.Scan(key, &toVersion, &fromVersion)

		// Delete orphan key and reverse-lookup key.
		ndb.batch.Delete(key)

		// If there is no predecessor, or the predecessor is earlier than the
		// beginning of the lifetime (ie: negative lifetime), or the lifetime
		// spans a single version and that version is the one being deleted, we
		// can delete the orphan.  Otherwise, we shorten its lifetime, by
		// moving its endpoint to the previous version.
		if predecessor < fromVersion || fromVersion == toVersion {
			debug("DELETE predecessor:%v fromVersion:%v toVersion:%v %X\n", predecessor, fromVersion, toVersion, hash)
			ndb.batch.Delete(ndb.nodeKey(hash))
			ndb.uncacheNode(hash)
		} else {
			debug("MOVE predecessor:%v fromVersion:%v toVersion:%v %X\n", predecessor, fromVersion, toVersion, hash)
			ndb.saveOrphan(hash, fromVersion, predecessor)
		}
	})
}
70937
func getStorageVersionKind(storageVersioner runtime.GroupVersioner, storage rest.Storage, typer runtime.ObjectTyper) (schema.GroupVersionKind, error) {
	object := storage.New()
	fqKinds, _, err := typer.ObjectKinds(object)
	if err != nil {
		return schema.GroupVersionKind{}, err
	}
	gvk, ok := storageVersioner.KindForGroupVersionKinds(fqKinds)
	if !ok {
		return schema.GroupVersionKind{}, fmt.Errorf("cannot find the storage version kind for %v", reflect.TypeOf(object))
	}
	return gvk, nil
}
573132
func updateSchemaVersion(t *meta.Meta, job *model.Job) (int64, error) {
	schemaVersion, err := t.GenSchemaVersion()
	if err != nil {
		return 0, errors.Trace(err)
	}
	diff := &model.SchemaDiff{
		Version:  schemaVersion,
		Type:     job.Type,
		SchemaID: job.SchemaID,
	}
	if job.Type == model.ActionTruncateTable {
		// Truncate table has two table ID, should be handled differently.
		err = job.DecodeArgs(&diff.TableID)
		if err != nil {
			return 0, errors.Trace(err)
		}
		diff.OldTableID = job.TableID
	} else if job.Type == model.ActionRenameTable {
		err = job.DecodeArgs(&diff.OldSchemaID)
		if err != nil {
			return 0, errors.Trace(err)
		}
		diff.TableID = job.TableID
	} else {
		diff.TableID = job.TableID
	}
	err = t.SetSchemaDiff(diff)
	return schemaVersion, errors.Trace(err)
}
1085168
func makeVersionFile(relPath string, versionFile pkg.VersionFile) (fs.File, error) {
	if !fs.IsCleanSlashPath(relPath) {
		return nil, fmt.Errorf("invalid version_file: %s", relPath)
	}
	blob, err := json.MarshalIndent(versionFile, "", "  ")
	if err != nil {
		return nil, err
	}
	return &blobFile{
		name: relPath,
		blob: blob,
	}, nil
}
1004609
func (c *Client) NumAllocs() int {
	n := 0
	c.allocLock.RLock()
	for _, a := range c.allocs {
		if !a.IsDestroyed() {
			n++
		}
	}
	c.allocLock.RUnlock()
	return n
}
406593
func InstallVersion(projectDir, targetVersion, wantChecksum string, cacheValidDuration time.Duration, newInstall bool, stdout io.Writer) error {
	if targetVersion == "" {
		version, err := latestGodelVersion(cacheValidDuration)
		if err != nil {
			return err
		}
		targetVersion = version
	}
	pkgSrc, err := pkgSrcForVersion(targetVersion, wantChecksum)
	if err != nil {
		return err
	}

	var installFn func(string, godelgetter.PkgSrc, io.Writer) error
	if newInstall {
		installFn = NewInstall
	} else {
		installFn = Update
	}
	return installFn(projectDir, pkgSrc, stdout)
}
1267635
func goToolVersion() (toolVersion, error) {
	goTool := &tool.T{Cmd: "go"}
	out, err := goTool.Exec("version")
	if err != nil {
		return toolVersionUnknown, err
	}
	build := strings.Split(out, " ")
	if len(build) > 2 {
		return parseToolVersion(build[2]), nil
	}
	return toolVersionUnknown, nil
}
3385
func getGodelVersion(projectDir string) (godelVersion, error) {
	godelw := path.Join(projectDir, "godelw")
	cmd := exec.Command(godelw, "version")
	output, err := cmd.Output()
	if err != nil {
		return godelVersion{}, errors.Wrapf(err, "failed to execute command %v: %s", cmd.Args, string(output))
	}

	// split input on newlines and only consider final line. Do this in case invoking "godelw" causes assets to be
	// downloaded (in which case download messages will be in output before version is printed).
	outputLines := strings.Split(strings.TrimSpace(string(output)), "\n")
	if len(outputLines) == 0 {
		return godelVersion{}, errors.Wrapf(err, "no elements found when splitting output %q on newlines", string(output))
	}
	outputString := outputLines[len(outputLines)-1]

	parts := strings.Split(outputString, " ")
	if len(parts) != 3 {
		return godelVersion{}, errors.Errorf(`expected output %s to have 3 parts when split by " ", but was %v`, outputString, parts)
	}
	v, err := newGodelVersion(parts[2])
	if err != nil {
		return godelVersion{}, errors.Wrapf(err, "failed to create version from output")
	}
	return v, nil
}
328014
func (s *SystemScheduler) computeJobAllocs() error {
	// Lookup the allocations by JobID
	ws := memdb.NewWatchSet()
	allocs, err := s.state.AllocsByJob(ws, s.eval.Namespace, s.eval.JobID, true)
	if err != nil {
		return fmt.Errorf("failed to get allocs for job '%s': %v",
			s.eval.JobID, err)
	}

	// Determine the tainted nodes containing job allocs
	tainted, err := taintedNodes(s.state, allocs)
	if err != nil {
		return fmt.Errorf("failed to get tainted nodes for job '%s': %v",
			s.eval.JobID, err)
	}

	// Update the allocations which are in pending/running state on tainted
	// nodes to lost
	updateNonTerminalAllocsToLost(s.plan, tainted, allocs)

	// Filter out the allocations in a terminal state
	allocs, terminalAllocs := structs.FilterTerminalAllocs(allocs)

	// Diff the required and existing allocations
	diff := diffSystemAllocs(s.job, s.nodes, tainted, allocs, terminalAllocs)
	s.logger.Debug("reconciled current state with desired state",
		"place", len(diff.place), "update", len(diff.update),
		"migrate", len(diff.migrate), "stop", len(diff.stop),
		"ignore", len(diff.ignore), "lost", len(diff.lost))

	// Add all the allocs to stop
	for _, e := range diff.stop {
		s.plan.AppendStoppedAlloc(e.Alloc, allocNotNeeded, "")
	}

	// Add all the allocs to migrate
	for _, e := range diff.migrate {
		s.plan.AppendStoppedAlloc(e.Alloc, allocNodeTainted, "")
	}

	// Lost allocations should be transitioned to desired status stop and client
	// status lost.
	for _, e := range diff.lost {
		s.plan.AppendStoppedAlloc(e.Alloc, allocLost, structs.AllocClientStatusLost)
	}

	// Attempt to do the upgrades in place
	destructiveUpdates, inplaceUpdates := inplaceUpdate(s.ctx, s.eval, s.job, s.stack, diff.update)
	diff.update = destructiveUpdates

	if s.eval.AnnotatePlan {
		s.plan.Annotations = &structs.PlanAnnotations{
			DesiredTGUpdates: desiredUpdates(diff, inplaceUpdates, destructiveUpdates),
		}
	}

	// Check if a rolling upgrade strategy is being used
	limit := len(diff.update)
	if !s.job.Stopped() && s.job.Update.Rolling() {
		limit = s.job.Update.MaxParallel
	}

	// Treat non in-place updates as an eviction and new placement.
	s.limitReached = evictAndPlace(s.ctx, diff, diff.update, allocUpdating, &limit)

	// Nothing remaining to do if placement is not required
	if len(diff.place) == 0 {
		if !s.job.Stopped() {
			for _, tg := range s.job.TaskGroups {
				s.queuedAllocs[tg.Name] = 0
			}
		}
		return nil
	}

	// Record the number of allocations that needs to be placed per Task Group
	for _, allocTuple := range diff.place {
		s.queuedAllocs[allocTuple.TaskGroup.Name] += 1
	}

	// Compute the placements
	return s.computePlacements(diff.place)
}
748899
func jobVersionSchema() *memdb.TableSchema {
	return &memdb.TableSchema{
		Name: "job_version",
		Indexes: map[string]*memdb.IndexSchema{
			"id": {
				Name:         "id",
				AllowMissing: false,
				Unique:       true,

				// Use a compound index so the tuple of (Namespace, ID, Version) is
				// uniquely identifying
				Indexer: &memdb.CompoundIndex{
					Indexes: []memdb.Indexer{
						&memdb.StringFieldIndex{
							Field: "Namespace",
						},

						&memdb.StringFieldIndex{
							Field:     "ID",
							Lowercase: true,
						},

						&memdb.UintFieldIndex{
							Field: "Version",
						},
					},
				},
			},
		},
	}
}
632371
func (c *configInternal) MongoVersion() mongo.Version {
	v, err := mongo.NewVersion(c.mongoVersion)
	if err != nil {
		return mongo.Mongo24
	}
	return v
}
1148389
func (o *Options) IndexVersions() []zoekt.RepositoryBranch {
	fn := o.shardName(0)

	f, err := os.Open(fn)
	if err != nil {
		return nil
	}

	iFile, err := zoekt.NewIndexFile(f)
	if err != nil {
		return nil
	}
	defer iFile.Close()

	repo, index, err := zoekt.ReadMetadata(iFile)
	if err != nil {
		return nil
	}

	if index.IndexFeatureVersion != zoekt.FeatureVersion {
		return nil
	}

	if repo.IndexOptions != o.HashOptions() {
		return nil
	}

	return repo.Branches
}
52556
func openVersionedLevelDB(log logger.Logger, storageRoot string,
	dbFolderName string, currentDiskCacheVersion uint64, dbFilename string) (
	db *LevelDb, err error) {
	dbPath := filepath.Join(storageRoot, dbFolderName)
	versionPath, err := getVersionedPathForDiskCache(
		log, dbPath, dbFolderName, currentDiskCacheVersion)
	if err != nil {
		return nil, err
	}
	p := filepath.Join(versionPath, dbFilename)
	log.Debug("opening LevelDB: %s", p)
	storage, err := storage.OpenFile(p, false)
	if err != nil {
		return nil, err
	}
	defer func() {
		if err != nil {
			storage.Close()
		}
	}()
	options := *leveldbOptions
	if db, err = openLevelDBWithOptions(storage, &options); err != nil {
		return nil, err
	}
	return db, nil
}
224375
func (j *Job) GetJobVersions(args *structs.JobVersionsRequest,
	reply *structs.JobVersionsResponse) error {
	if done, err := j.srv.forward("Job.GetJobVersions", args, args, reply); done {
		return err
	}
	defer metrics.MeasureSince([]string{"nomad", "job", "get_job_versions"}, time.Now())

	// Check for read-job permissions
	if aclObj, err := j.srv.ResolveToken(args.AuthToken); err != nil {
		return err
	} else if aclObj != nil && !aclObj.AllowNsOp(args.RequestNamespace(), acl.NamespaceCapabilityReadJob) {
		return structs.ErrPermissionDenied
	}

	// Setup the blocking query
	opts := blockingOptions{
		queryOpts: &args.QueryOptions,
		queryMeta: &reply.QueryMeta,
		run: func(ws memdb.WatchSet, state *state.StateStore) error {
			// Look for the job
			out, err := state.JobVersionsByID(ws, args.RequestNamespace(), args.JobID)
			if err != nil {
				return err
			}

			// Setup the output
			reply.Versions = out
			if len(out) != 0 {
				reply.Index = out[0].ModifyIndex

				// Compute the diffs
				if args.Diffs {
					for i := 0; i < len(out)-1; i++ {
						old, new := out[i+1], out[i]
						d, err := old.Diff(new, true)
						if err != nil {
							return fmt.Errorf("failed to create job diff: %v", err)
						}
						reply.Diffs = append(reply.Diffs, d)
					}
				}
			} else {
				// Use the last index that affected the nodes table
				index, err := state.Index("job_version")
				if err != nil {
					return err
				}
				reply.Index = index
			}

			// Set the query response
			j.srv.setQueryMeta(&reply.QueryMeta)
			return nil
		}}
	return j.srv.blockingRPC(&opts)
}