blob: 6869bc18b4a86329f6c535770c9a3767bf1b581e [file] [log] [blame]
// Copyright 2018 The LUCI 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 model
import (
"crypto/sha256"
"encoding/json"
"fmt"
"sort"
"time"
"go.chromium.org/luci/common/data/strpair"
)
// PoolDescriptor describes the attributes of a pool in "tag:value" format.
// This is defined as Swarming Dimensions + Hostname.
type PoolDescriptor []string
// SwarmingHostnameKey is a magic PoolDescriptor tag containing the Swarming Hostname.
const SwarmingHostnameKey = "swarming_hostname"
// NewPoolDescriptor creates a new PoolDescriptor given a swarming hostname
// and a slice of dimensions. The dimensions are expected to be in "key:value" format,
// where the key is the tag name. This is the same format returned by the Swarming API.
func NewPoolDescriptor(host string, dimensions []string) PoolDescriptor {
desc := make([]string, 0, len(dimensions)+1)
desc = append(desc, fmt.Sprintf("%s:%s", SwarmingHostnameKey, host))
desc = append(desc, dimensions...)
sort.Strings(desc)
return desc
}
// PoolID returns they ID for a BotPool with the specified PoolDescriptor.
// The ID is a SHA256 hash in hex form.
// descriptor must be pre-sorted (I.E. Created with NewPoolDescriptor).
func (d PoolDescriptor) PoolID() string {
s, err := json.Marshal(d)
if err != nil {
// This should never happen for a slice of strings.
panic(err)
}
return fmt.Sprintf("%x", sha256.Sum256(s))
}
// Host returns the swarming_hostname item of the PoolDescriptor.
func (d PoolDescriptor) Host() string {
return strpair.ParseMap(d).Get(SwarmingHostnameKey)
}
// Dimensions returns a copy of the PoolDescriptor without the swarming_hostname item
// in strpair.Map format.
func (d PoolDescriptor) Dimensions() strpair.Map {
m := strpair.ParseMap(d)
m.Del(SwarmingHostnameKey)
return m
}
// BotPoolKind is the name of the datastore entity kind of BotPool.
const BotPoolKind = "BotPool"
// BotPool is the execution pool information associated with a
// set of Swarming bots. This information is periodically refreshed from Swarming.
type BotPool struct {
// PoolID is an identifier for the BotPool.
// PoolID must match the Descriptor.
// This field should always be constructed with PoolID().
PoolID string `gae:"$id"`
// Descriptor uniquely describes this BotPool.
// It is defined as Swarming Dimensions + Hostname.
Descriptor PoolDescriptor
// Bots is a slice of bots in the pool, along with their statuses.
Bots []Bot `gae:",noindex"`
// LastUpdate is when this entity was last updated.
LastUpdate time.Time
}
// Bot represents a single job executor.
type Bot struct {
// Name is an identifier for the Bot. This is usually a short hostname.
Name string
// URL is a link to a bot page, if available.
URL string
// Status is the current status of the Bot.
Status BotStatus
// LastSeen denotes when the Bot was last seen.
LastSeen time.Time
}