Documentation
¶
Overview ¶
Package htcondor provides a Go client library for HTCondor. This file adds helpers for locating a peer daemon by its address file.
Package htcondor provides HTCondor job submission functionality.
Index ¶
- Constants
- Variables
- func AddressFilePath(cfg *config.Config, subsys string) string
- func DecodePageToken(token string) (int64, int64, error)
- func DefaultCollectorProjection() []string
- func DefaultEpochProjection() []string
- func DefaultHistoryProjection() []string
- func DefaultJobProjection() []string
- func DefaultTransferProjection() []string
- func DialSinful(ctx context.Context, address string, secConfig *security.SecurityConfig, ...) (*client.HTCondorClient, error)
- func EncodePageToken(clusterID, procID int64) string
- func FileAddressResolver(path string) func() (string, error)
- func GetAuthenticatedUserFromContext(ctx context.Context) string
- func GetCommandCodes() struct{ ... }
- func GetDefaultConfig() *config.Config
- func GetSecurityConfig(cfg *config.Config, command int, context string) (*security.SecurityConfig, error)
- func GetSecurityConfigFromContext(ctx context.Context) (security.SecurityConfig, bool)
- func GetSecurityConfigOrDefault(ctx context.Context, cfg *config.Config, command int, secContext string, ...) (*security.SecurityConfig, error)
- func GetServerSecurityConfig(cfg *config.Config, command int, secContext string) (*security.SecurityConfig, error)
- func IsDaemonFallbackRefused(err error) bool
- func LoadSigningKeys(cfg *config.Config) (map[string][]byte, error)
- func LocalDaemonAddress(cfg *config.Config, subsys string) (func() (string, error), string, error)
- func LookupSSLClientCredentials() (certFile, keyFile, caFile string, ok bool)
- func LookupSSLClientCredentialsWithConfig(cfg *config.Config) (certFile, keyFile, caFile string, ok bool)
- func NewClientSecurityConfig(ctx context.Context, token string, peerName string, command int, ...) (*security.SecurityConfig, error)
- func NewClientSecurityConfigWithConfig(ctx context.Context, cfg *config.Config, token string, peerName string, ...) (*security.SecurityConfig, error)
- func ParseAdvertiseCommand(cmd string) (commands.CommandType, bool)
- func ParseJobID(s string) (int, int, error)
- func ReadAddressFile(path string) (string, error)
- func ReloadDefaultConfig()
- func ResetRescheduleLimiter()
- func SSHToJobHarnessConfig() (string, bool)
- func SSHToJobPrereqs() (sshd string, configTemplate string, ok bool)
- func SetUnmarkedOriginPolicy(p UnmarkedOriginPolicy)
- func SetUnmarkedOriginReporter(fn func(command int, secContext, peerName string))
- func SpoolInputAllowSet(ad *classad.ClassAd) []string
- func ValidateAttributeForEdit(attrName string, opts *EditJobOptions) error
- func ValidateOAuthCredential(service string, cred []byte) error
- func WithAuthenticatedUser(ctx context.Context, username string) context.Context
- func WithDaemonCredential(ctx context.Context, reason string) context.Context
- func WithRenewableSecurityConfig(ctx context.Context, secConfig *security.SecurityConfig, ...) context.Context
- func WithSecurityConfig(ctx context.Context, secConfig *security.SecurityConfig) context.Context
- func WithUserRequest(ctx context.Context, reason string) context.Context
- func WithoutSecurityConfig(ctx context.Context) context.Context
- type ActionResult
- type ActionResultType
- type AdResult
- type AdvertiseError
- type AdvertiseOptions
- type AggregateRow
- type CCBDialer
- type CCBDialerConfig
- type CCBReverseRouter
- type CallerCredential
- type CedarCredd
- func (c *CedarCredd) CheckCreds(ctx context.Context, requests []CredRequest) (string, error)
- func (c *CedarCredd) DeleteServiceCred(ctx context.Context, credType CredType, service string, handle string, ...) error
- func (c *CedarCredd) DeleteUserCred(ctx context.Context, credType CredType, user string) error
- func (c *CedarCredd) GetCredential(ctx context.Context, credType CredType, service string, handle string, ...) ([]byte, error)
- func (c *CedarCredd) GetServiceCredStatus(ctx context.Context, credType CredType, service string, handle string, ...) (CredentialStatus, error)
- func (c *CedarCredd) GetUserCredStatus(ctx context.Context, credType CredType, user string) (CredentialStatus, error)
- func (c *CedarCredd) ListServiceCreds(ctx context.Context, credType CredType, user string) ([]ServiceStatus, error)
- func (c *CedarCredd) PutServiceCred(ctx context.Context, credType CredType, credential []byte, service string, ...) error
- func (c *CedarCredd) PutUserCred(ctx context.Context, credType CredType, credential []byte, user string) error
- func (c *CedarCredd) WithConfig(cfg *config.Config) *CedarCredd
- type CheckCredsRefusal
- type Collector
- func (c *Collector) Address() string
- func (c *Collector) Addresses() []string
- func (c *Collector) Advertise(ctx context.Context, ad *classad.ClassAd, opts *AdvertiseOptions) error
- func (c *Collector) AdvertiseMultiple(ctx context.Context, ads []*classad.ClassAd, opts *AdvertiseOptions) []error
- func (c *Collector) LocateDaemon(ctx context.Context, daemonType DaemonType, name string) (*DaemonLocation, error)
- func (c *Collector) Ping(ctx context.Context) (*PingResult, error)
- func (c *Collector) PingWithOptions(ctx context.Context, opts *PingOptions) (*PingResult, error)
- func (c *Collector) QueryAds(ctx context.Context, adType string, constraint string) ([]*classad.ClassAd, error)deprecated
- func (c *Collector) QueryAdsStream(ctx context.Context, adType string, constraint string, projection []string, ...) (<-chan AdResult, error)
- func (c *Collector) QueryAdsWithOptions(ctx context.Context, adType string, constraint string, opts *QueryOptions) ([]*classad.ClassAd, *PageInfo, error)
- func (c *Collector) QueryAdsWithProjection(ctx context.Context, adType string, constraint string, projection []string) ([]*classad.ClassAd, error)deprecated
- func (c *Collector) WatchAds(ctx context.Context, adType, constraint string, cursor []byte) (<-chan WatchEvent, error)
- func (c *Collector) WithConfig(cfg *config.Config) *Collector
- func (c *Collector) WithRaceStagger(stagger time.Duration) *Collector
- type CondorTestHarness
- func (h *CondorTestHarness) GetCollectorAddr() string
- func (h *CondorTestHarness) GetConfig() (*config.Config, error)
- func (h *CondorTestHarness) GetConfigFile() string
- func (h *CondorTestHarness) GetLockDir() string
- func (h *CondorTestHarness) GetLogDir() string
- func (h *CondorTestHarness) GetPasswordDir() string
- func (h *CondorTestHarness) GetScheddName() string
- func (h *CondorTestHarness) GetSigningKeyPath() string
- func (h *CondorTestHarness) GetSpoolDir() string
- func (h *CondorTestHarness) GetTrustDomain() string
- func (h *CondorTestHarness) PrintCollectorLog()
- func (h *CondorTestHarness) PrintScheddLog()
- func (h *CondorTestHarness) PrintShadowLog()
- func (h *CondorTestHarness) PrintStartdLog()
- func (h *CondorTestHarness) PrintStarterLogs()
- func (h *CondorTestHarness) Shutdown()
- func (h *CondorTestHarness) WaitForDaemons() error
- func (h *CondorTestHarness) WaitForSchedd(timeout time.Duration) error
- func (h *CondorTestHarness) WaitForStartd(timeout time.Duration) error
- type CredRequest
- type CredType
- type CreddClient
- type CredentialCache
- type CredentialOrigin
- type CredentialReloader
- type CredentialStatus
- type DaemonLocation
- type DaemonType
- type DialOptions
- type EditJobOptions
- type ErrDaemonFallbackRefused
- type FileTransferClient
- type FileTransferItem
- type FileTransferServer
- type HistoryAdResult
- type HistoryQueryOptions
- func (opts *HistoryQueryOptions) ApplyDefaults() HistoryQueryOptions
- func (opts *HistoryQueryOptions) GetEffectiveProjection() []string
- func (opts *HistoryQueryOptions) IsUnlimited() bool
- func (opts *HistoryQueryOptions) ShouldUseAllAttributes() bool
- func (opts *HistoryQueryOptions) ShouldUseDefaultProjection() bool
- type HistoryRecordSource
- type HistoryScanStats
- type InMemoryCredd
- func (c *InMemoryCredd) CheckCreds(ctx context.Context, requests []CredRequest) (string, error)
- func (c *InMemoryCredd) DeleteServiceCred(ctx context.Context, credType CredType, service string, handle string, ...) error
- func (c *InMemoryCredd) DeleteUserCred(ctx context.Context, credType CredType, user string) error
- func (c *InMemoryCredd) GetCredential(ctx context.Context, credType CredType, service string, handle string, ...) ([]byte, error)
- func (c *InMemoryCredd) GetServiceCredStatus(ctx context.Context, credType CredType, service string, handle string, ...) (CredentialStatus, error)
- func (c *InMemoryCredd) GetUserCredStatus(ctx context.Context, credType CredType, user string) (CredentialStatus, error)
- func (c *InMemoryCredd) ListServiceCreds(ctx context.Context, credType CredType, user string) ([]ServiceStatus, error)
- func (c *InMemoryCredd) PutServiceCred(ctx context.Context, credType CredType, credential []byte, service string, ...) error
- func (c *InMemoryCredd) PutUserCred(ctx context.Context, credType CredType, credential []byte, user string) error
- type JobAction
- type JobActionRefusedError
- type JobActionResults
- type JobAdResult
- type JobConnectInfo
- type JobID
- type JobShellOptions
- type KeepAliveOptions
- type Master
- func (m *Master) Address() string
- func (m *Master) DaemonName() string
- func (m *Master) ParentPID() int
- func (m *Master) SendKeepAlive(ctx context.Context, opts *KeepAliveOptions) error
- func (m *Master) SendReady(ctx context.Context, opts *ReadyOptions) error
- func (m *Master) SetDaemonName(name string)
- func (m *Master) StartKeepAlive(ctx context.Context, opts *KeepAliveOptions) (stop func(), errs <-chan error, err error)
- func (m *Master) WithConfig(cfg *config.Config) *Master
- type OutputRemap
- type PageInfo
- type PeekRequest
- type PeekResult
- type PeekedStream
- type PingOptions
- type PingResult
- type PlacementAuthorization
- type PlacementError
- type PlacementLoginRequest
- type PlacementLoginResult
- type PlacementToken
- type PlacementTokenQuery
- type PlacementUser
- type Placementd
- func (p *Placementd) Address() string
- func (p *Placementd) Login(ctx context.Context, req PlacementLoginRequest) (*PlacementLoginResult, error)
- func (p *Placementd) QueryAuthorizations(ctx context.Context, userName string) ([]PlacementAuthorization, error)
- func (p *Placementd) QueryTokens(ctx context.Context, query PlacementTokenQuery) ([]PlacementToken, error)
- func (p *Placementd) QueryUsers(ctx context.Context, userName string) ([]PlacementUser, error)
- func (p *Placementd) WithConfig(cfg *config.Config) *Placementd
- type PlacementdClient
- type QmgmtConnection
- func (q *QmgmtConnection) AbortTransaction(ctx context.Context) error
- func (q *QmgmtConnection) BeginTransaction(ctx context.Context) error
- func (q *QmgmtConnection) Close() error
- func (q *QmgmtConnection) CommitTransaction(ctx context.Context) error
- func (q *QmgmtConnection) DestroyCluster(ctx context.Context, clusterID int) error
- func (q *QmgmtConnection) NewCluster(ctx context.Context) (int, error)
- func (q *QmgmtConnection) NewProc(ctx context.Context, clusterID int) (int, error)
- func (q *QmgmtConnection) SendJobAttributes(ctx context.Context, clusterID, procID int, ad *classad.ClassAd) error
- func (q *QmgmtConnection) SetAttribute(ctx context.Context, clusterID, procID int, attrName, attrValue string, ...) error
- func (q *QmgmtConnection) SetAttributeInt(ctx context.Context, clusterID, procID int, attrName string, value int, ...) error
- func (q *QmgmtConnection) SetEffectiveOwner(ctx context.Context, owner string) error
- type QueryFetchOpts
- type QueryOptions
- type ReadyOptions
- type RescheduleOptions
- type Schedd
- func (s *Schedd) Address() string
- func (s *Schedd) AggregateJobs(ctx context.Context, constraint string, groupBy []string, opts *QueryOptions) ([]AggregateRow, error)
- func (s *Schedd) ConfigVal(ctx context.Context, name string) (value string, ok bool, err error)
- func (s *Schedd) CreateStartupLimit(ctx context.Context, req *StartupLimitRequest) (string, error)
- func (s *Schedd) EditJob(ctx context.Context, clusterID, procID int, attributes map[string]string, ...) error
- func (s *Schedd) EditJobAttributes(ctx context.Context, clusterID, procID int, attributes *classad.ClassAd, ...) error
- func (s *Schedd) EditJobByID(ctx context.Context, jobID string, attributes map[string]string, ...) error
- func (s *Schedd) EditJobs(ctx context.Context, constraint string, attributes map[string]string, ...) (int, error)
- func (s *Schedd) GetJobConnectInfo(ctx context.Context, clusterID, procID int) (*JobConnectInfo, error)
- func (s *Schedd) GetUserRecord(ctx context.Context, user string) (*UserRecord, error)
- func (s *Schedd) HoldJobs(ctx context.Context, constraint string, reason string) (*JobActionResults, error)
- func (s *Schedd) Name() string
- func (s *Schedd) OpenJobShell(ctx context.Context, clusterID, procID int, opts *JobShellOptions) (*ssh.Client, error)
- func (s *Schedd) PeekJobOutput(ctx context.Context, cluster, proc int, req PeekRequest) (*PeekResult, error)
- func (s *Schedd) Ping(ctx context.Context) (*PingResult, error)
- func (s *Schedd) PingWithOptions(ctx context.Context, opts *PingOptions) (*PingResult, error)
- func (s *Schedd) Query(ctx context.Context, constraint string, projection []string) ([]*classad.ClassAd, error)deprecated
- func (s *Schedd) QueryHistory(ctx context.Context, constraint string, projection []string) ([]*classad.ClassAd, error)
- func (s *Schedd) QueryHistoryStream(ctx context.Context, constraint string, opts *HistoryQueryOptions, ...) (<-chan HistoryAdResult, error)
- func (s *Schedd) QueryHistoryWithOptions(ctx context.Context, constraint string, opts *HistoryQueryOptions) ([]*classad.ClassAd, error)
- func (s *Schedd) QueryStartupLimits(ctx context.Context, uuid, tag string) ([]*StartupLimit, error)
- func (s *Schedd) QueryStream(ctx context.Context, constraint string, projection []string, ...) (<-chan JobAdResult, error)deprecated
- func (s *Schedd) QueryStreamWithOptions(ctx context.Context, constraint string, opts *QueryOptions, ...) (<-chan JobAdResult, error)
- func (s *Schedd) QueryUserRecords(ctx context.Context, opts *UserRecordQueryOptions) (records []UserRecord, err error)
- func (s *Schedd) QueryWithOptions(ctx context.Context, constraint string, opts *QueryOptions) ([]*classad.ClassAd, *PageInfo, error)
- func (s *Schedd) QueueSuperUsers(ctx context.Context) ([]string, error)
- func (s *Schedd) ReceiveJobSandbox(ctx context.Context, constraint string, w io.Writer) <-chan error
- func (s *Schedd) ReleaseJobs(ctx context.Context, constraint string, reason string) (*JobActionResults, error)
- func (s *Schedd) RemoveJobs(ctx context.Context, constraint string, reason string) (*JobActionResults, error)
- func (s *Schedd) RemoveJobsByID(ctx context.Context, ids []string, reason string) (*JobActionResults, error)
- func (s *Schedd) Reschedule(ctx context.Context) error
- func (s *Schedd) RescheduleWithOptions(ctx context.Context, opts *RescheduleOptions) error
- func (s *Schedd) SpoolJobFilesFromFS(ctx context.Context, jobAds []*classad.ClassAd, fsys fs.FS) error
- func (s *Schedd) SpoolJobFilesFromTar(ctx context.Context, jobAds []*classad.ClassAd, r io.Reader) error
- func (s *Schedd) Submit(ctx context.Context, submitFileContent string) (string, error)
- func (s *Schedd) SubmitRemote(ctx context.Context, submitFileContent string) (clusterID int, procAds []*classad.ClassAd, err error)
- func (s *Schedd) WithConfig(cfg *config.Config) *Schedd
- func (s *Schedd) WithRateLimitKey(key string) *Schedd
- type ScheddTarget
- type SecurityConfigRenewer
- type ServiceStatus
- type SetAttributeFlags
- type Startd
- func (s *Startd) Address() string
- func (s *Startd) Name() string
- func (s *Startd) QueryHistory(ctx context.Context, constraint string, projection []string) ([]*classad.ClassAd, error)
- func (s *Startd) QueryHistoryStream(ctx context.Context, constraint string, opts *HistoryQueryOptions, ...) (<-chan HistoryAdResult, error)
- func (s *Startd) QueryHistoryWithOptions(ctx context.Context, constraint string, opts *HistoryQueryOptions) ([]*classad.ClassAd, error)
- func (s *Startd) WithConfig(cfg *config.Config) *Startd
- type StartupLimit
- type StartupLimitRequest
- type StartupLimitResponse
- type StreamOptions
- type SubmitFile
- func (sf *SubmitFile) MakeClusterAd(clusterID int) (*classad.ClassAd, error)
- func (sf *SubmitFile) MakeJobAd(jobID JobID, queueVars map[string]string) (*classad.ClassAd, error)
- func (sf *SubmitFile) MakeProcAd(clusterID int, procID int, queueVars map[string]string) (*classad.ClassAd, error)
- func (sf *SubmitFile) Submit(clusterID int) (*SubmitResult, error)
- func (sf *SubmitFile) SubmitLate(clusterID int) (*SubmitResult, error)
- type SubmitIterator
- type SubmitParseOptions
- type SubmitResult
- type TestingT
- type TransferCommand
- type TransferType
- type UnmarkedOriginPolicy
- type UserRecord
- type UserRecordQueryOptions
- type WatchEvent
Constants ¶
const ( // MaxAdvertiseBufferSize is the maximum buffer size for multiple ad advertisements (1MB) MaxAdvertiseBufferSize = 1024 * 1024 // DefaultMyAddress is the default MyAddress value for ads without one set DefaultMyAddress = "<127.0.0.1:0>" // AvgBytesPerAttribute is the estimated average size per ClassAd attribute for buffer management AvgBytesPerAttribute = 100 )
const ( StartdAdType = "StartdAd" ScheddAdType = "ScheddAd" MasterAdType = "MasterAd" SubmitterAdType = "SubmitterAd" LicenseAdType = "LicenseAd" CollectorAdType = "CollectorAd" NegotiatorAdType = "NegotiatorAd" AccountingAdType = "AccountingAd" StorageAdType = "StorageAd" GridAdType = "GridAd" HADAdType = "HADAd" // StartdPrivateAdType is the startd's private ad (MyType // "MachinePrivate"), queried via QUERY_STARTD_PVT_ADS. StartdPrivateAdType = "StartdPrivateAd" // CkptServerAdType is the (legacy) checkpoint server ad. Standard // universe is gone, so this is rarely present, but the collector // query command still exists. CkptServerAdType = "CkptServerAd" // PlacementdAdType is the placementd's ad. Unlike the types above it is // the MyType the daemon publishes verbatim, because the collector stores // placementd ads as generic ads keyed by that name. PlacementdAdType = "PlacementD" // AnyAdType is a catch-all: it queries the collector for every ad type // (QUERY_ANY_ADS) rather than one specific kind. AnyAdType = "Any" )
Ad type names accepted as the adType argument by the collector query methods (QueryAds, QueryAdsWithProjection, QueryAdsWithOptions, QueryAdsStream). Each names the ad a daemon advertises — a schedd advertises a ScheddAd, whose MyType is "Scheduler" — and selects the matching collector query. The daemon-type spellings (e.g. "Schedd") are also accepted, but prefer these constants.
They are plain string constants so they drop into the existing adType string parameters without a conversion.
const ( // StoreCred is the main credential storage command (SCHED_VERS+79 = 479) // This is what store_cred_handler uses StoreCred = 479 // SCHED_VERS+79 CreddGetToken = 81004 // CREDD_BASE+4 CreddCheckCreds = 81030 // CREDD_BASE+30 )
Command codes for credd daemon (from condor_commands.h) HTCondor command codes
const ( ModeMask = 3 GenericAdd = 0 GenericDelete = 1 GenericQuery = 2 StoreCredUserKrb = 0x20 StoreCredUserOAuth = 0x28 StoreCredLegacy = 0x40 AddOAuthMode = StoreCredUserOAuth | GenericAdd DeleteOAuthMode = StoreCredUserOAuth | GenericDelete QueryOAuthMode = StoreCredUserOAuth | GenericQuery AddKrbMode = StoreCredUserKrb | GenericAdd DeleteKrbMode = StoreCredUserKrb | GenericDelete QueryKrbMode = StoreCredUserKrb | GenericQuery )
Mode constants for StoreCred command (from store_cred.h)
const ( Success = 1 Failure = 0 FailureBadPassword = 2 FailureNotSecure = 4 FailureNotFound = 5 SuccessPending = 6 FailureNotAllowed = 7 FailureBadArgs = 8 FailureConfigError = 11 )
Return codes from store_cred operations (from store_cred.h)
const ( // FailureNoImpersonate means user switching is not supported. FailureNoImpersonate = 3 // FailureProtocolMismatch means client and server disagreed about // what should have been sent on the wire. FailureProtocolMismatch = 9 // FailureCredmonTimeout means the credmon did not process the // credential within its timeout. FailureCredmonTimeout = 10 // FailureJSONParse means the stored credential could not be parsed // as JSON. An OAuth service credential is a JSON document, and the // credd re-parses it when a query names a specific service -- so a // credential stored as something else is written without complaint // and then fails every read of it thereafter. FailureJSONParse = 12 // FailureCredMismatch means a credential was found but did not match // the requested scopes or audience. FailureCredMismatch = 13 // FailureUntrustedHost means the credential would require contacting // a host the credd does not trust. FailureUntrustedHost = 14 )
Return codes the credd sends back from a store or query, from HTCondor's store_cred.h. The ones this package already names (Success, FailureNotFound, ...) are declared in credd_client.go; these fill in the rest so an error can say what happened instead of quoting a number.
const ( DCChildAlive = 60008 // DC_CHILDALIVE: child keepalive to parent DCSetReady = 60043 // DC_SET_READY: daemon signals startup readiness DCQueryReady = 60044 // DC_QUERY_READY: master readiness query (reserved for future use) )
DC command identifiers used by the master for daemon lifecycle signaling.
const ( DCNopRead = commands.DC_NOP_READ DCNopWrite = commands.DC_NOP_WRITE DCNopNegotiator = commands.DC_NOP_NEGOTIATOR DCNopAdministrator = commands.DC_NOP_ADMINISTRATOR DCNopOwner = commands.DC_NOP_OWNER DCNopConfig = commands.DC_NOP_CONFIG DCNopDaemon = commands.DC_NOP_DAEMON DCNopAdvertiseStartd = commands.DC_NOP_ADVERTISE_STARTD DCNopAdvertiseSchedd = commands.DC_NOP_ADVERTISE_SCHEDD DCNopAdvertiseMaster = commands.DC_NOP_ADVERTISE_MASTER )
Permission levels for DC_SEC_QUERY authorization checking. These are sent as AuthCommand during the security handshake.
The values come from cedar's commands package rather than being written out here. They were previously hardcoded and every one from READ through ADMINISTRATOR was off by one — DC_NOP_OWNER (DC_BASE+24) was missing from the list, so DCNopRead asked the daemon about WRITE, DCNopWrite about NEGOTIATOR, and DCNopAdministrator about OWNER. The mistake was invisible because PingWithOptions never read the daemon's answer (see PingResult. Authorized), so nothing depended on asking the right question.
const ( // PlacementUserLogin requests an IDToken for a foreign user identity. PlacementUserLogin = commands.SCHED_VERS + 155 // PlacementQueryUsers lists the users the placementd knows about. PlacementQueryUsers = commands.SCHED_VERS + 156 // PlacementQueryTokens lists the tokens the placementd has issued. PlacementQueryTokens = commands.SCHED_VERS + 157 // PlacementQueryAuthorizations lists the authorizations the placementd // can grant, optionally narrowed to those a single user may request. PlacementQueryAuthorizations = commands.SCHED_VERS + 158 )
Command codes for the placement daemon (condor_placementd), from condor_commands.h. They are defined here rather than in cedar's commands package because the placementd is new enough that cedar has not enumerated them; the values are the stable wire numbers.
const ( // PlacementErrNotEncrypted means the request arrived unencrypted. The // daemon refuses to mint a token over a channel that would expose it. PlacementErrNotEncrypted = 1 // PlacementErrMissingUserName means the request carried no UserName. PlacementErrMissingUserName = 2 // PlacementErrUserNotAuthorized means the user is absent from the // placementd's map file. PlacementErrUserNotAuthorized = 3 // PlacementErrAuthorizationDenied means the user asked for an // authorization their map-file entry does not grant. PlacementErrAuthorizationDenied = 4 // PlacementErrUserMappingExpired means the user's map-file entry has an // expiration in the past. PlacementErrUserMappingExpired = 6 // PlacementErrRequesterUnknown means a login made on another user's // behalf named a requester absent from the map file. PlacementErrRequesterUnknown = 7 // PlacementErrRequesterNotInstructor means the requester exists but // lacks the INSTRUCTOR authorization needed to act for someone else. PlacementErrRequesterNotInstructor = 8 // PlacementErrRequesterMappingExpired means the requester's own // map-file entry has expired. PlacementErrRequesterMappingExpired = 9 // PlacementErrProjectNotAuthorized means the user's map-file entry does // not list the requested project. PlacementErrProjectNotAuthorized = 10 // PlacementErrDatabase means the placementd could not record the issued // token in its sqlite database. No token is returned in that case even // though one was minted. PlacementErrDatabase = 11 // PlacementErrSchedd means the schedd leg of a login failed: the schedd // could not be located or queried, or the user or project record there // exists but is disabled. PlacementErrSchedd = 12 )
Error codes the placementd assigns to its own failures (placementd.cpp). The daemon also forwards CondorError codes from the schedd verbatim, so a code outside this set is a schedd-side error, not one of these.
const ( AttrStartupLimitUUID = "StartupLimitUUID" AttrStartupLimitTag = "StartupLimitTag" AttrStartupLimitName = "StartupLimitName" AttrStartupLimitExpr = "StartupLimitExpression" AttrStartupLimitCostExpr = "StartupLimitRateCost" AttrStartupLimitRateCount = "StartupLimitRateCount" AttrStartupLimitRateWindow = "StartupLimitRateWindow" AttrStartupLimitBurst = "StartupLimitRateBurst" AttrStartupLimitMaxBurstCost = "StartupLimitRateBurstMaxCost" AttrStartupLimitExpiration = "StartupLimitExpiration" AttrStartupLimitStatus = "StartupLimitStatus" AttrStartupLimitError = "StartupLimitError" AttrStartupLimitJobsAllowed = "StartupLimitJobsAllowed" AttrStartupLimitCostAllowed = "StartupLimitCostAllowed" AttrStartupLimitJobsSkipped = "StartupLimitJobsSkipped" AttrStartupLimitMatchesIgnored = "StartupLimitMatchesIgnored" AttrStartupLimitLastIgnored = "StartupLimitLastIgnoredTime" AttrStartupLimitIgnoredUsers = "StartupLimitIgnoredSources" )
ClassAd attribute names for startup limits
const ( CONDOR_NewCluster = qmgmt.OpNewCluster CONDOR_NewProc = qmgmt.OpNewProc CONDOR_DestroyCluster = qmgmt.OpDestroyCluster CONDOR_SetAttribute = qmgmt.OpSetAttribute CONDOR_SetAttribute2 = qmgmt.OpSetAttribute2 CONDOR_BeginTransaction = qmgmt.OpBeginTransaction CONDOR_CommitTransactionNoFlags = qmgmt.OpCommitTransactionNoFlags CONDOR_CommitTransaction = qmgmt.OpCommitTransaction CONDOR_AbortTransaction = qmgmt.OpAbortTransaction CONDOR_SetEffectiveOwner = qmgmt.OpSetEffectiveOwner CONDOR_GetCapabilities = qmgmt.OpGetCapabilities CONDOR_CloseSocket = qmgmt.OpCloseSocket QMGMT_WRITE_CMD = qmgmt.WriteCmd )
QMGMT Protocol Commands. The canonical definitions now live in the qmgmt codec package (shared with the server); these names are kept for backward compatibility and match HTCondor's C++ naming convention.
const ( UniverseMin = 0 UniverseStandard = 1 UniverseVanilla = 5 UniverseScheduler = 7 UniverseGrid = 9 UniverseJava = 10 UniverseParallel = 11 UniverseLocal = 12 UniverseVM = 13 )
Universe constants matching HTCondor
const DefaultCCBLearnedTTL = 15 * time.Minute
DefaultCCBLearnedTTL is how long a CCBDialer trusts what it learned about a broker. It is a compromise: long enough that a busy server is not re-measuring the same broker all day, short enough that a firewall change or a broker upgrade is picked up without a restart.
const DefaultCollectorRaceStagger = 150 * time.Millisecond
DefaultCollectorRaceStagger is the time between successive per-address connect attempts. 150 ms matches the inner v4/v6 happy-eyeballs cadence the user-facing dialer should be running.
const DefaultHistoryScanLimit = 10000
DefaultHistoryScanLimit is the ScanLimit a history query uses when the caller sets none: the daemon examines at most this many records, newest first, before it stops looking for matches.
const DefaultPeekMaxBytes = 64 * 1024
DefaultPeekMaxBytes is the per-call cap when the caller doesn't supply one. The C++ tool defaults to 1024 to be friendly on terminals; for a UI poll we want enough for a useful snapshot while still keeping each round-trip cheap.
const DefaultRescheduleInterval = 5 * time.Second
DefaultRescheduleInterval is the minimum wall-clock gap between successful Reschedule calls to the same schedd address.
Five seconds matches the typical NEGOTIATOR_INTERVAL operators configure for low-latency pools and stays well clear of the rate at which a busy submitter loop might fire-and-forget reschedule requests — sending one after every Submit in a tight loop should not amount to DoS pressure on the schedd.
const HarnessTrustDomain = "test.htcondor.org"
HarnessTrustDomain is the TRUST_DOMAIN the harness pins, and so the `iss` a daemon must mint tokens with to be trusted by this schedd. It is a fixed string rather than the hostname the default would produce, so a test can configure a daemon to match it without first asking the harness what its hostname resolved to.
Variables ¶
var ErrCredentialNotFound = errors.New("credential not found")
ErrCredentialNotFound is returned when the requested credential does not exist.
var ErrInvalidTarEntry = errors.New("invalid tar entry name")
ErrInvalidTarEntry is returned (wrapped) by SpoolJobFilesFromTar when an entry's name is not a canonical path inside the sandbox. The upload is abandoned before that entry is sent and without the final command, so the schedd does not release the job.
var ErrNoJobsMatched = errors.New("no jobs matched")
ErrNoJobsMatched reports a job action whose constraint or IDs matched no job in the queue. Test for it with errors.Is; the error itself is a *JobActionRefusedError.
var ErrPaginationUnsupported = errors.New(
"the schedd cannot paginate: its job queue is a hash table with no order to resume from " +
"and no index to seek with, so each page would cost a full queue scan. " +
"Raise the limit to read more at once, narrow the constraint, or query an htcondordb mirror")
ErrPaginationUnsupported is returned for a job query carrying a page token, because a schedd cannot be walked page by page.
Two independent reasons, either of which is enough:
There is no order to page by. QUERY_JOB_ADS walks the job queue's ClassAdLog, a HashTable, and LimitResults stops that walk early — so the jobs a page returns are an arbitrary subset of the matches, and a cursor taken from one either returns the same page forever or silently skips every job the page did not include. Imposing an order on this side means sorting every match, which is only possible by fetching every match.
And there is no index to make the next page cheap. filter_iterator (condor_utils/classad_log.h) runs that hash table from begin() to end() evaluating the constraint against every ad; matching jobs sit in whatever buckets they hash to, so no bound on ClusterId prunes anything. Every page costs a full queue walk, which means walking a queue in P pages costs the schedd P full walks where reading it once costs one. Pagination against a schedd is more load than the thing it exists to avoid.
Where pagination does work is an htcondordb mirror: it resumes from a storage cursor against a snapshot, with no scan and no reordering (see webapi/dbmirror). Callers with no mirror raise the limit, narrow the constraint, or use a server-side aggregate for counts.
Functions ¶
func AddressFilePath ¶ added in v0.10.0
AddressFilePath returns where subsys writes its address file: the <SUBSYS>_ADDRESS_FILE config value if set, otherwise $(LOG)/.<subsys>_address (the HTCondor default). It returns "" when neither is resolvable (no override and LOG unset). subsys is the upper-case subsystem name (e.g. "HTCONDORDB", "COLLECTOR").
A DaemonCore daemon writes its current contact address to this file as a single-line sinful string. That address is NOT stable: under shared port it carries a per-run socket token that changes every time condor_master restarts the daemon, so a client that caches the address once goes stale on restart. Pair this with FileAddressResolver so a reconnecting client re-reads the file and follows a restarted daemon automatically.
func DecodePageToken ¶ added in v0.0.4
DecodePageToken decodes a base64 page token to cluster and proc IDs Returns cluster ID, proc ID, and error if decoding fails
func DefaultCollectorProjection ¶ added in v0.0.4
func DefaultCollectorProjection() []string
DefaultCollectorProjection returns the default list of collector ad attributes
func DefaultEpochProjection ¶ added in v0.0.4
func DefaultEpochProjection() []string
DefaultEpochProjection returns the default list of attributes for job epoch history
func DefaultHistoryProjection ¶ added in v0.0.4
func DefaultHistoryProjection() []string
DefaultHistoryProjection returns the default list of attributes for job history
func DefaultJobProjection ¶ added in v0.0.4
func DefaultJobProjection() []string
DefaultJobProjection returns the default list of job attributes to include in query results
func DefaultTransferProjection ¶ added in v0.0.4
func DefaultTransferProjection() []string
DefaultTransferProjection returns the default list of attributes for transfer history
func DialSinful ¶ added in v0.2.0
func DialSinful(ctx context.Context, address string, secConfig *security.SecurityConfig, opts *DialOptions) (*client.HTCondorClient, error)
DialSinful establishes an authenticated connection to an HTCondor daemon named by a sinful string, transparently following the appropriate transport: direct TCP, a shared-port daemon, or — when the sinful carries a ccbid — the Condor Connection Broker.
CCB has two modes, and the default is wrong for a caller that cannot accept inbound connections. Standard mode has the private daemon dial back to the caller, so the caller must be reachable from it; streaming mode has the broker relay both directions over the request socket, so it need not be. A caller in a container or behind NAT wants opts.CCBRequireStreaming.
secConfig should be built with the existing helpers (e.g. GetSecurityConfig) for the intended command. The returned client's stream is ready for the command payload.
func EncodePageToken ¶ added in v0.0.4
EncodePageToken encodes a cluster.proc identifier as a base64 page token
func FileAddressResolver ¶ added in v0.10.0
FileAddressResolver returns a function that re-reads path (via ReadAddressFile) on every call. Give it to a client that reconnects -- e.g. a connection pool that re-dials on failure -- so each reconnect picks up the daemon's current address instead of a cached, possibly-restarted-away one. A transient read failure surfaces to the caller (which should back off and retry) rather than yielding a stale address.
func GetAuthenticatedUserFromContext ¶ added in v0.0.3
GetAuthenticatedUserFromContext retrieves the authenticated username from the context Returns empty string if not found, which will be treated as "unauthenticated"
func GetCommandCodes ¶
GetCommandCodes returns the CEDAR command codes for file transfer operations. These are defined in cedar/commands package.
func GetDefaultConfig ¶ added in v0.0.11
GetDefaultConfig returns the global default HTCondor configuration, loading it from CONDOR_CONFIG on first access. Returns nil if no config is reachable (which happens in unit tests and any process that runs outside an HTCondor install).
Exposed so callers in other packages (notably httpserver) can build SecurityConfigs that respect SEC_CLIENT_AUTHENTICATION_METHODS, AUTH_SSL_CLIENT_CERTFILE, etc., without re-implementing the loader.
func GetSecurityConfig ¶
func GetSecurityConfig(cfg *config.Config, command int, context string) (*security.SecurityConfig, error)
GetSecurityConfig creates a SecurityConfig from HTCondor configuration. It reads security-related parameters like SEC_CLIENT_AUTHENTICATION, SEC_DEFAULT_AUTHENTICATION, SEC_CLIENT_AUTHENTICATION_METHODS, etc., and maps them to the cedar SecurityConfig struct.
The function follows HTCondor's security configuration pattern:
- SEC_<context>_<feature> where context is CLIENT, READ, WRITE, etc.
- Each setting falls back along the context's chain to SEC_DEFAULT_*, as HTCondor's SecMan::getSecSetting: an ADVERTISE_* context takes SEC_DAEMON_* first (and DAEMON takes SEC_WRITE_* under LEGACY_ALLOW_SEMANTICS)
- Supports REQUIRED, PREFERRED, OPTIONAL, NEVER security levels
- Supports multiple authentication methods (SSL, KERBEROS, TOKEN, etc.)
- Supports multiple encryption methods (AES, BLOWFISH, 3DES)
Parameters:
- cfg: HTCondor configuration object
- command: The command to be executed (from cedar/commands package)
- context: Security context ("CLIENT", "READ", "WRITE", "ADMINISTRATOR", etc.)
Returns:
- *security.SecurityConfig: Cedar security configuration
- error: Any configuration error encountered
Deficiencies (to be addressed in follow-up):
- Authorization settings (ALLOW_READ, DENY_WRITE, etc.) are separate from SecurityConfig
- NEGOTIATION security level not yet mapped
func GetSecurityConfigFromContext ¶
func GetSecurityConfigFromContext(ctx context.Context) (security.SecurityConfig, bool)
GetSecurityConfigFromContext retrieves the security configuration from the context
func GetSecurityConfigOrDefault ¶ added in v0.0.3
func GetSecurityConfigOrDefault(ctx context.Context, cfg *config.Config, command int, secContext string, peerName string) (*security.SecurityConfig, error)
GetSecurityConfigOrDefault retrieves SecurityConfig from context if available, otherwise attempts to load from HTCondor configuration, and falls back to defaults.
This function provides consistent SecurityConfig creation across the module:
- Check context for existing SecurityConfig
- If not in context, use provided config or fall back to global default config
- If config available, load from HTCondor configuration
- Fall back to sensible defaults if config is not available
Parameters:
- ctx: Context that may contain SecurityConfig
- cfg: HTCondor configuration (can be nil, will use global default if available)
- command: The command code for the operation
- context: Security context ("CLIENT", "READ", "WRITE", etc.)
- peerName: Peer name for session cache (e.g., schedd address)
Returns:
- *security.SecurityConfig: Cedar security configuration
- error: Any configuration error encountered
func GetServerSecurityConfig ¶ added in v0.2.0
func GetServerSecurityConfig(cfg *config.Config, command int, secContext string) (*security.SecurityConfig, error)
GetServerSecurityConfig builds a *server-side* SecurityConfig from the HTCondor configuration. It takes the same auth/crypto methods and security levels as GetSecurityConfig (so the server enforces the pool's SEC_* policy), and additionally loads the credentials a server needs to *verify* incoming authentications rather than to present its own:
- SSL: the server certificate/key/CA (AUTH_SSL_SERVER_CERTFILE / KEYFILE / CAFILE) instead of the client ones.
- TOKEN/IDTOKENS: the signing keys used to validate presented tokens (SEC_TOKEN_POOL_SIGNING_KEY_FILE for the pool key, SEC_PASSWORD_DIRECTORY for named issuer keys), the trust domain (TRUST_DOMAIN, defaulting to UID_DOMAIN), and the maximum token age (SEC_TOKEN_MAX_AGE).
secContext is the authorization level whose SEC_<level>_* policy applies; each setting falls back as GetSecurityConfig describes, so an unset SEC_ADVERTISE_STARTD_AUTHENTICATION takes SEC_DAEMON_AUTHENTICATION before SEC_DEFAULT_AUTHENTICATION. A daemon negotiates each command under the policy of the level it is registered at with daemon.Daemon.InstallSecurityLevels.
UID_DOMAIN (set by GetSecurityConfig) is the domain of an FS peer's identity, user@UID_DOMAIN. A daemon behind a shared port should build its configs with daemon.Daemon.ServerSecurityConfig, which also sets the shared-port id.
This is what a Go HTCondor daemon (e.g. a CCB server) should use so it authenticates clients with the same policy and keys as the C++ daemons.
func IsDaemonFallbackRefused ¶ added in v0.20.0
IsDaemonFallbackRefused reports whether err is a refusal of the daemon fallback.
Exported so a transport can answer with the status the refusal actually means. It is an authentication failure -- the caller presented nothing this server could use -- so it maps to 401, not to the 500 that a security-config error otherwise reads as.
func LoadSigningKeys ¶ added in v0.2.0
LoadSigningKeys reads the HTCondor pool signing keys from SEC_PASSWORD_DIRECTORY, returning a map of key name (e.g. "POOL") to its raw (unscrambled) key bytes. These keys are used as key-encryption keys for at-rest encryption of derived secrets (e.g. the persisted CCB session cache).
It returns (nil, nil) when SEC_PASSWORD_DIRECTORY is unset (no keys available). Unreadable individual key files are skipped (a key the daemon cannot read is not one it can use); a missing directory is reported as an error so a misconfiguration is visible.
SEC_PASSWORD_DIRECTORY and its key files are root-owned (0700/0600), so the directory listing and each file are read as root via droppriv — matching HTCondor's set_priv(PRIV_ROOT) — letting a daemon that has dropped to the condor account still load them (a no-op re-elevation when already root).
func LocalDaemonAddress ¶ added in v0.10.0
LocalDaemonAddress resolves subsys's address for a peer using the standard knobs, and returns a resolver plus a one-line description of the source (for logging). On each call the resolver prefers the daemon's address file (AddressFilePath) when that file is present and readable -- so a co-located daemon is followed across restarts -- and otherwise falls back to the static <SUBSYS>_HOST knob (e.g. a daemon on another host with no local address file). It errors at construction only when neither a file path nor a host is configured; a per-call file-read error still falls back to <SUBSYS>_HOST if one is set, else surfaces so the caller can retry.
A caller with its own knob names (e.g. a collector using COLLECTOR_DB_HOST / COLLECTOR_DB_ADDRESS_FILE rather than the <SUBSYS>_* convention) should instead compose AddressFilePath / FileAddressResolver directly with its own precedence.
func LookupSSLClientCredentials ¶ added in v0.0.11
LookupSSLClientCredentials reads the AUTH_SSL_CLIENT_CERTFILE, AUTH_SSL_CLIENT_KEYFILE, and AUTH_SSL_CLIENT_CAFILE settings from the global HTCondor configuration. Returns ok=true only when both cert and key paths are configured (CA may legitimately be empty when the system trust store is used).
Intended for callers that want to add SSL as a secondary auth method to a hand-built SecurityConfig without going through the full GetSecurityConfig path (which only loads SSL credentials when the configured AuthenticationMethods list already names SSL).
func LookupSSLClientCredentialsWithConfig ¶ added in v0.20.0
func LookupSSLClientCredentialsWithConfig(cfg *config.Config) (certFile, keyFile, caFile string, ok bool)
LookupSSLClientCredentialsWithConfig is LookupSSLClientCredentials reading cfg instead of the process-wide default configuration. A nil cfg is exactly LookupSSLClientCredentials.
func NewClientSecurityConfig ¶ added in v0.0.11
func NewClientSecurityConfig( ctx context.Context, token string, peerName string, command int, secContext string, sessionCache *security.SessionCache, ) (*security.SecurityConfig, error)
NewClientSecurityConfig builds a SecurityConfig for a client→daemon connection, starting from the configured SEC_<context>_AUTHENTICATION_METHODS (or SEC_DEFAULT_*) in the loaded HTCondor configuration and overlaying the supplied token, peer name, and session cache. This is the preferred constructor for any daemon-side path that needs to talk to another condor daemon — call sites that hand-build a SecurityConfig literal will lock themselves into a specific auth-method list and silently override what the operator configured.
Method-list construction:
- Starts from the configured SEC_<context>_AUTHENTICATION_METHODS (falling back to SEC_DEFAULT_*, then to a sensible compiled-in fallback that includes SSL alongside TOKEN/FS). Read through loadClientSecurityDefaults when a token was supplied, and through GetSecurityConfigOrDefault -- which may instead return a credential the context already carries -- when none was.
- When a non-empty token is supplied, guarantees TOKEN appears in the method list — prepended if absent — so the supplied token is actually offered to the peer, and drops every method that would identify this process instead (FS, KERBEROS, PASSWORD) or no one (ANONYMOUS). AuthIDTokens already counts as TOKEN at the wire level, so we don't duplicate.
Field overlays:
- Token: set when token != "". TokenFile, TokenDir, CertFile and KeyFile are then cleared and Authentication is REQUIRED, so the token is the only credential the connection can present.
- SessionCache: set when sessionCache != nil; otherwise cedar uses its global cache.
- PeerName: populated from the argument, used for session-cache lookups and SSL hostname verification.
Other security parameters (CryptoMethods, Authentication/Encryption/ Integrity levels, SSL credentials when SSL is configured) come from GetSecurityConfig — same code path that condor_config_val sees.
command is the cedar/commands constant for the RPC the caller is about to dispatch. Used for session-cache lookups via LookupByCommand; stored on the resulting SecurityConfig.
secContext should be one of "CLIENT", "READ", "WRITE", "ADMINISTRATOR", "DAEMON", "NEGOTIATOR" — the same context strings HTCondor uses for SEC_<context>_* knob lookup. Empty defaults to "CLIENT".
func NewClientSecurityConfigWithConfig ¶ added in v0.20.0
func NewClientSecurityConfigWithConfig( ctx context.Context, cfg *config.Config, token string, peerName string, command int, secContext string, sessionCache *security.SessionCache, ) (*security.SecurityConfig, error)
NewClientSecurityConfigWithConfig is NewClientSecurityConfig reading the SEC_* settings from cfg instead of the process-wide default configuration. A nil cfg is exactly NewClientSecurityConfig. cfg decides only where the configuration comes from; which credential is presented is decided the same way for either.
func ParseAdvertiseCommand ¶ added in v0.0.4
func ParseAdvertiseCommand(cmd string) (commands.CommandType, bool)
ParseAdvertiseCommand parses an UPDATE command string to CommandType This is a shared utility used by both HTTP handlers and MCP handlers
func ParseJobID ¶ added in v0.0.11
ParseJobID parses "cluster.proc" into a (cluster, proc) pair. Used by httpserver routes; lives here so it has a single owner.
func ReadAddressFile ¶ added in v0.10.0
ReadAddressFile returns the first non-empty line of an HTCondor address file: a sinful string, possibly angle-bracket wrapped (cedar's addresses.ParseSinful accepts either form, and ConnectAndAuthenticate takes it as-is).
func ReloadDefaultConfig ¶ added in v0.0.3
func ReloadDefaultConfig()
ReloadDefaultConfig reloads the global default HTCondor configuration. This is useful when configuration files change and need to be re-read. If loading fails, the global config is set to nil.
func ResetRescheduleLimiter ¶ added in v0.1.0
func ResetRescheduleLimiter()
ResetRescheduleLimiter clears the per-process reschedule rate limiter state. Intended for tests; production callers shouldn't need it.
func SSHToJobHarnessConfig ¶ added in v0.14.3
SSHToJobHarnessConfig returns the extra condor_config lines a test harness needs so jobs in it accept condor_ssh_to_job, plus ok=false when this host cannot support it.
func SSHToJobPrereqs ¶ added in v0.14.3
SSHToJobPrereqs locates what condor_ssh_to_job needs on this host: the system sshd the starter spawns inside the sandbox, and the sshd_config template HTCondor hands it.
Both are found by searching, not by a fixed list of paths, because the fixed list is how an integration test quietly stops running. A developer whose HTCondor lives in a build tree (release_dir/lib/...) rather than in /usr/lib had every ssh-to-job test skip on their machine — which looks identical, in CI output and at a glance, to the tests passing.
Returns ok=false when either piece is missing, which is a genuine "this host cannot run condor_ssh_to_job" and a legitimate skip.
func SetUnmarkedOriginPolicy ¶ added in v0.20.0
func SetUnmarkedOriginPolicy(p UnmarkedOriginPolicy)
SetUnmarkedOriginPolicy sets the process-wide policy for unclassified contexts. The zero value, in force until something calls this, is UnmarkedAllow.
func SetUnmarkedOriginReporter ¶ added in v0.20.0
SetUnmarkedOriginReporter installs the function UnmarkedWarn calls for each unclassified daemon fallback. Passing nil removes it.
A hook rather than a log call: this package deliberately does not depend on the logging package (a daemon hands its own logger in), and the caller that turns Warn on is the same one that knows where its logs go.
func SpoolInputAllowSet ¶ added in v0.17.0
SpoolInputAllowSet returns, sorted, the filenames the schedd will accept into this job's input spool. Any name outside the set is dropped in silence on its way through sendJobFilesFromTar, so a caller who uploads by that name gets a clean success and a job that runs without the file.
Exported for the share-URL mint path: the person redeeming an upload URL is often not the person who wrote the submit file, and has no other way to learn which names are expected before spending an upload on the wrong one.
The ad must carry jobInputSpoolProjection's attributes with the cluster ad overlaid, or the set comes back missing the executable -- see fetchProcAdForSpool.
func ValidateAttributeForEdit ¶
func ValidateAttributeForEdit(attrName string, opts *EditJobOptions) error
ValidateAttributeForEdit checks if an attribute can be edited Returns an error if the attribute is immutable or protected (when not allowed)
func ValidateOAuthCredential ¶ added in v0.13.0
ValidateOAuthCredential reports whether a credential's bytes are storable as an OAuth service credential, and explains the problem when they are not.
An OAuth service credential has to be a JSON document. The credd will not tell you that at store time: it accepts whatever bytes it is given, and only parses them when a request carries scopes or an audience. It re-parses them, though, whenever a query names a specific service -- so storing a bare token string succeeds, and then get_credential_status fails ever after with FAILURE_JSON_PARSE while list_service_credentials, which never names a service, keeps reporting the credential as present.
Two read paths disagreeing about the same credential is a miserable thing to debug, and the evidence points away from the cause: the store said OK. So every path that stores one should refuse at the door instead.
Lives here, next to PutServiceCred, because it is a fact about the credd rather than about any particular API in front of it -- there is more than one, and they were not agreeing.
An empty credential is deliberately allowed, and is not the same thing as a malformed one. A credmon that mints tokens locally -- see the localcredmon module -- watches for the stored .top file and never reads its contents, so storing nothing is how you ask for a token rather than supply one. That is the normal path for OAuth services a server-side job transform added.
func WithAuthenticatedUser ¶ added in v0.0.3
WithAuthenticatedUser creates a context that includes the authenticated username This is used for rate limiting purposes
func WithDaemonCredential ¶ added in v0.20.0
WithDaemonCredential marks ctx as this daemon's own work, which is what makes authenticating as this daemon legitimate.
It also detaches any caller credential, because the two always belong together: the reason a piece of plumbing is daemon work is that the peer is infrastructure with no reason to trust the caller's token, and offering it one anyway asks a third party to accept a credential meant for somebody else. Doing both here means a context derived from a request cannot be half-converted.
func WithRenewableSecurityConfig ¶ added in v0.20.0
func WithRenewableSecurityConfig(ctx context.Context, secConfig *security.SecurityConfig, renew SecurityConfigRenewer) context.Context
WithRenewableSecurityConfig is WithSecurityConfig for a credential minted for the caller: when the token secConfig carries is about to expire, GetSecurityConfigOrDefault replaces it with what renew returns. renew may refuse -- the grant behind the credential has ended -- and the connection then fails rather than presenting the expired token.
func WithSecurityConfig ¶
WithSecurityConfig creates a context that includes security configuration This allows passing authentication information (like tokens) from HTTP handlers to Schedd methods
func WithUserRequest ¶ added in v0.20.0
WithUserRequest marks ctx as acting for somebody other than this daemon, so that reaching the daemon fallback under it is an error rather than a silent promotion.
Mark at the transport, not at the authentication branch. The branches are precisely the code that forgets: one returns the context unchanged when it has no signing key, another hands back a context whose credential could not be minted, a third is a route that nobody wrapped in the gate. Marking where the request enters the process means a route added tomorrow inherits it, and a branch that fails to attach a credential produces a context that is refused instead of one that authenticates as a superuser.
reason names the surface, and is carried into the refusal message: an operator reading the log line needs to know which door the context came in through, because the fix is at that door.
func WithoutSecurityConfig ¶ added in v0.14.0
WithoutSecurityConfig returns ctx with any caller credential detached, so the connection built from it authenticates as this daemon rather than as whoever made the request.
A request context carries the caller's own SecurityConfig, and GetSecurityConfigOrDefault prefers it over the daemon's configuration. That is right for anything done *on behalf of* the caller. It is wrong for the plumbing underneath: a connection to a broker, a relay, or any other piece of infrastructure is this daemon talking, and offering the caller's credential there asks a third party to trust a token it has no reason to recognise.
Cancellation and deadlines are preserved -- only the credential is dropped.
Detaching the credential is also a statement about who the connection is, so this classifies the context as daemon work (see CredentialOrigin). Without that, a plumbing context derived from a request would keep the request's own classification and be refused for having no credential -- which is the correct treatment of an accident and the wrong treatment of this, where the daemon's credential is the one the peer recognises.
Types ¶
type ActionResult ¶
type ActionResult int
ActionResult represents the result of an action on a single job
const ( AR_ERROR ActionResult = iota // 0: Error occurred (no longer generated by the schedd as of 2025) AR_SUCCESS // 1: Action succeeded AR_NOT_FOUND // 2: Job not found AR_BAD_STATUS // 3: Job in wrong status for action AR_ALREADY_DONE // 4: Action already performed AR_PERMISSION_DENIED // 5: Permission denied AR_LIMIT_EXCEEDED // 6: Per-user job/action limit exceeded )
Action result constants.
These index the result ad's per-result attributes (result_total_<N> for AR_TOTALS, job_<c>_<p>/cluster_<c> = <N> for AR_LONG). MUST match the C++ action_result_t enum (src/condor_daemon_client/dc_schedd.h:52-60).
type ActionResultType ¶
type ActionResultType int
ActionResultType specifies what kind of result information to return
const ( AR_NONE ActionResultType = iota // 0: don't care / don't yet know AR_LONG // 1: Return detailed per-job results AR_TOTALS // 2: Return only totals (default) )
Action result type constants.
Placed on the wire as ATTR_ACTION_RESULT_TYPE. MUST match the C++ action_result_type_t enum (src/condor_daemon_client/dc_schedd.h:63-67):
AR_NONE = 0 // don't care / don't yet know AR_LONG = 1 // want info per job (job_<c>_<p> / cluster_<c> = result) AR_TOTALS = 2 // want totals for each possible result (result_total_<N>)
The schedd only special-cases AR_LONG; anything else is treated as AR_TOTALS (src/condor_schedd.V6/schedd.cpp:7571-7574). The earlier Go values had AR_TOTALS=0, which happened to work but did not match the C++ enum.
type AdvertiseError ¶ added in v0.14.1
type AdvertiseError struct {
// Succeeded lists the collectors that took the ad, sorted.
Succeeded []string
// Failed maps a collector address to why it did not.
Failed map[string]error
}
AdvertiseError reports an advertisement that did not reach every configured collector.
It is returned whenever at least one collector failed, including when others succeeded -- partial success is a real outcome and the caller should be able to see it rather than have it collapsed into "ok" or "failed". Use AllFailed to tell "the ad is nowhere" from "the ad is in some collectors but not all", which is the distinction that decides whether a daemon is invisible or merely under-advertised.
func (*AdvertiseError) AllFailed ¶ added in v0.14.1
func (e *AdvertiseError) AllFailed() bool
AllFailed reports whether no collector took the ad.
func (*AdvertiseError) Error ¶ added in v0.14.1
func (e *AdvertiseError) Error() string
func (*AdvertiseError) Unwrap ¶ added in v0.14.1
func (e *AdvertiseError) Unwrap() []error
Unwrap exposes the per-collector errors to errors.Is and errors.As.
type AdvertiseOptions ¶ added in v0.0.4
type AdvertiseOptions struct {
// Command specifies the UPDATE command to use (e.g., UPDATE_SCHEDD_AD).
//
// The zero value means "derive the command from the ad's MyType"
// (getCommandForAdvertise), which is the intended default and yields the
// correct command for every standard ad type. NOTE: because UPDATE_STARTD_AD
// is itself 0, an explicit Command: UPDATE_STARTD_AD is indistinguishable from
// the unset zero value and is also derived from MyType -- identical for a
// Machine/StartD ad, so this matters only for the nonsensical case of forcing a
// startd update on an ad whose MyType is absent or non-startd (which would
// instead derive UPDATE_AD_GENERIC). To force any other command, set it here
// (all other UPDATE_* commands are non-zero and are honored exactly).
Command commands.CommandType
// WithAck requests acknowledgment from the collector (forces TCP)
WithAck bool
// UseTCP forces TCP connection (default: true)
UseTCP bool
// PrivateAd is an optional companion "private" ad sent immediately after the
// public ad on the SAME CEDAR message (public ad, then private ad, then a
// single end_of_message), mirroring the C++ startd's UPDATE_STARTD_AD wire
// (dc_collector.cpp): putClassAd(public) then putClassAd(private).
//
// This carries the STARTD_PVT ad -- the private half of the public+private
// Machine ad pair the negotiator requires, holding the slot's ClaimId. The
// collector matches the private ad to its public ad by Name and MyAddress,
// so a private ad should carry those; Advertise copies "MyAddress" from the
// public ad into the private ad if the public ad has it and the private ad
// does not, matching dc_collector.cpp.
//
// The private ad is serialized WITH private (secret) attributes included
// (PutClassAdIncludePrivate) so its ClaimId survives the trip; the public ad
// is serialized normally, which redacts any secret attributes.
//
// Optional: a nil PrivateAd sends only the public ad (a missing private ad is
// tolerated by the collector). Only honored by Advertise; AdvertiseMultiple
// returns an error if PrivateAd is set (see AdvertiseMultiple).
PrivateAd *classad.ClassAd
}
AdvertiseOptions configures advertisement behavior
type AggregateRow ¶ added in v0.13.0
type AggregateRow struct {
// Group holds the group-by attribute values, in the order the
// attributes were requested. Empty for an ungrouped total.
Group []string
// Count is the number of jobs in the group.
Count int64
}
AggregateRow is one group returned by an aggregate query: the values of the group-by attributes, and how many jobs fell into that group.
type CCBDialer ¶ added in v0.18.0
type CCBDialer struct {
// contains filtered or unexported fields
}
CCBDialer reaches daemons behind a Condor Connection Broker, choosing between connection reversal and broker relaying, and remembering what worked.
The choice cannot be made ahead of time. Which broker a dial goes through is decided by the execute node, in the sinful it advertised, so this process does not know until it holds the address -- and even then the two things that determine the answer are not things it can ask about. Whether the execute node can reach us is a fact about the network between two hosts that are not this one; whether the broker can relay is a fact about a version we only see once we have authenticated to it. So both are learned by trying, and the result is cached per broker so a server that has learned the answer does not pay for it on every exec.
The zero value is not usable; call NewCCBDialer. A nil *CCBDialer is valid and dials exactly as DialSinful does with no CCB options -- the behavior of a caller that never configured any of this.
func NewCCBDialer ¶ added in v0.18.0
func NewCCBDialer(cfg CCBDialerConfig) *CCBDialer
NewCCBDialer builds a CCBDialer from cfg.
func (*CCBDialer) Dial ¶ added in v0.18.0
func (d *CCBDialer) Dial(ctx context.Context, address string, secConfig *security.SecurityConfig, opts *DialOptions) (*client.HTCondorClient, error)
Dial establishes an authenticated connection to address, choosing how to traverse CCB if the address needs it. Non-CCB addresses are dialed unchanged.
opts supplies everything but the CCB mode (notably Timeout); the CCB fields on it are ignored, since choosing them is this method's job.
type CCBDialerConfig ¶ added in v0.18.0
type CCBDialerConfig struct {
// Router, when set, gives this process an inbound path, which makes
// connection reversal possible and is preferred over streaming: it works
// with every broker version, while streaming does not, and the broker for
// a given dial is chosen by the execute node.
Router CCBReverseRouter
// Streaming permits the broker-relayed mode. With no Router it is the only
// thing that works from a host the execute nodes cannot reach; with one it
// is the fallback for when they turn out not to reach us anyway.
Streaming bool
// LearnedTTL bounds how long what we learned about a broker is trusted
// (default DefaultCCBLearnedTTL).
LearnedTTL time.Duration
// PrivateNetworkName is this client's PRIVATE_NETWORK_NAME. When it
// equals a target's PrivNet, the target is dialed directly instead of
// through its broker. Empty disables the behaviour entirely.
PrivateNetworkName string
// Logger receives one line per mode change. Defaults to slog.Default().
Logger *slog.Logger
}
CCBDialerConfig configures a CCBDialer.
type CCBReverseRouter ¶ added in v0.18.0
type CCBReverseRouter interface {
// Register claims one inbound path. The caller closes the listener when
// the dial is done, which releases the registration.
Register() (net.Listener, string, error)
}
CCBReverseRouter hands out inbound paths for CCB connection reversal: a listener the execute node's connection back to us will arrive on, and the HTCondor sinful to advertise as the address it should dial.
The implementation is an in-process shared-port router (see webapi/sharedportrouter), which multiplexes any number of concurrent reversals over one inbound TCP port. It is an interface here so the core library does not require one, and so tests can supply a trivial one.
type CallerCredential ¶ added in v0.20.0
type CallerCredential struct {
// contains filtered or unexported fields
}
CallerCredential is a caller's credential detached from the request that carried it, for work that outlives the request.
func CallerCredentialFromContext ¶ added in v0.20.0
func CallerCredentialFromContext(ctx context.Context) (CallerCredential, bool)
CallerCredentialFromContext copies the caller's credential off ctx, with the renewer that was attached alongside it, if any. The copy is the holder's own: nothing the request does afterwards changes it.
func (CallerCredential) Attach ¶ added in v0.20.0
func (c CallerCredential) Attach(ctx context.Context) context.Context
Attach returns ctx carrying the credential, renewable as it was on the request it came from.
func (CallerCredential) Renew ¶ added in v0.20.0
func (c CallerCredential) Renew(ctx context.Context) (CallerCredential, error)
Renew mints the credential again now, whatever its token's expiry.
func (CallerCredential) Renewable ¶ added in v0.20.0
func (c CallerCredential) Renewable() bool
Renewable reports whether the credential can be re-minted. One that cannot -- a token the caller presented themselves -- lasts exactly as long as that token.
func (CallerCredential) Token ¶ added in v0.20.0
func (c CallerCredential) Token() string
Token is the token the credential presents.
type CedarCredd ¶ added in v0.0.6
type CedarCredd struct {
// contains filtered or unexported fields
}
CedarCredd provides a CEDAR-based credd client implementation
func NewCedarCredd ¶ added in v0.0.6
func NewCedarCredd(address string) *CedarCredd
NewCedarCredd creates a new CEDAR-based credd client
func (*CedarCredd) CheckCreds ¶ added in v0.20.0
func (c *CedarCredd) CheckCreds(ctx context.Context, requests []CredRequest) (string, error)
CheckCreds implements CREDD_CHECK_CREDS, the request condor_submit makes before submitting (do_check_oauth_creds in store_cred.cpp): a count, one ad per requested service, then a single string in reply.
The credd may hold the reply while a local credmon writes a token it has just asked for, up to about 20 seconds, so ctx should allow for that.
func (*CedarCredd) DeleteServiceCred ¶ added in v0.0.6
func (c *CedarCredd) DeleteServiceCred(ctx context.Context, credType CredType, service string, handle string, user string) error
DeleteServiceCred removes a service credential
func (*CedarCredd) DeleteUserCred ¶ added in v0.0.6
DeleteUserCred removes a user credential
func (*CedarCredd) GetCredential ¶ added in v0.0.6
func (c *CedarCredd) GetCredential(ctx context.Context, credType CredType, service string, handle string, user string) ([]byte, error)
GetCredential returns the stored credential payload
func (*CedarCredd) GetServiceCredStatus ¶ added in v0.0.6
func (c *CedarCredd) GetServiceCredStatus(ctx context.Context, credType CredType, service string, handle string, user string) (CredentialStatus, error)
GetServiceCredStatus reports status for a stored service credential.
It asks the credd for every credential file the user holds rather than naming the service. A query that names a service makes the credd re-read the service's .top file as JSON to compare scopes, and a local credmon's .top is not JSON -- it holds only the user's name -- so naming the service fails with FAILURE_JSON_PARSE on a credential that works. The listing reads no file contents.
A service with no files at all is reported as ErrCredentialNotFound.
func (*CedarCredd) GetUserCredStatus ¶ added in v0.0.6
func (c *CedarCredd) GetUserCredStatus(ctx context.Context, credType CredType, user string) (CredentialStatus, error)
GetUserCredStatus reports credential status
func (*CedarCredd) ListServiceCreds ¶ added in v0.0.6
func (c *CedarCredd) ListServiceCreds(ctx context.Context, credType CredType, user string) ([]ServiceStatus, error)
ListServiceCreds returns all service credentials for the user. A user with none gets an empty list: the credd answers that query with "not found", which is an answer, not a failure.
func (*CedarCredd) PutServiceCred ¶ added in v0.0.6
func (c *CedarCredd) PutServiceCred(ctx context.Context, credType CredType, credential []byte, service string, handle string, user string, refresh *bool) error
PutServiceCred stores an OAuth service credential
func (*CedarCredd) PutUserCred ¶ added in v0.0.6
func (c *CedarCredd) PutUserCred(ctx context.Context, credType CredType, credential []byte, user string) error
PutUserCred stores a user credential (Kerberos)
func (*CedarCredd) WithConfig ¶ added in v0.20.0
func (c *CedarCredd) WithConfig(cfg *config.Config) *CedarCredd
WithConfig sets the HTCondor configuration this credd client uses; see the note above.
type CheckCredsRefusal ¶ added in v0.20.0
type CheckCredsRefusal struct {
Reason string
}
CheckCredsRefusal is the credd answering CREDD_CHECK_CREDS with a reason it cannot supply the credentials, as distinct from failing to reach it. Asking again gets the same answer until something on the access point changes.
func (*CheckCredsRefusal) Error ¶ added in v0.20.0
func (e *CheckCredsRefusal) Error() string
type Collector ¶
type Collector struct {
// contains filtered or unexported fields
}
Collector represents an HTCondor collector daemon.
The configured address may be a single host:port / sinful string or a comma-separated list ("host1,host2" or "host1:9618,host2:9618") matching the HTCondor COLLECTOR_HOST convention. With a list, every operation races against the entries with a small stagger so a stalled primary collector falls over to the secondary quickly. See collector_race.go for the protocol; `raceStagger == 0` (the default) means DefaultCollectorRaceStagger.
Address ordering inside a list follows two principles, matching the C++ HTCondor client:
- At construction, the address list is shuffled. A fleet of identically-configured clients would otherwise pile onto the same primary collector; shuffling spreads load.
- After a successful dial, the winning address becomes "sticky" and is moved to position 0 for subsequent dials. Sustained traffic from one client therefore lands on a single collector until that collector fails, at which point the race naturally promotes whichever address won the failover.
func NewCollector ¶
NewCollector creates a new Collector instance. address may be a single hostname, host:port (or sinful string), or a comma-separated list:
NewCollector("cm-1.ospool.osg-htc.org,cm-2.ospool.osg-htc.org")
Entries without a port number are given the default HTCondor collector port (9618). With a list, attempts are raced with a 150 ms stagger and the first that returns an authenticated CEDAR stream wins. The list is shuffled at construction; see the Collector type comment for the ordering policy.
func (*Collector) Address ¶ added in v0.0.11
Address returns the address the collector is configured against. Useful for logging and diagnostics; never returns the empty string for a Collector constructed via NewCollector. For a comma-separated list, returns the raw list string the caller passed in.
func (*Collector) Addresses ¶ added in v0.1.0
Addresses returns the parsed list of collector addresses in the Collector's current dial-order: the last-successful address (if any) first, then the post-shuffle remainder. For a single- collector setup this returns a one-element slice. Never returns nil for a Collector built via NewCollector with a non-empty address.
The returned slice is a defensive copy; mutating it has no effect on the Collector.
func (*Collector) Advertise ¶
func (c *Collector) Advertise(ctx context.Context, ad *classad.ClassAd, opts *AdvertiseOptions) error
Advertise sends an advertisement to the collector The command type is determined from the ad's MyType attribute if not specified in opts Returns error if advertisement fails
func (*Collector) AdvertiseMultiple ¶ added in v0.0.4
func (c *Collector) AdvertiseMultiple(ctx context.Context, ads []*classad.ClassAd, opts *AdvertiseOptions) []error
AdvertiseMultiple sends many advertisements over as few connections as possible using HTCondor's persistent command-socket protocol: one authenticated connection carries a run of updates, the first riding the connection's negotiated command and each follow-on prefixed with its own command integer. Matching the C++ condor_collector (and DaemonCore), the command integer and the ad are two separate CEDAR messages -- [cmd + EOM] then [ad + EOM] -- which is exactly how a C++ daemon streams a schedd ad plus submitter ads down one stashed socket.
This amortizes the per-ad TCP connect + authenticate cost that otherwise dominates advertising (a fresh connection per ad). On a send error the connection is torn down and re-established, and the remaining ads continue on the new one. Returns one error per ad (nil entries where the ad succeeded), or nil if the batch was empty.
func (*Collector) LocateDaemon ¶
func (c *Collector) LocateDaemon(ctx context.Context, daemonType DaemonType, name string) (*DaemonLocation, error)
LocateDaemon locates a daemon by querying the collector.
daemonType is the kind of daemon to locate — one of the DaemonType constants (DaemonSchedd, DaemonStartd, DaemonMaster, DaemonCollector, DaemonNegotiator). It is translated to the corresponding collector-query ad type internally, so callers pass a daemon type (DaemonSchedd), not an ad type ("ScheddAd").
name is the name of the daemon to locate (optional, pass empty string to find any).
func (*Collector) Ping ¶ added in v0.0.4
func (c *Collector) Ping(ctx context.Context) (*PingResult, error)
Ping performs a ping operation against the collector daemon This is similar to condor_ping and provides information about authentication and authorization. It's useful for health checks and debugging security settings.
func (*Collector) PingWithOptions ¶ added in v0.0.4
func (c *Collector) PingWithOptions(ctx context.Context, opts *PingOptions) (*PingResult, error)
PingWithOptions performs a ping operation with optional permission checking
func (*Collector) QueryAds
deprecated
func (c *Collector) QueryAds(ctx context.Context, adType string, constraint string) ([]*classad.ClassAd, error)
QueryAds queries the collector for daemon advertisements adType selects the ad type to query — one of the *AdType constants (e.g. ScheddAdType), or a daemon-type name like "Schedd" constraint is a ClassAd constraint expression string (pass empty string for no constraint)
Deprecated: Use QueryAdsWithOptions for pagination and default limits/projections
func (*Collector) QueryAdsStream ¶ added in v0.0.4
func (c *Collector) QueryAdsStream(ctx context.Context, adType string, constraint string, projection []string, limit int, streamOpts *StreamOptions) (<-chan AdResult, error)
QueryAdsStream queries the collector and streams results through a channel Returns a channel and an error. If the error is non-nil, it indicates a problem before the request was sent (e.g., invalid parameters, connection failure). The channel will be closed when all ads have been sent or an error occurs during streaming. If cumulative time blocking on channel writes exceeds StreamOptions.WriteTimeout, an error is sent through the channel. The limit parameter controls the maximum number of ads to return (-1 for unlimited).
func (*Collector) QueryAdsWithOptions ¶ added in v0.0.4
func (c *Collector) QueryAdsWithOptions(ctx context.Context, adType string, constraint string, opts *QueryOptions) ([]*classad.ClassAd, *PageInfo, error)
QueryAdsWithOptions queries the collector for daemon advertisements with pagination and limits opts specifies query options including limit, projection, and pagination Returns the matching ads and pagination info
func (*Collector) QueryAdsWithProjection
deprecated
added in
v0.0.3
func (c *Collector) QueryAdsWithProjection(ctx context.Context, adType string, constraint string, projection []string) ([]*classad.ClassAd, error)
QueryAdsWithProjection queries the collector for daemon advertisements with optional projection adType selects the ad type to query — one of the *AdType constants (e.g. ScheddAdType), or a daemon-type name like "Schedd" constraint is a ClassAd constraint expression string (pass empty string for no constraint) projection is an optional list of attribute names to return (pass nil for all attributes)
Deprecated: Use QueryAdsWithOptions for pagination and default limits/projections
func (*Collector) WatchAds ¶ added in v0.5.0
func (c *Collector) WatchAds(ctx context.Context, adType, constraint string, cursor []byte) (<-chan WatchEvent, error)
WatchAds subscribes to changes for adType (e.g. "StartdAd", "Machine", "ScheddAd") at the collector and returns a channel of events. constraint, if non-empty, is a ClassAd match expression (e.g. `DAGManJobId == 42`) so only events for matching ads are delivered -- an ad that stops matching arrives as a Delete. Pass a nil cursor for a full replay, or a cursor from a prior Synced/live event to resume incrementally.
The channel is closed when ctx is cancelled or the stream ends (the server went away or the connection dropped); a GoingAway event, if delivered, arrives just before the close. The caller should range over the channel and, on GoingAway/Resync or an unexpected close, reconnect with its last cursor. The underlying connection is closed automatically when the stream ends.
func (*Collector) WithConfig ¶ added in v0.20.0
WithConfig sets the HTCondor configuration this Collector uses; see the note above.
func (*Collector) WithRaceStagger ¶ added in v0.1.0
WithRaceStagger returns a Collector with the inter-attempt delay overridden. Setting stagger == 0 disables the stagger (every address attempts in parallel from t=0). Negative values are clamped to the default.
This is a fluent-style modifier so it composes with NewCollector:
c := htcondor.NewCollector(addrs).WithRaceStagger(200 * time.Millisecond)
type CondorTestHarness ¶ added in v0.0.4
type CondorTestHarness struct {
// contains filtered or unexported fields
}
CondorTestHarness manages a mini HTCondor instance for integration testing
func SetupCondorHarness ¶ added in v0.0.4
func SetupCondorHarness(t TestingT) *CondorTestHarness
SetupCondorHarness creates and starts a mini HTCondor instance
func SetupCondorHarnessWithConfig ¶ added in v0.0.4
func SetupCondorHarnessWithConfig(t TestingT, extraConfig string) *CondorTestHarness
SetupCondorHarnessWithConfig is like SetupCondorHarness but appends extra configuration to the generated condor_config. This allows tests to register custom daemons or tweak logging without duplicating harness logic.
func (*CondorTestHarness) GetCollectorAddr ¶ added in v0.0.4
func (h *CondorTestHarness) GetCollectorAddr() string
GetCollectorAddr returns the collector address
func (*CondorTestHarness) GetConfig ¶ added in v0.0.4
func (h *CondorTestHarness) GetConfig() (*config.Config, error)
GetConfig returns a Config instance configured for this harness
func (*CondorTestHarness) GetConfigFile ¶ added in v0.0.11
func (h *CondorTestHarness) GetConfigFile() string
GetConfigFile returns the path of the on-disk condor_config file the harness wrote. Tests that spawn extra processes pointed at the same HTCondor instance need this so they can set CONDOR_CONFIG.
func (*CondorTestHarness) GetLockDir ¶ added in v0.0.11
func (h *CondorTestHarness) GetLockDir() string
GetLockDir returns the lock directory path for this harness — useful for tests that read the shared_port_ad file the shared_port daemon drops there to discover its dynamically-assigned port.
func (*CondorTestHarness) GetLogDir ¶ added in v0.0.4
func (h *CondorTestHarness) GetLogDir() string
GetLogDir returns the log directory path for this harness
func (*CondorTestHarness) GetPasswordDir ¶ added in v0.13.0
func (h *CondorTestHarness) GetPasswordDir() string
GetPasswordDir returns the SEC_PASSWORD_DIRECTORY this harness pins, which is where its daemons look for token signing keys.
func (*CondorTestHarness) GetScheddName ¶ added in v0.0.4
func (h *CondorTestHarness) GetScheddName() string
GetScheddName returns the schedd name for this harness
func (*CondorTestHarness) GetSigningKeyPath ¶ added in v0.13.0
func (h *CondorTestHarness) GetSigningKeyPath() string
GetSigningKeyPath returns the POOL signing key this harness created. Pass it as a daemon's SIGNING_KEY_PATH: a token signed with it and issued for GetTrustDomain is one this harness's schedd will accept, so the daemon authenticates as the token's subject rather than falling through to FS and being recorded as its own OS user.
func (*CondorTestHarness) GetSpoolDir ¶ added in v0.0.4
func (h *CondorTestHarness) GetSpoolDir() string
GetSpoolDir returns the spool directory path for this harness
func (*CondorTestHarness) GetTrustDomain ¶ added in v0.13.0
func (h *CondorTestHarness) GetTrustDomain() string
GetTrustDomain returns the trust domain this harness's daemons accept tokens from. Pass it as a daemon's TRUST_DOMAIN.
func (*CondorTestHarness) PrintCollectorLog ¶ added in v0.18.0
func (h *CondorTestHarness) PrintCollectorLog()
PrintCollectorLog prints the collector log contents for debugging. The collector also hosts the pool's built-in CCB server, so this is where a failed connection reversal explains itself.
func (*CondorTestHarness) PrintScheddLog ¶ added in v0.0.4
func (h *CondorTestHarness) PrintScheddLog()
PrintScheddLog prints the schedd log contents for debugging
func (*CondorTestHarness) PrintShadowLog ¶ added in v0.0.7
func (h *CondorTestHarness) PrintShadowLog()
PrintShadowLog is the exported version for test access
func (*CondorTestHarness) PrintStartdLog ¶ added in v0.18.0
func (h *CondorTestHarness) PrintStartdLog()
PrintStartdLog prints the startd log contents for debugging.
func (*CondorTestHarness) PrintStarterLogs ¶ added in v0.0.7
func (h *CondorTestHarness) PrintStarterLogs()
PrintStarterLogs is the exported version for test access
func (*CondorTestHarness) Shutdown ¶ added in v0.0.4
func (h *CondorTestHarness) Shutdown()
Shutdown stops the HTCondor instance
func (*CondorTestHarness) WaitForDaemons ¶ added in v0.0.4
func (h *CondorTestHarness) WaitForDaemons() error
WaitForDaemons waits for the HTCondor daemons to start and become responsive
func (*CondorTestHarness) WaitForSchedd ¶ added in v0.12.8
func (h *CondorTestHarness) WaitForSchedd(timeout time.Duration) error
WaitForSchedd waits for the schedd to advertise to the collector, which is what makes it locatable by the tests. Separate from the address file the schedd writes: a test reaches the schedd through the collector, so the ad is the readiness signal that matters.
func (*CondorTestHarness) WaitForStartd ¶ added in v0.0.4
func (h *CondorTestHarness) WaitForStartd(timeout time.Duration) error
WaitForStartd waits for the startd daemon to advertise to the collector. This is useful because the startd may take longer to start up and advertise than the collector and schedd, especially on slower systems.
type CredRequest ¶ added in v0.20.0
CredRequest names one OAuth service credential a job needs, as sent to CheckCreds.
type CredType ¶ added in v0.0.6
type CredType string
CredType enumerates the credential types supported by the credd. Mirrors the Python bindings CredType enum (Kerberos, OAuth).
type CreddClient ¶ added in v0.0.6
type CreddClient interface {
PutUserCred(ctx context.Context, credType CredType, credential []byte, user string) error
DeleteUserCred(ctx context.Context, credType CredType, user string) error
GetUserCredStatus(ctx context.Context, credType CredType, user string) (CredentialStatus, error)
PutServiceCred(ctx context.Context, credType CredType, credential []byte, service string, handle string, user string, refresh *bool) error
DeleteServiceCred(ctx context.Context, credType CredType, service string, handle string, user string) error
GetServiceCredStatus(ctx context.Context, credType CredType, service string, handle string, user string) (CredentialStatus, error)
ListServiceCreds(ctx context.Context, credType CredType, user string) ([]ServiceStatus, error)
GetCredential(ctx context.Context, credType CredType, service string, handle string, user string) ([]byte, error)
// CheckCreds makes the request condor_submit makes before it submits a
// job: it asks the credd to make sure the caller holds every OAuth
// credential in requests, and the credd adds the services its own
// local credmons provide (SUBMIT_ADD_LOCAL_CREDMON_PROVIDERS, on by
// default). For a local credmon's service a missing credential is
// created on the spot, which is how an access point that requires one
// on every job gets it -- so an empty request list is meaningful.
//
// It returns "" when everything is in place, or a URL the user must
// visit to grant a credential the credd cannot create itself.
CheckCreds(ctx context.Context, requests []CredRequest) (string, error)
}
CreddClient defines the operations exposed by the credd (credential daemon). The methods mirror the Python bindings htcondor2.Credd API but omit Windows password support.
type CredentialCache ¶ added in v0.2.0
type CredentialCache struct {
// contains filtered or unexported fields
}
CredentialCache reads credential files (the SSL server key/cert, token signing keys) for a daemon that has dropped privileges to a service account. It reads through droppriv as root — matching HTCondor's set_priv(PRIV_ROOT) — so root-owned 0600 credentials remain readable after the drop, and caches the bytes so steady-state handshakes do not pay a privilege transition and file read each time.
It satisfies cedar's security.CredentialReader (assign it to SecurityConfig.Credentials). Reload clears the cache so the next read picks up rotated signing keys or a renewed certificate; wire it to the daemon's SIGHUP reconfigure so credential reloads follow HTCondor's reconfig convention.
func NewCredentialCache ¶ added in v0.2.0
func NewCredentialCache() *CredentialCache
NewCredentialCache returns an empty credential cache.
func (*CredentialCache) ListCredentialDir ¶ added in v0.11.0
func (c *CredentialCache) ListCredentialDir(path string) ([]os.DirEntry, error)
ListCredentialDir lists the entries of a credential directory as root (via droppriv), so a daemon that has dropped privileges can still enumerate a root-only, mode-0700 token directory such as SEC_TOKEN_SYSTEM_DIRECTORY (/etc/condor/tokens.d). It satisfies cedar's security.CredentialDirLister.
Unlike ReadCredential the listing is not cached: a token directory's contents change as tokens are added, rotated, or removed, and the scan happens at most once per handshake, so a stale cached listing would cost more than it saves.
func (*CredentialCache) ReadCredential ¶ added in v0.2.0
func (c *CredentialCache) ReadCredential(path string) ([]byte, error)
ReadCredential returns the bytes of the credential file at path, reading it as root (via droppriv) on a cache miss and caching the result.
func (*CredentialCache) Reload ¶ added in v0.2.0
func (c *CredentialCache) Reload()
Reload drops all cached credentials so subsequent reads re-fetch the current on-disk bytes. Call it on reconfigure (SIGHUP) to honor rotated keys/certs.
type CredentialOrigin ¶ added in v0.20.0
type CredentialOrigin int
CredentialOrigin records who a context is acting for.
It exists because a context carrying no *security.SecurityConfig was ambiguous in the one way that matters. "Nobody attached a credential because this is the daemon's own queue mirroring" and "nobody attached a credential because the code that should have done so returned early" look identical at the point where the connection is built, and GetSecurityConfigOrDefault resolved both of them the same way: fall through to this daemon's own configuration. On an access point the daemon is a queue superuser, so a missing credential did not fail closed -- it escalated. A request whose authentication went wrong ended up with MORE authority than one whose went right.
The classification therefore has to come from somewhere that cannot be skipped by the failure it is meant to catch, which means the transport that accepted the request rather than the branch that authenticates it. See WithUserRequest.
const ( // OriginUnset is a context nobody has classified. What happens when one // reaches the daemon fallback is the process-wide policy's decision; // see SetUnmarkedOriginPolicy. OriginUnset CredentialOrigin = iota // OriginUser is a context acting for somebody who is not this daemon. // The daemon fallback is never right for one of these: the worst // acceptable outcome is an unauthenticated connection the peer refuses, // not an authenticated one the peer trusts completely. OriginUser // OriginDaemon is this daemon's own work -- queue mirroring, collector // advertising, a CCB relay, a health ping. Here the daemon credential is // the point rather than an accident. OriginDaemon )
func CredentialOriginFromContext ¶ added in v0.20.0
func CredentialOriginFromContext(ctx context.Context) (CredentialOrigin, string)
CredentialOriginFromContext reports how ctx was classified, and why.
func (CredentialOrigin) String ¶ added in v0.20.0
func (o CredentialOrigin) String() string
type CredentialReloader ¶ added in v0.2.0
type CredentialReloader interface {
Reload()
}
CredentialReloader is implemented by a SecurityConfig.Credentials value (e.g. *CredentialCache) that can drop cached credentials so the next read picks up rotated keys / renewed certs. A daemon wires this to its SIGHUP reconfigure.
type CredentialStatus ¶ added in v0.0.6
type CredentialStatus struct {
Exists bool `json:"exists"`
UpdatedAt *time.Time `json:"updated_at,omitempty"`
// Pending reports a credential that has been requested or stored but
// is not usable yet: the credd holds its request (.top) file and a
// credmon has not written the token (.use) from it. Exists is false
// while this is true.
Pending bool `json:"pending,omitempty"`
}
CredentialStatus describes whether a credential exists and when it was last updated.
type DaemonLocation ¶
DaemonLocation represents the location information for a daemon
type DaemonType ¶ added in v0.8.0
type DaemonType string
DaemonType identifies a kind of HTCondor daemon for LocateDaemon. It mirrors the daemon types used by the HTCondor Python bindings' Collector.locate().
A daemon type is distinct from the collector-query ad type: a schedd, for example, is DaemonSchedd but advertises a "Scheduler" ad queried as the "ScheddAd" ad type. LocateDaemon does that translation for you (see adType).
const ( DaemonSchedd DaemonType = "Schedd" DaemonStartd DaemonType = "Startd" DaemonMaster DaemonType = "Master" DaemonCollector DaemonType = "Collector" DaemonNegotiator DaemonType = "Negotiator" // DaemonPlacementd is condor_placementd. It advertises a generic ad // whose MyType is "PlacementD", so it is located through the generic-ad // query path rather than a dedicated QUERY_*_ADS command. DaemonPlacementd DaemonType = "PlacementD" )
Daemon types accepted by LocateDaemon.
type DialOptions ¶ added in v0.2.0
type DialOptions struct {
// Timeout bounds connection establishment (default 30s).
Timeout time.Duration
// CCBReturnAddr enables streaming/proxy mode when the address is a CCB
// sinful: it is this client's own CCB sinful (carrying a ccbid), used when
// the client itself is private and cannot accept a direct reverse
// connection. Leave empty for the common case (a publicly reachable tool
// dialing into a private daemon).
CCBReturnAddr string
// CCBRequireStreaming makes streaming mode mandatory: if the broker does
// not support it, DialSinful fails fast rather than attempting a direct
// reverse connection.
//
// Setting this alone is enough to select streaming; CCBReturnAddr is
// filled in for you. See DialSinful.
CCBRequireStreaming bool
// CCBReverseListener supplies the inbound path for a standard-mode CCB
// dial instead of a private TCP socket, letting a caller with no port of
// its own still accept connection reversal -- see
// ccb.DialOptions.ReverseListener and CCBDialer, which is what normally
// sets this.
//
// Ignored when CCBRequireStreaming or CCBReturnAddr select streaming: in
// streaming mode nothing reverses.
CCBReverseListener ccb.ReverseListenerFunc
}
DialOptions configures DialSinful, principally for reaching daemons behind a Condor Connection Broker (CCB).
type EditJobOptions ¶
type EditJobOptions struct {
// AllowProtectedAttrs allows editing of protected attributes (requires superuser privileges)
AllowProtectedAttrs bool
// Force allows editing even if some validations fail (use with caution)
Force bool
}
EditJobOptions contains options for editing jobs
type ErrDaemonFallbackRefused ¶ added in v0.20.0
type ErrDaemonFallbackRefused struct {
// Origin is how the context was classified: OriginUser for a refused
// caller, OriginUnset when the policy refuses unclassified contexts.
Origin CredentialOrigin
// Reason is the surface the classification was made at.
Reason string
// Command, Context and PeerName describe the connection that was about
// to be built, so a log line identifies which call was refused.
Command int
Context string
PeerName string
}
ErrDaemonFallbackRefused is returned when a context that is not this daemon's own work reaches the point where the daemon's credential would have been used.
It always means a bug in this server: some code path reached CEDAR without attaching the caller's credential (htcondor.WithSecurityConfig), or did the daemon's own work without saying so (htcondor.WithDaemonCredential). That advice is for whoever fixes the code, so it lives here rather than in the message, which reaches log readers and, through the HTTP handlers, users.
func (*ErrDaemonFallbackRefused) Error ¶ added in v0.20.0
func (e *ErrDaemonFallbackRefused) Error() string
type FileTransferClient ¶
type FileTransferClient struct {
// contains filtered or unexported fields
}
FileTransferClient handles client-side file transfers. Supports uploading files to schedd and downloading from schedd.
func NewFileTransferClient ¶
func NewFileTransferClient(daemonAddr string, daemonPort int, transKey string) *FileTransferClient
NewFileTransferClient creates a new file transfer client.
func (*FileTransferClient) DownloadFile ¶
func (ftc *FileTransferClient) DownloadFile(ctx context.Context, remotePath string, localPath string) error
DownloadFile downloads a single file from the schedd.
This implements the client side of the FILETRANS_DOWNLOAD protocol:
- Connect to daemon
- Perform security handshake
- Send FILETRANS_DOWNLOAD command
- Send transfer key (using Stream.PutSecret)
- Send file path request
- Receive file metadata
- Receive file data (using Stream.GetFile)
- Verify checksum if provided
Parameters:
- ctx: Context for cancellation
- remotePath: Path on schedd
- localPath: Where to save the file locally
Returns error if transfer fails.
NOTE: This implementation uses cedar v0.0.2+ APIs:
- Stream.PutSecret() for transfer key transmission
- Stream.GetFile() for efficient file streaming
TODO: Still missing Daemon.StartCommand() - currently must manually send command code.
func (*FileTransferClient) UploadFile ¶
func (ftc *FileTransferClient) UploadFile(ctx context.Context, item FileTransferItem) error
UploadFile uploads a single file to the schedd.
This implements the client side of the FILETRANS_UPLOAD protocol:
- Gather file metadata (size, permissions, checksum)
- Connect to daemon
- Perform security handshake
- Send FILETRANS_UPLOAD command
- Send transfer key (using Stream.PutSecret)
- Send file metadata
- Send CommandXferFile
- Send file data (using Stream.PutFile)
- Send CommandFinished
Parameters:
- ctx: Context for cancellation
- item: File metadata and paths
Returns error if transfer fails.
NOTE: This implementation uses cedar v0.0.2+ APIs:
- Stream.PutSecret() for transfer key transmission
- Stream.PutFile() for efficient file streaming
TODO: Still missing Daemon.StartCommand() - currently must manually send command code.
type FileTransferItem ¶
type FileTransferItem struct {
// SrcPath is the source file path (local for upload, remote for download)
SrcPath string
// DestPath is the destination file path
DestPath string
// FileSize is the size of the file in bytes
FileSize int64
// FileMode is the Unix file permissions (e.g., 0644, 0755)
FileMode uint32
// Checksum is optional SHA256 checksum for verification
Checksum string
// ChecksumType is the type of checksum (e.g., "SHA256")
ChecksumType string
}
FileTransferItem represents a single file to transfer. Contains metadata needed for the transfer protocol.
type FileTransferServer ¶
type FileTransferServer struct {
// contains filtered or unexported fields
}
FileTransferServer handles server-side file transfers. This would be implemented by schedd to handle incoming transfer requests.
NOTE: Server-side implementation requires command registration API from CEDAR which is not yet available. This is a placeholder for future implementation.
func NewFileTransferServer ¶
func NewFileTransferServer(transKey string, baseDir string) *FileTransferServer
NewFileTransferServer creates a new file transfer server handler.
func (*FileTransferServer) HandleDownload ¶
HandleDownload sends files to a client.
This would be registered as a command handler for FILETRANS_DOWNLOAD. The schedd calls this when a client requests a download.
Protocol:
- Receive transfer key and file request
- Send file metadata
- Send file data
- Send CommandFinished
NOTE: Command registration API not yet available in CEDAR Go library.
func (*FileTransferServer) HandleUpload ¶
HandleUpload receives files from a client.
This would be registered as a command handler for FILETRANS_UPLOAD. The schedd calls this when a client initiates an upload.
Protocol:
- Receive transfer key (already authenticated)
- Receive file metadata
- Receive file data
- Write to disk
- Wait for CommandFinished
NOTE: Command registration API not yet available in CEDAR Go library.
type HistoryAdResult ¶ added in v0.0.4
HistoryAdResult represents a single history ad or error from a streaming query
type HistoryQueryOptions ¶ added in v0.0.4
type HistoryQueryOptions struct {
// Source specifies the history record source to query
// Default is HistorySourceJobHistory
Source HistoryRecordSource
// Limit specifies the maximum number of results to return.
// Use 0 or negative value for unlimited results.
// Default is 50 if not specified.
Limit int
// ScanLimit specifies the maximum number of ads to scan.
// Use a negative value for unlimited scanning.
// Default (0) is DefaultHistoryScanLimit, to prevent timeouts on large
// pools. Set Stats to learn whether a query stopped at this limit.
ScanLimit int
// Projection is a list of attributes to include in results.
// Use nil or empty slice for default projections.
// Use []string{"*"} to include all attributes.
Projection []string
// Backwards controls the order of results.
// If true, returns results in reverse chronological order (newest first).
// If false, returns results in chronological order (oldest first).
// Default is true (backwards).
Backwards bool
// StreamResults requests that the server stream results as they are found
// rather than buffering all results before sending.
// Default is true for streaming.
StreamResults bool
// Since can be a job ID (e.g., "123.0") or a constraint expression
// to stop scanning when matched. Only used when Backwards is true.
Since string
// TransferTypes specifies which transfer types to include when
// Source is HistorySourceTransfer. Empty means all types.
TransferTypes []TransferType
// AdTypeFilter filters ads by their type (not MyType).
// Only applies to some history sources.
AdTypeFilter []string
// ReadFromDirectory requests reading from per-job epoch directory
// instead of aggregate history file. Only applies to epoch history.
ReadFromDirectory bool
// DaemonSubsystem specifies which daemon subsystem to query
// when Source is HistorySourceDaemon (e.g., "SCHEDD").
DaemonSubsystem string
// Stats, when non-nil, is filled in from the daemon's closing ad once
// the query completes successfully: how many records it examined and
// whether it stopped because of ScanLimit. It is not sent to the
// daemon. For a streaming query it is written before the result
// channel is closed, so it is safe to read after draining the channel.
Stats *HistoryScanStats
}
HistoryQueryOptions contains options for querying history records
func (*HistoryQueryOptions) ApplyDefaults ¶ added in v0.0.4
func (opts *HistoryQueryOptions) ApplyDefaults() HistoryQueryOptions
ApplyDefaults applies default values to HistoryQueryOptions
func (*HistoryQueryOptions) GetEffectiveProjection ¶ added in v0.0.4
func (opts *HistoryQueryOptions) GetEffectiveProjection() []string
GetEffectiveProjection returns the projection to use based on the source type
func (*HistoryQueryOptions) IsUnlimited ¶ added in v0.0.4
func (opts *HistoryQueryOptions) IsUnlimited() bool
IsUnlimited returns true if the query should return unlimited results
func (*HistoryQueryOptions) ShouldUseAllAttributes ¶ added in v0.0.4
func (opts *HistoryQueryOptions) ShouldUseAllAttributes() bool
ShouldUseAllAttributes returns true if all attributes should be returned
func (*HistoryQueryOptions) ShouldUseDefaultProjection ¶ added in v0.0.4
func (opts *HistoryQueryOptions) ShouldUseDefaultProjection() bool
ShouldUseDefaultProjection returns true if default projection should be used
type HistoryRecordSource ¶ added in v0.0.4
type HistoryRecordSource string
HistoryRecordSource specifies what type of history records to query
const ( // HistorySourceJobHistory queries standard job history (completed jobs) HistorySourceJobHistory HistoryRecordSource = "HISTORY" // HistorySourceJobEpoch queries job epoch history (per job run instance) // This includes records for each execution attempt of a job HistorySourceJobEpoch HistoryRecordSource = "JOB_EPOCH" // HistorySourceTransfer queries transfer history from job epochs // This includes file transfer events (input, output, checkpoint) HistorySourceTransfer HistoryRecordSource = "TRANSFER" // HistorySourceStartd queries startd history (from compute nodes) HistorySourceStartd HistoryRecordSource = "STARTD" // HistorySourceDaemon queries daemon history (historical daemon ads) HistorySourceDaemon HistoryRecordSource = "DAEMON" )
type HistoryScanStats ¶ added in v0.20.1
type HistoryScanStats struct {
// Reported is true when the daemon's closing ad carried AdCount.
// Without it the other counts are zero and ScanLimitReached is false
// because nothing can be concluded, not because the scan finished.
Reported bool
// RecordsScanned is the number of history records the daemon examined
// (AdCount).
RecordsScanned int
// Matches is the number of records that matched (NumMatches).
Matches int
// MalformedAds is the number of matching records the daemon could not
// send.
MalformedAds int
// ScanLimit is the scan limit the query was sent with; 0 means none.
ScanLimit int
// ScanLimitReached reports that the daemon stopped because it had
// examined ScanLimit records before finding Limit matches: older
// records were not searched, and more matches may exist there.
ScanLimitReached bool
}
HistoryScanStats is the daemon's own account of a history query, taken from the closing ad of the response. A query whose matches lie further back than the scan limit returns fewer records than asked for -- often none -- and this is the only place that says the search was cut short rather than exhausted.
type InMemoryCredd ¶ added in v0.0.6
type InMemoryCredd struct {
// contains filtered or unexported fields
}
InMemoryCredd provides a lightweight, non-persistent credd implementation useful for testing and demo environments. It is not intended for production credential storage.
func NewInMemoryCredd ¶ added in v0.0.6
func NewInMemoryCredd() *InMemoryCredd
NewInMemoryCredd constructs a new in-memory credd client.
func (*InMemoryCredd) CheckCreds ¶ added in v0.20.0
func (c *InMemoryCredd) CheckCreds(ctx context.Context, requests []CredRequest) (string, error)
CheckCreds reports whether every requested service credential is stored. There is no credmon here to create a missing one, so a missing credential is an error, as the credd reports a service it has no credmon for.
func (*InMemoryCredd) DeleteServiceCred ¶ added in v0.0.6
func (c *InMemoryCredd) DeleteServiceCred(ctx context.Context, credType CredType, service string, handle string, user string) error
DeleteServiceCred removes a service credential for a user.
func (*InMemoryCredd) DeleteUserCred ¶ added in v0.0.6
DeleteUserCred removes a user credential of the specified type.
func (*InMemoryCredd) GetCredential ¶ added in v0.0.6
func (c *InMemoryCredd) GetCredential(ctx context.Context, credType CredType, service string, handle string, user string) ([]byte, error)
GetCredential returns the stored credential payload for service/handle.
func (*InMemoryCredd) GetServiceCredStatus ¶ added in v0.0.6
func (c *InMemoryCredd) GetServiceCredStatus(ctx context.Context, credType CredType, service string, handle string, user string) (CredentialStatus, error)
GetServiceCredStatus reports status for a stored service credential.
func (*InMemoryCredd) GetUserCredStatus ¶ added in v0.0.6
func (c *InMemoryCredd) GetUserCredStatus(ctx context.Context, credType CredType, user string) (CredentialStatus, error)
GetUserCredStatus reports credential status for the specified user credential type.
func (*InMemoryCredd) ListServiceCreds ¶ added in v0.0.6
func (c *InMemoryCredd) ListServiceCreds(ctx context.Context, credType CredType, user string) ([]ServiceStatus, error)
ListServiceCreds returns all service credentials for the user and credType.
func (*InMemoryCredd) PutServiceCred ¶ added in v0.0.6
func (c *InMemoryCredd) PutServiceCred(ctx context.Context, credType CredType, credential []byte, service string, handle string, user string, refresh *bool) error
PutServiceCred stores an OAuth service credential for a user.
func (*InMemoryCredd) PutUserCred ¶ added in v0.0.6
func (c *InMemoryCredd) PutUserCred(ctx context.Context, credType CredType, credential []byte, user string) error
PutUserCred stores a user credential of the given type (Kerberos).
type JobAction ¶
type JobAction int
JobAction represents an action to perform on jobs
const ( JA_ERROR JobAction = iota // 0: Error/invalid action JA_HOLD_JOBS // 1: Hold jobs JA_RELEASE_JOBS // 2: Release held jobs JA_REMOVE_JOBS // 3: Remove jobs JA_REMOVE_X_JOBS // 4: Remove jobs with force (X = extended/force) JA_VACATE_JOBS // 5: Vacate jobs (gentle) JA_VACATE_FAST_JOBS // 6: Vacate jobs (fast/hard kill) JA_CLEAR_DIRTY_JOB_ATTRS // 7: Clear dirty job attributes JA_SUSPEND_JOBS // 8: Suspend jobs JA_CONTINUE_JOBS // 9: Continue suspended jobs JA_TRANSFER_AND_REMOVE_JOBS // 10: Spool then remove jobs )
Job action constants based on HTCondor's JobAction enum.
These values are placed on the wire as ATTR_JOB_ACTION and MUST match the C++ enum exactly (src/condor_utils/enum_utils.h:106-116):
JA_ERROR = 0, JA_HOLD_JOBS, JA_RELEASE_JOBS, JA_REMOVE_JOBS, JA_REMOVE_X_JOBS, JA_VACATE_JOBS, JA_VACATE_FAST_JOBS, JA_CLEAR_DIRTY_JOB_ATTRS, JA_SUSPEND_JOBS, JA_CONTINUE_JOBS, JA_TRANSFER_AND_REMOVE_JOBS
(An earlier version of this file omitted JA_CLEAR_DIRTY_JOB_ATTRS, which silently shifted JA_SUSPEND_JOBS/JA_CONTINUE_JOBS off by one relative to the schedd's switch in Scheduler::actOnJobs, src/condor_schedd.V6/schedd.cpp:7517.)
type JobActionRefusedError ¶ added in v0.20.0
type JobActionRefusedError struct {
Results *JobActionResults
}
JobActionRefusedError is a job action the schedd carried out on none of the jobs it was aimed at. It is an answer, not a failure to get one: Results says why, job by job -- nothing matched, the jobs were already in that state, permission was denied. Callers usually want to report that reason rather than a server error.
func (*JobActionRefusedError) Error ¶ added in v0.20.0
func (e *JobActionRefusedError) Error() string
func (*JobActionRefusedError) Is ¶ added in v0.20.0
func (e *JobActionRefusedError) Is(target error) bool
Is makes errors.Is(err, ErrNoJobsMatched) true when nothing matched.
type JobActionResults ¶
type JobActionResults struct {
// Total count of each result type
TotalJobs int
Success int
NotFound int
PermissionDenied int
BadStatus int
AlreadyDone int
LimitExceeded int
Error int
// The result ClassAd from the schedd (may contain per-job details)
ResultAd *classad.ClassAd
}
JobActionResults contains the results of a job action
func (*JobActionResults) Attempted ¶ added in v0.20.0
func (r *JobActionResults) Attempted() int
Attempted is the number of jobs the action reached: every one has exactly one outcome, so it is the sum of the outcome counts. Zero means nothing matched.
func (*JobActionResults) Summary ¶ added in v0.20.0
func (r *JobActionResults) Summary() string
Summary describes the outcomes other than success, e.g. "2 already in that state, 1 permission denied". Empty when every job succeeded.
type JobAdResult ¶ added in v0.0.4
JobAdResult represents a single job ad or error from a streaming query
type JobConnectInfo ¶ added in v0.0.11
type JobConnectInfo struct {
StarterAddr string // sinful string of the starter
ClaimID string // claim id for the schedd-minted starter session
StarterVersion string // starter's HTCondor version banner
RemoteHost string // slot name (cosmetic only, useful for logs)
// contains filtered or unexported fields
}
JobConnectInfo is the result of a GET_JOB_CONNECT_INFO call against the schedd. It is everything you need to talk to the starter on behalf of the user without going through the schedd again.
func (*JobConnectInfo) OpenSSH ¶ added in v0.0.11
func (info *JobConnectInfo) OpenSSH(ctx context.Context, opts *JobShellOptions) (*ssh.Client, error)
OpenSSH performs the START_SSHD step + crypto/ssh handshake against an already-located starter. This is the seam for tests and for advanced callers that want to look at the slot/version metadata first.
type JobShellOptions ¶ added in v0.0.11
type JobShellOptions struct {
// HandshakeTimeout caps the SSH handshake (NewClientConn). Default 30s.
HandshakeTimeout time.Duration
// CCB decides how to reach a starter that sits behind a Condor Connection
// Broker: on an inbound path of our own, or by having the broker relay.
//
// It matters because the default -- having the execute node dial back to
// us -- needs this process to be reachable from that node, which is not
// true of an API server in a container or behind NAT. The broker then
// tells the starter to connect to an address nothing routes to and the
// attempt times out with nothing to show for it. A nil CCB keeps that
// default, which is right for a tool running on a pool host. It costs
// nothing when the starter is not behind CCB -- the address decides
// whether CCB is involved at all.
CCB *CCBDialer
}
JobShellOptions tunes the SSH session. Zero values are fine for typical use.
type KeepAliveOptions ¶ added in v0.0.4
type KeepAliveOptions struct {
// HangTimeout is the grace period the master should allow before considering the daemon hung.
HangTimeout time.Duration
// Interval is how frequently to send keepalives. If zero, it is derived from HangTimeout.
Interval time.Duration
// DprintfLockDelay optionally reports the log lock hold time; omitted when zero.
DprintfLockDelay time.Duration
}
KeepAliveOptions controls keepalive payload and timing.
type Master ¶ added in v0.0.4
type Master struct {
// contains filtered or unexported fields
}
Master provides child-to-master control plane helpers for daemons launched by condor_master. It can send keepalive heartbeats and readiness notifications.
func MasterFromEnv ¶ added in v0.0.4
MasterFromEnv builds a Master using HTCondor's CONDOR_INHERIT metadata. It expects the CONDOR_INHERIT environment variable to contain the parent PID followed by the master's command sinful string (e.g., "1234 <127.0.0.1:9618>").
As a side effect, this also primes the global cedar SessionCache by touching it once: GetSessionCache() lazily imports inherited sessions from CONDOR_PRIVATE_INHERIT, and we want that import to happen at daemon startup rather than the first time we send DC_CHILDALIVE. Without the priming, a transient init race could cause our first keepalive to do a fresh handshake when an inherited family session was available all along — the master would then log `vscode@<host>` for that one DC_CHILDALIVE instead of `condor@child`, which is benign but makes audit logs noisier.
func NewMaster ¶ added in v0.0.4
NewMaster constructs a Master pointed at a specific command address.
func (*Master) DaemonName ¶ added in v0.0.4
DaemonName returns the configured daemon name (if provided).
func (*Master) ParentPID ¶ added in v0.0.4
ParentPID returns the parent PID parsed from CONDOR_INHERIT when available.
func (*Master) SendKeepAlive ¶ added in v0.0.4
func (m *Master) SendKeepAlive(ctx context.Context, opts *KeepAliveOptions) error
SendKeepAlive transmits a DC_CHILDALIVE heartbeat to condor_master.
func (*Master) SendReady ¶ added in v0.0.4
func (m *Master) SendReady(ctx context.Context, opts *ReadyOptions) error
SendReady transmits a DC_SET_READY notification indicating the daemon successfully initialized and is ready to serve work.
func (*Master) SetDaemonName ¶ added in v0.9.4
SetDaemonName sets the name reported to the master in DC_SET_READY (the "DaemonName" attribute the master logs as "Setting ready state ... for <name>"). The master identifies the daemon by PID, so this is for its logging/bookkeeping; callers use it to supply the subsystem name when _CONDOR_DAEMON_NAME is unset.
func (*Master) StartKeepAlive ¶ added in v0.0.4
func (m *Master) StartKeepAlive(ctx context.Context, opts *KeepAliveOptions) (stop func(), errs <-chan error, err error)
StartKeepAlive launches a background keepalive loop. It sends an initial heartbeat immediately, then repeats at the configured interval until the context is cancelled or Stop is invoked.
The returned stop function cancels the loop. The error channel is closed once the loop exits; non-nil errors are delivered through it.
type OutputRemap ¶ added in v0.0.4
type OutputRemap struct {
Source string // Original filename from the job sandbox
Destination string // Remapped destination path or URL
IsURL bool // True if destination is a URL (should be skipped in tarball)
}
OutputRemap represents a single output file remap entry
type PageInfo ¶ added in v0.0.4
type PageInfo struct {
// NextPageToken is the token to use for fetching the next page of results.
// Empty string if there are no more results.
NextPageToken string
// HasMoreResults indicates whether there are more results available
HasMoreResults bool
// TotalReturned is the number of results in the current response
TotalReturned int
}
PageInfo contains pagination metadata
type PeekRequest ¶ added in v0.0.12
type PeekRequest struct {
Stdout bool
StdoutOffset int64
Stderr bool
StderrOffset int64
// MaxBytes is the total cap shared across the requested
// streams. The starter splits it across files internally.
// Zero or negative falls back to DefaultPeekMaxBytes.
MaxBytes int64
// CCB decides how to reach a starter behind a Condor Connection Broker --
// see JobShellOptions.CCB, which is the same choice for the same reason on
// the shell path.
CCB *CCBDialer
}
PeekRequest controls a single STARTER_PEEK call.
An offset of -1 asks the starter to "tail" — return the last MaxBytes of the file. After a successful call the response carries the new absolute offset; pass that back in on the next call to stream incremental chunks (the same trick the condor_tail -follow loop uses).
type PeekResult ¶ added in v0.0.12
type PeekResult struct {
Stdout *PeekedStream
Stderr *PeekedStream
}
PeekResult carries whichever streams the caller asked for. Each pointer is non-nil iff the matching request flag was set AND the starter returned a payload for it.
type PeekedStream ¶ added in v0.0.12
type PeekedStream struct {
Bytes []byte
Offset int64 // absolute byte offset at the *end* of Bytes
}
PeekedStream is what came back for one of the requested streams.
type PingOptions ¶ added in v0.0.4
type PingOptions struct {
// CheckPermission specifies a permission level to check authorization for.
// If 0, only authentication is performed (DC_NOP).
// If set to one of DC_NOP_* constants, authorization is checked (DC_SEC_QUERY).
CheckPermission int
// Command, when set, is the DC_NOP_* command the ping sends in place of
// DC_NOP. DaemonCore registers DC_NOP at ALLOW, so a plain ping succeeds
// for any identity the daemon can authenticate; each DC_NOP_<LEVEL> is
// registered at its level, so the daemon refuses the handshake (post-auth
// ReturnCode DENIED) unless the identity is authorized there. The ping
// then fails rather than reporting a User.
//
// Unlike CheckPermission, which asks the daemon a question and reads its
// answer, this makes the ping itself an operation at that level. Mutually
// exclusive with CheckPermission.
Command int
}
PingOptions configures the ping operation
type PingResult ¶ added in v0.0.4
type PingResult struct {
// AuthMethod is the authentication method that was negotiated
AuthMethod string
// User is the authenticated username
User string
// SessionID is the session identifier
SessionID string
// ValidCommands is a string describing which commands are authorized
ValidCommands string
// Encryption indicates whether encryption was negotiated
Encryption bool
// Authentication indicates whether authentication was performed
Authentication bool
// Authorized reports the daemon's answer to the DC_SEC_QUERY probe:
// whether the authenticated identity would be permitted to run a
// command at the requested level. Only meaningful when
// PingOptions.CheckPermission was set; false otherwise. A daemon that
// refuses the level answers DENIED in the handshake itself (C++
// DaemonCore and cedar alike); that is reported here as false, with
// Reason, rather than as an error.
//
// Note this is an authorization answer, not an identity one. It says
// the daemon's ACLs admit whatever identity the connection presented;
// it says nothing about whether that identity still exists wherever it
// originated.
Authorized bool
// Permission is the permission level that was checked (e.g., "READ", "WRITE")
// Only set when CheckPermission is specified
Permission string
// Reason says why Authorized is false after a CheckPermission query:
// the daemon refused the level, or registers no command at it.
Reason string
// CommandNotFound reports that the daemon registers no command at the
// level CheckPermission queried (it answered CMD_NOT_FOUND), so it
// could not say whether the identity is authorized there. Authorized
// is false.
CommandNotFound bool
}
PingResult contains the result of a ping operation
type PlacementAuthorization ¶ added in v0.13.0
type PlacementAuthorization struct {
// Name is the authorization as it appears in a token's bounding set.
Name string
// Label is the human-readable name to show instead of Name.
Label string
// Color is the operator's suggested display color for the badge. It is
// whatever the map file says -- a CSS color name, a hex triplet, or a
// token meaningful only to a particular UI -- so treat it as a hint and
// have a fallback.
Color string
// Description is a sentence explaining what the authorization permits.
Description string
}
PlacementAuthorization is one authorization the placementd can grant, with the display metadata its authorizations map file carries so a UI can render the same labels and colors the reference portal does.
type PlacementError ¶ added in v0.13.0
PlacementError is an error the placementd reported in its reply ad, carrying the daemon's own ErrorCode/ErrorString rather than a transport failure. Callers that need to distinguish, say, "this user may not have that authorization" from "the schedd is down" should errors.As to this type and switch on Code against the PlacementErr* constants.
func (*PlacementError) Error ¶ added in v0.13.0
func (e *PlacementError) Error() string
type PlacementLoginRequest ¶ added in v0.13.0
type PlacementLoginRequest struct {
// UserName is the foreign identity to log in -- the left-hand column of
// the placementd map file, not the local AP account. Required.
UserName string
// Authorizations narrows the token's bounding set to these
// authorizations. Every entry must be one the user's map-file line
// grants, or the login is refused entirely (the daemon does not silently
// drop the ones it cannot grant). Empty means "everything this user is
// entitled to".
Authorizations []string
// Project ties the token, and so the jobs submitted with it, to an AP
// project. It must appear in the user's map-file project list. Empty
// means the token carries no project claim.
Project string
// Requester is the foreign identity of whoever is asking, when that is
// not the user being logged in -- an instructor minting a token for a
// student, say. The requester must itself be mapped and hold the
// INSTRUCTOR authorization. Empty means the user is requesting for
// themselves.
Requester string
}
PlacementLoginRequest asks the placementd to mint an IDToken.
type PlacementLoginResult ¶ added in v0.13.0
type PlacementLoginResult struct {
// Token is the signed IDToken. Treat it as a secret: it is a bearer
// credential for the AP identity it names.
Token string
// Ad is the daemon's full reply ad, so callers can read attributes this
// struct does not model yet.
Ad *classad.ClassAd
}
PlacementLoginResult is a successful login.
type PlacementToken ¶ added in v0.13.0
type PlacementToken struct {
// Requester is the foreign identity that asked for the token, which
// differs from UserName only for instructor-issued tokens.
Requester string
// UserName is the foreign identity the token was issued for.
UserName string
// APUserID is the local AP account named in the token's subject.
APUserID string
// Authorizations is the token's bounding set.
Authorizations []string
// TokenID is the token's jti claim, the handle for talking about one
// specific token.
TokenID string
// Expiration is the token's exp claim.
Expiration time.Time
// Project is the project claim, empty when the token carries none.
Project string
}
PlacementToken is one issued token as recorded in the placementd database. The token itself is not stored, only its identity and claims.
type PlacementTokenQuery ¶ added in v0.13.0
type PlacementTokenQuery struct {
// UserName restricts the result to tokens issued for one foreign
// identity.
UserName string
// TokenID restricts the result to the single token with this jti. It
// takes precedence over the other two fields: the daemon applies it
// alone.
TokenID string
// ValidOnly drops tokens that have already expired.
ValidOnly bool
}
PlacementTokenQuery narrows QueryTokens. A zero query returns every token the daemon has ever issued, expired ones included.
type PlacementUser ¶ added in v0.13.0
type PlacementUser struct {
// UserName is the foreign identity.
UserName string
// APUserID is the local AP account the identity maps to (the token's
// subject).
APUserID string
// TokenExpiration is when the newest unexpired token for this user runs
// out; the zero time means no live token.
TokenExpiration time.Time
// MappingExpiration is when the map-file entry itself stops being
// honored; the zero time means it never does.
MappingExpiration time.Time
// Projects are the AP projects this identity may bind a token to.
Projects []string
// Authorizations are the authorizations the map file grants.
Authorizations []string
// Authorized reports whether the identity is still in the map file. A
// user with live tokens but no map-file entry comes back with
// Authorized false: their tokens work until they expire, but they can no
// longer log in.
Authorized bool
}
PlacementUser is one row of the placementd's user view: the map-file entry for a foreign identity, merged with the newest unexpired token issued to it.
type Placementd ¶ added in v0.13.0
type Placementd struct {
// contains filtered or unexported fields
}
Placementd is a CEDAR client for condor_placementd.
Every command the daemon registers requires ADMINISTRATOR authorization and forced authentication, and the login command additionally refuses to run on an unencrypted channel (it would otherwise hand a bearer token to anyone on the path). This client therefore demands authentication and encryption on every connection rather than letting configuration weaken them.
func NewPlacementd ¶ added in v0.13.0
func NewPlacementd(address string) *Placementd
NewPlacementd returns a client for the placementd at address, a sinful string. Use Collector.LocateDaemon with DaemonPlacementd to find one.
func (*Placementd) Address ¶ added in v0.13.0
func (p *Placementd) Address() string
Address returns the sinful string this client talks to.
func (*Placementd) Login ¶ added in v0.13.0
func (p *Placementd) Login(ctx context.Context, req PlacementLoginRequest) (*PlacementLoginResult, error)
Login mints an IDToken for a foreign identity. See PlacementLoginRequest for what the daemon does with each field.
A login has a side effect beyond the token: the placementd creates the AP user record -- and the project record, when the request names a project -- in the schedd if they do not already exist. A login against a disabled user or project fails with PlacementErrSchedd rather than re-enabling it.
func (*Placementd) QueryAuthorizations ¶ added in v0.13.0
func (p *Placementd) QueryAuthorizations(ctx context.Context, userName string) ([]PlacementAuthorization, error)
QueryAuthorizations lists the authorizations the placementd can grant, with the display metadata from its authorizations map file. An empty userName lists every defined authorization; a non-empty one narrows the list to those that user may request, and fails with PlacementErrUserNotAuthorized if the user is not mapped.
func (*Placementd) QueryTokens ¶ added in v0.13.0
func (p *Placementd) QueryTokens(ctx context.Context, query PlacementTokenQuery) ([]PlacementToken, error)
QueryTokens lists tokens the placementd has issued. Tokens are never removed from its database, so an unfiltered query returns expired ones too; set PlacementTokenQuery.ValidOnly to see only live tokens.
func (*Placementd) QueryUsers ¶ added in v0.13.0
func (p *Placementd) QueryUsers(ctx context.Context, userName string) ([]PlacementUser, error)
QueryUsers lists the users the placementd knows about: everyone in its map file, plus anyone holding an unexpired token even if their mapping is gone (those come back with Authorized false). An empty userName lists all of them; a userName that is neither mapped nor holds a live token yields an empty result, not an error.
func (*Placementd) WithConfig ¶ added in v0.20.0
func (p *Placementd) WithConfig(cfg *config.Config) *Placementd
WithConfig sets the HTCondor configuration this placementd client uses; see the note above. The client's authentication and encryption requirements are not configurable either way.
type PlacementdClient ¶ added in v0.13.0
type PlacementdClient interface {
// Login mints an IDToken for a foreign identity.
Login(ctx context.Context, req PlacementLoginRequest) (*PlacementLoginResult, error)
// QueryUsers lists known users; an empty userName lists all of them.
QueryUsers(ctx context.Context, userName string) ([]PlacementUser, error)
// QueryTokens lists issued tokens.
QueryTokens(ctx context.Context, query PlacementTokenQuery) ([]PlacementToken, error)
// QueryAuthorizations lists grantable authorizations; a non-empty
// userName narrows the list to what that user may request.
QueryAuthorizations(ctx context.Context, userName string) ([]PlacementAuthorization, error)
}
PlacementdClient is the placementd operations, as an interface so callers (notably the web API) can substitute a fake in tests.
type QmgmtConnection ¶
type QmgmtConnection struct {
// contains filtered or unexported fields
}
QmgmtConnection represents an active connection to the schedd for queue management operations Implements HTCondor's QMGMT (Queue Management) protocol for job submission
Protocol Flow:
- TCP connection to schedd
- DC_AUTHENTICATE handshake
- QMGMT_WRITE_CMD (1112) to enter queue management mode
- GetCapabilities (10036) to query schedd capabilities
- BeginTransaction (10023)
- NewCluster (10002) → cluster ID
- NewProc (10003) → proc ID
- SetAttribute (10006) for each attribute
- CommitTransaction (10007)
- CloseSocket (10028)
func NewQmgmtConnection ¶
func NewQmgmtConnection(ctx context.Context, address string) (*QmgmtConnection, error)
NewQmgmtConnection establishes a queue management connection to the schedd Uses FS authentication from cedar package address can be a hostname:port or a sinful string like "<IP:PORT?addrs=...>"
func (*QmgmtConnection) AbortTransaction ¶
func (q *QmgmtConnection) AbortTransaction(ctx context.Context) error
AbortTransaction aborts a queue management transaction
func (*QmgmtConnection) BeginTransaction ¶
func (q *QmgmtConnection) BeginTransaction(ctx context.Context) error
BeginTransaction starts a queue management transaction
func (*QmgmtConnection) Close ¶
func (q *QmgmtConnection) Close() error
Close disconnects from the schedd queue
func (*QmgmtConnection) CommitTransaction ¶
func (q *QmgmtConnection) CommitTransaction(ctx context.Context) error
CommitTransaction commits a queue management transaction
func (*QmgmtConnection) DestroyCluster ¶
func (q *QmgmtConnection) DestroyCluster(ctx context.Context, clusterID int) error
DestroyCluster removes a cluster and all its procs
func (*QmgmtConnection) NewCluster ¶
func (q *QmgmtConnection) NewCluster(ctx context.Context) (int, error)
NewCluster allocates a new cluster ID
func (*QmgmtConnection) SendJobAttributes ¶
func (q *QmgmtConnection) SendJobAttributes(ctx context.Context, clusterID, procID int, ad *classad.ClassAd) error
SendJobAttributes sends all attributes from a ClassAd to the schedd for a specific job This iterates through the ClassAd and calls SetAttribute for each attribute
func (*QmgmtConnection) SetAttribute ¶
func (q *QmgmtConnection) SetAttribute(ctx context.Context, clusterID, procID int, attrName, attrValue string, flags SetAttributeFlags) error
SetAttribute sets an attribute on a job (cluster.proc) or cluster (cluster.-1)
func (*QmgmtConnection) SetAttributeInt ¶
func (q *QmgmtConnection) SetAttributeInt(ctx context.Context, clusterID, procID int, attrName string, value int, flags SetAttributeFlags) error
SetAttributeInt is a convenience method to set an integer attribute
func (*QmgmtConnection) SetEffectiveOwner ¶
func (q *QmgmtConnection) SetEffectiveOwner(ctx context.Context, owner string) error
SetEffectiveOwner sets the effective owner for subsequent job operations This must be called before setting job attributes as it determines the owner of the jobs
type QueryFetchOpts ¶ added in v0.0.4
type QueryFetchOpts int
QueryFetchOpts specifies what types of ads to fetch in a job query
const ( // FetchNormal fetches normal job ads (default) FetchNormal QueryFetchOpts = 0 // FetchMyJobs filters to only jobs owned by the authenticated user // Requires Owner to be set in QueryOptions FetchMyJobs QueryFetchOpts = 1 << 0 // FetchSummaryOnly returns summary information instead of individual job ads FetchSummaryOnly QueryFetchOpts = 1 << 1 // FetchIncludeClusterAd includes cluster ads in addition to proc ads FetchIncludeClusterAd QueryFetchOpts = 1 << 2 // FetchIncludeJobsetAds includes jobset ads in the query results FetchIncludeJobsetAds QueryFetchOpts = 1 << 3 // FetchNoProcAds excludes proc ads, only returning cluster/jobset ads FetchNoProcAds QueryFetchOpts = 1 << 4 )
type QueryOptions ¶ added in v0.0.4
type QueryOptions struct {
// Limit specifies the maximum number of results to return.
// Use 0 or negative value for unlimited results (opt-in with "*" in API).
// Default is 50 if not specified.
Limit int
// Projection is a list of attributes to include in results.
// Use nil or empty slice for default projections.
// Use []string{"*"} to include all attributes.
Projection []string
// PageToken is used for pagination. Empty string for first page.
// The token identifies where to continue fetching results.
PageToken string
// FetchOpts specifies query fetch options (MyJobs, SummaryOnly, etc.)
// Default is FetchNormal (0) which fetches all job ads
FetchOpts QueryFetchOpts
// Owner specifies the job owner for FetchMyJobs queries
// If empty and FetchMyJobs is set, uses authenticated username from context
Owner string
}
QueryOptions contains options for querying jobs and collector ads
func (*QueryOptions) ApplyDefaults ¶ added in v0.0.4
func (opts *QueryOptions) ApplyDefaults() QueryOptions
ApplyDefaults applies default values to QueryOptions.
It copies EVERY field. It used to rebuild the struct from Limit, Projection and PageToken alone, which silently dropped FetchOpts and Owner — so a caller asking to see only its own jobs got a query with no owner filter at all, on both the streaming and buffered paths. Adding a field to QueryOptions means adding it here too.
func (*QueryOptions) GetEffectiveProjection ¶ added in v0.0.4
func (opts *QueryOptions) GetEffectiveProjection(defaultProj []string) []string
GetEffectiveProjection returns the projection to use, applying defaults if needed
func (*QueryOptions) IsUnlimited ¶ added in v0.0.4
func (opts *QueryOptions) IsUnlimited() bool
IsUnlimited returns true if the query should return unlimited results
func (*QueryOptions) ShouldUseAllAttributes ¶ added in v0.0.4
func (opts *QueryOptions) ShouldUseAllAttributes() bool
ShouldUseAllAttributes returns true if all attributes should be returned
func (*QueryOptions) ShouldUseDefaultProjection ¶ added in v0.0.4
func (opts *QueryOptions) ShouldUseDefaultProjection() bool
ShouldUseDefaultProjection returns true if default projection should be used
type ReadyOptions ¶ added in v0.0.4
type ReadyOptions struct {
// State is a human-readable daemon state. Defaults to "Ready".
State string
// Name overrides the daemon name. If empty, Master.daemonName is used.
Name string
// Attributes adds custom ClassAd attributes to the readiness ping.
Attributes map[string]any
}
ReadyOptions customizes the ready-state notification.
type RescheduleOptions ¶ added in v0.1.0
type RescheduleOptions struct {
// MinInterval is the minimum gap between successful reschedule
// requests to this schedd. Zero disables the limiter for this
// call. Negative is treated as zero. If unset (zero value),
// DefaultRescheduleInterval applies.
MinInterval time.Duration
// Force, when true, sends the reschedule even if the limiter
// would otherwise skip it. Equivalent to MinInterval = 0 but
// reads better at call sites that want the limiter to *protect
// the schedd from us* most of the time and *not* protect it
// during, say, an end-to-end test setup.
Force bool
}
RescheduleOptions tunes Reschedule's behavior for a single call.
type Schedd ¶
type Schedd struct {
// contains filtered or unexported fields
}
Schedd represents an HTCondor schedd daemon
func NewSchedd ¶
NewSchedd creates a new Schedd instance address can be a hostname:port or a sinful string like "<IP:PORT?addrs=...>"
func (*Schedd) AggregateJobs ¶ added in v0.13.0
func (s *Schedd) AggregateJobs(ctx context.Context, constraint string, groupBy []string, opts *QueryOptions) ([]AggregateRow, error)
AggregateJobs counts jobs matching constraint, grouped by the given attributes. An empty groupBy returns a single total.
The counting happens on the schedd; the wire carries one row per group rather than one ad per job.
func (*Schedd) ConfigVal ¶ added in v0.13.0
ConfigVal asks a daemon for the value of one configuration parameter, the way `condor_config_val -<daemon>` does.
This reads the DAEMON's view of its configuration, which is the point: the answer can differ from what this process would compute locally, because the daemon may run on another host, have been started with a different CONDOR_CONFIG, or simply not have been reconfigured since the file changed. For anything used to make an authorization decision, the daemon's own answer is the only one that means anything.
The command is registered at READ authorization on the daemon side, so this needs no special privilege.
A parameter with no value returns ("", false, nil) — an unset knob is a normal answer, not a failure.
func (*Schedd) CreateStartupLimit ¶ added in v0.0.6
CreateStartupLimit creates or updates a startup rate limit in the schedd
Parameters:
- ctx: Context for the operation (can include security config via WithSecurityConfig)
- req: Startup limit parameters
Returns:
- UUID of the created/updated limit
- Error if the operation fails
Example:
req := &htcondor.StartupLimitRequest{
Tag: "gpu_limit",
Name: "GPU Job Rate Limit",
Expression: "RequestGpus > 0",
RateCount: 10,
RateWindow: 60, // 10 GPU jobs per minute
Expiration: 3600, // expires in 1 hour
}
uuid, err := schedd.CreateStartupLimit(ctx, req)
func (*Schedd) EditJob ¶
func (s *Schedd) EditJob(ctx context.Context, clusterID, procID int, attributes map[string]string, opts *EditJobOptions) error
EditJob edits attributes of an existing job This opens a QMGMT connection, edits the specified attributes, and commits the changes
func (*Schedd) EditJobAttributes ¶
func (s *Schedd) EditJobAttributes(ctx context.Context, clusterID, procID int, attributes *classad.ClassAd, opts *EditJobOptions) error
EditJobAttributes edits attributes using ClassAd values instead of strings This is useful when you need to set complex ClassAd expressions or values
func (*Schedd) EditJobByID ¶
func (s *Schedd) EditJobByID(ctx context.Context, jobID string, attributes map[string]string, opts *EditJobOptions) error
EditJobByID is a convenience method that parses a job ID string (e.g., "123.0") and calls EditJob
func (*Schedd) EditJobs ¶
func (s *Schedd) EditJobs(ctx context.Context, constraint string, attributes map[string]string, opts *EditJobOptions) (int, error)
EditJobs edits attributes for multiple jobs matching a constraint This is more efficient than calling EditJob multiple times as it uses a single transaction
func (*Schedd) GetJobConnectInfo ¶ added in v0.0.11
func (s *Schedd) GetJobConnectInfo(ctx context.Context, clusterID, procID int) (*JobConnectInfo, error)
GetJobConnectInfo invokes the schedd's GET_JOB_CONNECT_INFO RPC for ClusterId.ProcId and returns the address of the starter and the claim id for an on-demand session. The schedd authenticates the caller and verifies they own the job before minting the session.
func (*Schedd) GetUserRecord ¶ added in v0.13.0
GetUserRecord returns the record for one fully-qualified user, or nil when the schedd has no record of them.
A nil record is NOT a denial. The schedd creates records lazily on first submit, so a user who has only ever queried — or who is new — has no record at all. Callers gating access must treat nil as "no information".
func (*Schedd) HoldJobs ¶
func (s *Schedd) HoldJobs(ctx context.Context, constraint string, reason string) (*JobActionResults, error)
HoldJobs holds jobs matching the constraint
func (*Schedd) OpenJobShell ¶ added in v0.0.11
func (s *Schedd) OpenJobShell(ctx context.Context, clusterID, procID int, opts *JobShellOptions) (*ssh.Client, error)
OpenJobShell is the end-to-end convenience: GET_JOB_CONNECT_INFO + START_SSHD + crypto/ssh handshake. Returns a live *ssh.Client. The caller owns it and must Close() to release the underlying TCP connection.
Briefly transient errors at the schedd are retried (up to ~30 s) — the same race the C++ condor_ssh_to_job tool retries through after a job first hits Running but before the startd has registered the starter address.
func (*Schedd) PeekJobOutput ¶ added in v0.0.12
func (s *Schedd) PeekJobOutput(ctx context.Context, cluster, proc int, req PeekRequest) (*PeekResult, error)
PeekJobOutput is the public entry point. It looks up the running job's starter, resumes the schedd-minted session, runs one STARTER_PEEK round, and returns whichever streams were requested.
func (*Schedd) Ping ¶ added in v0.0.4
func (s *Schedd) Ping(ctx context.Context) (*PingResult, error)
Ping performs a ping operation against the schedd daemon This is similar to condor_ping and provides information about authentication and authorization. It's useful for health checks and debugging security settings.
func (*Schedd) PingWithOptions ¶ added in v0.0.4
func (s *Schedd) PingWithOptions(ctx context.Context, opts *PingOptions) (*PingResult, error)
PingWithOptions performs a ping operation with optional permission checking
func (*Schedd) Query
deprecated
func (s *Schedd) Query(ctx context.Context, constraint string, projection []string) ([]*classad.ClassAd, error)
Query queries the schedd for job advertisements constraint is a ClassAd constraint expression (use "true" to get all jobs) projection is a list of attributes to return (use nil to get all attributes)
Deprecated: Use QueryWithOptions for pagination and default limits/projections
func (*Schedd) QueryHistory ¶ added in v0.0.4
func (s *Schedd) QueryHistory(ctx context.Context, constraint string, projection []string) ([]*classad.ClassAd, error)
QueryHistory queries the schedd for job history records constraint is a ClassAd constraint expression (use "true" to get all records) projection is a list of attributes to return (use nil to get all attributes)
This method queries standard job history (completed jobs) by default. For epoch or transfer history, use QueryHistoryWithOptions.
func (*Schedd) QueryHistoryStream ¶ added in v0.0.4
func (s *Schedd) QueryHistoryStream(ctx context.Context, constraint string, opts *HistoryQueryOptions, streamOpts *StreamOptions) (<-chan HistoryAdResult, error)
QueryHistoryStream queries the schedd for history and streams ads through a channel Returns a channel and an error. If the error is non-nil, it indicates a problem before the request was sent (e.g., invalid parameters, connection failure). The channel will be closed when all ads have been sent or an error occurs during streaming.
func (*Schedd) QueryHistoryWithOptions ¶ added in v0.0.4
func (s *Schedd) QueryHistoryWithOptions(ctx context.Context, constraint string, opts *HistoryQueryOptions) ([]*classad.ClassAd, error)
QueryHistoryWithOptions queries the schedd for history records with options opts specifies query options including source type, limit, and projection Returns the matching history ads
func (*Schedd) QueryStartupLimits ¶ added in v0.0.6
QueryStartupLimits queries startup rate limits from the schedd
Parameters:
- ctx: Context for the operation (can include security config via WithSecurityConfig)
- uuid: Optional UUID to filter results (empty string = all limits)
- tag: Optional tag to filter results (empty string = all limits)
Returns:
- Slice of startup limits matching the query
- Error if the operation fails
Example:
// Get all limits limits, err := schedd.QueryStartupLimits(ctx, "", "") // Get specific limit by UUID limits, err := schedd.QueryStartupLimits(ctx, "abc123", "") // Get all limits with tag limits, err := schedd.QueryStartupLimits(ctx, "", "gpu_limit")
func (*Schedd) QueryStream
deprecated
added in
v0.0.4
func (s *Schedd) QueryStream(ctx context.Context, constraint string, projection []string, streamOpts *StreamOptions) (<-chan JobAdResult, error)
QueryStream queries the schedd and streams job ads through a channel Returns a channel and an error. If the error is non-nil, it indicates a problem before the request was sent (e.g., invalid parameters, connection failure). The channel will be closed when all ads have been sent or an error occurs during streaming. If cumulative time blocking on channel writes exceeds StreamOptions.WriteTimeout, an error is sent through the channel.
Deprecated: Use QueryStreamWithOptions for pagination and limit support
func (*Schedd) QueryStreamWithOptions ¶ added in v0.0.4
func (s *Schedd) QueryStreamWithOptions(ctx context.Context, constraint string, opts *QueryOptions, streamOpts *StreamOptions) (<-chan JobAdResult, error)
QueryStreamWithOptions queries the schedd with QueryOptions and streams job ads through a channel Returns a channel and an error. If the error is non-nil, it indicates a problem before the request was sent (e.g., invalid parameters, rate limit exceeded). This method supports server-side limits for better performance
func (*Schedd) QueryUserRecords ¶ added in v0.13.0
func (s *Schedd) QueryUserRecords(ctx context.Context, opts *UserRecordQueryOptions) (records []UserRecord, err error)
QueryUserRecords returns the schedd's user records matching opts.
The command is registered at READ authorization on the schedd side, so this needs no special privilege beyond what any query requires — in contrast to ENABLE_USERREC / DISABLE_USERREC, which are ADMINISTRATOR. That split is what makes these records usable as a revocation signal by an unprivileged service: an admin disables a user, and everything else can only observe it.
func (*Schedd) QueryWithOptions ¶ added in v0.0.4
func (s *Schedd) QueryWithOptions(ctx context.Context, constraint string, opts *QueryOptions) ([]*classad.ClassAd, *PageInfo, error)
QueryWithOptions queries the schedd for job advertisements with pagination and limits opts specifies query options including limit, projection, and pagination Returns the matching job ads and pagination info
func (*Schedd) QueueSuperUsers ¶ added in v0.13.0
QueueSuperUsers returns the schedd's effective QUEUE_SUPER_USERS set, in the identity form the schedd compares against: each configured name is returned both bare and qualified with the schedd's UID_DOMAIN.
The qualification mirrors what the schedd does when it builds its own set (see the "Backward compatibility hack" in qmgmt.cpp): QUEUE_SUPER_USERS historically named OS users, while authenticated identities are "user@domain", so a configured "condor" also makes "condor@$(UID_DOMAIN)" a superuser. A caller comparing an authenticated identity against this set would otherwise never match.
This does NOT reproduce every alternate identity the schedd accepts — condor@child, condor@parent and condor@password are session-internal identities that no web caller will ever present, and PERSONAL_CONDOR_IS_ SUPER_USER adds the process owner in a way that is only observable inside the daemon. The set returned here is therefore a SUBSET of what the schedd will accept: a caller may conclude "not a superuser" for an identity the schedd would in fact allow. That direction is the safe one — it costs a fallback to a less specific identity, never an unearned privilege.
func (*Schedd) ReceiveJobSandbox ¶
func (s *Schedd) ReceiveJobSandbox(ctx context.Context, constraint string, w io.Writer) <-chan error
ReceiveJobSandbox downloads job output files (sandbox) from the schedd for jobs matching the constraint. The files are written to a tar archive via the provided writer. This method starts the transfer in a goroutine and returns immediately. The caller should read from the returned channel to get the final result.
Protocol (based on DCSchedd::receiveJobSandbox in reference/dc_schedd.cpp):
- Connect to schedd and send TRANSFER_DATA_WITH_PERMS command
- Perform DC_AUTHENTICATE handshake
- Send version string (CondorVersion())
- Send constraint expression
- EOM
- Receive number of matching jobs (int)
- EOM
- For each job: a. Receive job ClassAd b. EOM c. Initialize FileTransfer with job ad d. Call FileTransfer.DownloadFiles() to receive files e. Files are sent using HTCondor's file transfer protocol
- Send OK reply (int = 0)
- EOM
constraint: ClassAd constraint expression to select jobs (e.g., "ClusterId == 123") w: Writer where the tar archive will be written Returns: A channel that will receive the error result (nil on success)
func (*Schedd) ReleaseJobs ¶
func (s *Schedd) ReleaseJobs(ctx context.Context, constraint string, reason string) (*JobActionResults, error)
ReleaseJobs releases held jobs matching the constraint
func (*Schedd) RemoveJobs ¶
func (s *Schedd) RemoveJobs(ctx context.Context, constraint string, reason string) (*JobActionResults, error)
RemoveJobs removes jobs matching the constraint constraint is a ClassAd constraint expression reason is an optional reason for the removal (can be empty string)
func (*Schedd) RemoveJobsByID ¶
func (s *Schedd) RemoveJobsByID(ctx context.Context, ids []string, reason string) (*JobActionResults, error)
RemoveJobsByID removes specific jobs by their cluster.proc IDs ids is a slice of job IDs in "cluster.proc" format (e.g., []string{"123.0", "123.1"}) reason is an optional reason for the removal (can be empty string)
func (*Schedd) Reschedule ¶ added in v0.1.0
Reschedule asks the schedd to push a fresh submitter ad to the collector and kick off a negotiation cycle. This is the wire-level equivalent of `condor_reschedule <schedd>`.
Why call this: after Schedd.Submit, the schedd doesn't immediately advertise a SubmitterAd; it waits SCHEDD_INTERVAL (default 300s) before its next collector update. The negotiator can't match the new job until a SubmitterAd arrives, so without Reschedule a fresh pool may take minutes to start the first job. condor_submit fires a reschedule itself; library callers must do the same.
Rate limiting: this client deliberately throttles successful reschedule requests to one every DefaultRescheduleInterval per schedd address (process-wide). The schedd treats reschedules as advisory anyway — it coalesces close-together requests — so dropping the duplicate on the client side is purely a courtesy. To bypass the limiter use RescheduleWithOptions with MinInterval = 0.
Errors: returns a non-nil error only when the connect/auth itself fails. A rate-limited skip returns nil; callers should treat Reschedule as advisory regardless. The context's deadline applies to the connect/auth attempt.
func (*Schedd) RescheduleWithOptions ¶ added in v0.1.0
func (s *Schedd) RescheduleWithOptions(ctx context.Context, opts *RescheduleOptions) error
RescheduleWithOptions is the configurable form of Reschedule. See the Reschedule doc for behavior; opts controls the rate limiter.
func (*Schedd) SpoolJobFilesFromFS ¶
func (s *Schedd) SpoolJobFilesFromFS(ctx context.Context, jobAds []*classad.ClassAd, fsys fs.FS) error
SpoolJobFilesFromFS uploads input files to the schedd for the specified jobs. Files are read from the provided filesystem.
The input files to transfer are determined from each job ad's TransferInput attribute. If TransferInput is not present, an error is returned.
Protocol (based on DCSchedd::spoolJobFiles in reference/dc_schedd.cpp):
- Connect to schedd and send SPOOL_JOB_FILES_WITH_PERMS command
- Perform DC_AUTHENTICATE handshake
- Send version string (CondorVersion())
- Send number of jobs (int)
- EOM
- For each job, send PROC_ID structure (cluster, proc)
- EOM
- For each job: a. Initialize FileTransfer with job ad b. Call FileTransfer.UploadFiles() to send files c. Files are sent using HTCondor's file transfer protocol
- EOM
- Receive reply (int, 1 = success, 0 = failure)
- EOM
jobAds: Array of job ClassAds containing ClusterId, ProcId, and TransferInput fsys: Filesystem containing the files to upload Returns: error if the upload fails
func (*Schedd) SpoolJobFilesFromTar ¶
func (s *Schedd) SpoolJobFilesFromTar(ctx context.Context, jobAds []*classad.ClassAd, r io.Reader) error
SpoolJobFilesFromTar uploads input files to the schedd for the specified jobs. Files are read from a tar archive.
Protocol: Same as SpoolJobFilesFromFS
The tar archive should be organized as:
- For single job: files directly at root (no cluster.proc prefix)
- For multiple jobs: cluster.proc/filename (e.g., "123.0/input.txt")
Files are spooled in the order they appear in the tar archive. Only files listed in the job's TransferInput are spooled. Files for jobs not in jobAds are ignored.
jobAds: Array of job ClassAds containing ClusterId, ProcId, and file transfer attributes r: Reader providing the tar archive Returns: error if the upload fails
func (*Schedd) Submit ¶
Submit submits a job to the schedd using an HTCondor submit file submitFileContent is the content of an HTCondor submit file Returns the cluster ID as a string
func (*Schedd) SubmitRemote ¶
func (s *Schedd) SubmitRemote(ctx context.Context, submitFileContent string) (clusterID int, procAds []*classad.ClassAd, err error)
SubmitRemote submits jobs to the schedd with remote submission semantics. This method is designed for remote job submission with file spooling support.
Remote submission behavior: 1. Parses the submit file 2. Ensures ShouldTransferFiles is set to YES 3. Jobs start in HELD status with SpoolingInput hold reason (code 16) 4. Sets LeaveJobInQueue to keep completed jobs for 10 days for output retrieval 5. Submits the job to the schedd 6. Returns the cluster ID and proc ads for subsequent file spooling
The caller should then use SpoolJobFilesFromFS or SpoolJobFilesFromTar to upload input files.
func (*Schedd) WithConfig ¶ added in v0.20.0
WithConfig sets the HTCondor configuration this Schedd uses; see the note above. It also applies to the JobConnectInfo it returns.
func (*Schedd) WithRateLimitKey ¶ added in v0.20.1
WithRateLimitKey gives this client its own partition of the schedd query rate limiter: a global budget of its own and per-user budgets of its own, at the configured rates, instead of the budget every client sharing its configuration draws on. A server talking to many schedds keys each by the schedd's name, so one busy schedd cannot starve the others. Empty (the default) is the shared budget.
type ScheddTarget ¶ added in v0.12.8
type ScheddTarget struct {
// Name is the schedd's name when SCHEDD_HOST was written as
// name@hostname, otherwise empty.
Name string
// Host is the machine the schedd runs on. May carry a ":port"
// suffix, in which case Address reports it as a directly dialable
// address and no collector lookup is needed.
Host string
}
ScheddTarget is what a SCHEDD_HOST setting points at. HTCondor documents the knob as "the host name of the machine where the condor_schedd is running for your pool", with the name included as name@hostname when that host sets SCHEDD_NAME or MASTER_NAME. It is undefined in most pools, so a defined value is a deliberate instruction to talk to that schedd rather than whichever one happens to be local or first in the collector.
func ParseScheddHost ¶ added in v0.12.8
func ParseScheddHost(value string) ScheddTarget
ParseScheddHost splits a SCHEDD_HOST value into its parts. An empty or whitespace-only value yields the zero ScheddTarget, whose IsSet reports false.
func (ScheddTarget) Address ¶ added in v0.12.8
func (t ScheddTarget) Address() string
Address returns a directly dialable address when SCHEDD_HOST included a port, and "" when the target still has to be looked up in the collector.
func (ScheddTarget) CollectorConstraint ¶ added in v0.12.8
func (t ScheddTarget) CollectorConstraint() string
CollectorConstraint returns the ClassAd constraint that selects this target's ScheddAd in the collector, or "" when the target names nothing to constrain on.
func (ScheddTarget) IsSet ¶ added in v0.12.8
func (t ScheddTarget) IsSet() bool
IsSet reports whether the target names anything.
type SecurityConfigRenewer ¶ added in v0.20.0
type SecurityConfigRenewer func(ctx context.Context) (*security.SecurityConfig, error)
SecurityConfigRenewer re-creates a caller's credential: a SecurityConfig like the one it was attached with, carrying a newly minted token.
It exists because the credential a server mints for a caller is meant for one request -- a minute or five -- while some of what a request starts outlives it: a stream that keeps polling, a watch shared by several viewers, a lease that removes a job when it runs out. Copying the request's token into those hands them a credential that expires under them. Copying the renewer instead lets them mint the caller's credential again, from the identity and authorization the original was minted for.
type ServiceStatus ¶ added in v0.0.6
type ServiceStatus struct {
Service string `json:"service"`
Handle string `json:"handle,omitempty"`
Exists bool `json:"exists"`
UpdatedAt *time.Time `json:"updated_at,omitempty"`
}
ServiceStatus describes the state of a service credential.
type SetAttributeFlags ¶
type SetAttributeFlags = qmgmt.SetAttributeFlags
SetAttributeFlags controls behavior when setting job attributes. It aliases the shared codec type in the qmgmt package.
const ( // SetAttributeNoAck indicates not to wait for acknowledgment when setting // attributes (SetAttribute_NoAck, bit 1<<1 in condor_qmgr.h). SetAttributeNoAck SetAttributeFlags = qmgmt.SetNoAck )
type Startd ¶ added in v0.20.0
type Startd struct {
// contains filtered or unexported fields
}
Startd is a client for one execution point's condor_startd. Today it speaks only the startd's remote-history protocol (GET_HISTORY, HTCondor 8.9.7+), which serves the per-job records the startd appends to its STARTD_HISTORY file as each job finishes on that machine. That file is the execution point's own view of what ran there -- it exists even for jobs whose submitting schedd is not ours, and it survives the schedd forgetting the job.
func NewStartd ¶ added in v0.20.0
NewStartd creates a new Startd instance. address can be a hostname:port or a sinful string like "<IP:PORT?addrs=...>".
func (*Startd) QueryHistory ¶ added in v0.20.0
func (s *Startd) QueryHistory(ctx context.Context, constraint string, projection []string) ([]*classad.ClassAd, error)
QueryHistory queries the startd for the job history records it wrote as jobs finished on that machine. constraint is a ClassAd constraint expression (use "true" or "" for all records); projection is the attributes to return (nil for condor_history's default set, []string{"*"} for every attribute).
func (*Startd) QueryHistoryStream ¶ added in v0.20.0
func (s *Startd) QueryHistoryStream(ctx context.Context, constraint string, opts *HistoryQueryOptions, streamOpts *StreamOptions) (<-chan HistoryAdResult, error)
QueryHistoryStream queries the startd's history and streams the records through a channel, which is closed when the query finishes or fails. A non-nil error means the query never started.
func (*Startd) QueryHistoryWithOptions ¶ added in v0.20.0
func (s *Startd) QueryHistoryWithOptions(ctx context.Context, constraint string, opts *HistoryQueryOptions) ([]*classad.ClassAd, error)
QueryHistoryWithOptions queries the startd's history with options. opts.Source is ignored -- the startd serves startd history and nothing else.
type StartupLimit ¶ added in v0.0.6
type StartupLimit struct {
UUID string `json:"uuid"`
Tag string `json:"tag"`
Name string `json:"name,omitempty"`
Expression string `json:"expression"`
CostExpression string `json:"cost_expression,omitempty"`
RateCount int `json:"rate_count"`
RateWindow int `json:"rate_window"` // seconds
Burst int `json:"burst,omitempty"`
MaxBurstCost int `json:"max_burst_cost,omitempty"`
Expiration int `json:"expiration,omitempty"` // seconds from creation
ExpiresAt int64 `json:"expires_at,omitempty"` // Unix timestamp
JobsAllowed int64 `json:"jobs_allowed,omitempty"` // Stats: jobs allowed
CostAllowed float64 `json:"cost_allowed,omitempty"` // Stats: cost allowed
JobsSkipped int64 `json:"jobs_skipped,omitempty"` // Stats: jobs skipped
MatchesIgnored int64 `json:"matches_ignored,omitempty"` // Stats: matches ignored
LastIgnored int64 `json:"last_ignored,omitempty"` // Stats: last time match ignored
IgnoredUsers string `json:"ignored_users,omitempty"` // Stats: comma-separated list
}
StartupLimit represents a startup rate limit in the schedd
type StartupLimitRequest ¶ added in v0.0.6
type StartupLimitRequest struct {
UUID string `json:"uuid,omitempty"` // If provided, updates existing limit
Tag string `json:"tag"` // Required: unique tag identifier
Name string `json:"name,omitempty"` // Optional: human-friendly name
Expression string `json:"expression"` // Required: ClassAd expression to match jobs
CostExpression string `json:"cost_expression,omitempty"` // Optional: expression for variable cost (default: 1)
RateCount int `json:"rate_count"` // Required: max jobs per window (0 = unlimited monitoring)
RateWindow int `json:"rate_window"` // Required: time window in seconds
Burst int `json:"burst,omitempty"` // Optional: extra capacity below zero
MaxBurstCost int `json:"max_burst_cost,omitempty"` // Optional: cap on single cost
Expiration int `json:"expiration,omitempty"` // Optional: expiration in seconds
}
StartupLimitRequest represents parameters for creating a startup limit
type StartupLimitResponse ¶ added in v0.0.6
type StartupLimitResponse struct {
Status int `json:"status"` // 0 = success, -1 = error
UUID string `json:"uuid,omitempty"` // UUID of created/updated limit
Error string `json:"error,omitempty"` // Error message if status != 0
}
StartupLimitResponse represents the response from creating a startup limit
type StreamOptions ¶ added in v0.0.4
type StreamOptions struct {
// BufferSize is the number of ads to buffer in the channel (default: 100)
BufferSize int
// WriteTimeout is the maximum cumulative time spent blocking on channel writes (default: 5s)
WriteTimeout time.Duration
}
StreamOptions configures streaming query behavior
func (*StreamOptions) ApplyStreamDefaults ¶ added in v0.0.4
func (o *StreamOptions) ApplyStreamDefaults() StreamOptions
ApplyStreamDefaults returns StreamOptions with defaults applied
type SubmitFile ¶
type SubmitFile struct {
// contains filtered or unexported fields
}
SubmitFile represents a parsed HTCondor submit file
func ParseSubmitFile ¶
func ParseSubmitFile(r io.Reader) (*SubmitFile, error)
ParseSubmitFile parses a submit file from a reader. The parse cannot reach the local host: see SubmitParseOptions.AllowLocalAccess and ParseSubmitFileWithOptions for a parse on behalf of the local user.
func ParseSubmitFileWithOptions ¶ added in v0.12.8
func ParseSubmitFileWithOptions(r io.Reader, opts SubmitParseOptions) (*SubmitFile, error)
ParseSubmitFileWithOptions parses a submit file from a reader with explicit parse options.
func (*SubmitFile) MakeClusterAd ¶
func (sf *SubmitFile) MakeClusterAd(clusterID int) (*classad.ClassAd, error)
MakeClusterAd creates a cluster ad with common attributes for all jobs This is part of late materialization - the cluster ad serves as a template
func (*SubmitFile) MakeJobAd ¶
MakeJobAd creates a ClassAd for a single job This is the main transformation from submit file to job ClassAd queueVars contains variable substitutions from the queue statement
func (*SubmitFile) MakeProcAd ¶
func (sf *SubmitFile) MakeProcAd(clusterID int, procID int, queueVars map[string]string) (*classad.ClassAd, error)
MakeProcAd creates a proc-specific ad given a cluster ad template This is used in late materialization to create individual proc ads efficiently
func (*SubmitFile) Submit ¶
func (sf *SubmitFile) Submit(clusterID int) (*SubmitResult, error)
Submit submits the jobs from this submit file Returns the cluster ID and number of procs created
func (*SubmitFile) SubmitLate ¶
func (sf *SubmitFile) SubmitLate(clusterID int) (*SubmitResult, error)
SubmitLate performs late materialization submission This creates a cluster ad template and individual proc ads with only differing attributes This is more efficient for large job submissions
type SubmitIterator ¶
type SubmitIterator interface {
// Next advances to the next item and returns true if successful
Next() bool
// Values returns the current row's variable values
Values() map[string]string
// Count returns the total number of items
Count() int
}
SubmitIterator provides iteration over queue items
type SubmitParseOptions ¶ added in v0.12.8
type SubmitParseOptions struct {
// AllowLocalAccess lets the parse reach the host it runs on:
// `include` and `include command` directives (the latter runs a
// shell command), the $ENV() macro function, `queue ... from
// <itemdata file>` and `queue ... matching <glob>`.
//
// Off by default, which is the setting a daemon parsing a submit
// file it received over the network wants: none of these should
// run with the daemon's identity on a remote caller's behalf —
// `include command` alone would be command execution as the daemon
// user. Set it for a submit file the local user wrote and that the
// parse runs on that user's behalf, which is how condor_submit
// reads one.
AllowLocalAccess bool
}
SubmitParseOptions controls what a submit-file parse is allowed to do besides reading the text it was handed.
type SubmitResult ¶
type SubmitResult struct {
ClusterID int
NumProcs int
ClusterAd *classad.ClassAd
ProcAds []*classad.ClassAd
}
SubmitResult contains the results of submitting jobs
type TestingT ¶ added in v0.0.4
type TestingT interface {
Helper()
Skip(...interface{})
Skipf(format string, args ...interface{})
Fatalf(format string, args ...interface{})
Logf(format string, args ...interface{})
Log(...interface{})
TempDir() string
Cleanup(func())
}
TestingT is an interface that matches the testing.T methods used by the test harness. This allows the harness to be used without directly depending on the testing package.
type TransferCommand ¶
type TransferCommand int32
TransferCommand represents file transfer protocol commands. These match the HTCondor C++ TransferCommand enum from file_transfer.cpp.
const ( // CommandFinished indicates transfer complete CommandFinished TransferCommand = 0 // CommandXferFile transfers a file CommandXferFile TransferCommand = 1 // CommandEnableEncryption enables encryption for subsequent transfers CommandEnableEncryption TransferCommand = 2 // CommandDisableEncryption disables encryption for subsequent transfers CommandDisableEncryption TransferCommand = 3 // CommandXferX509 transfers X.509 credential CommandXferX509 TransferCommand = 4 // CommandDownloadURL downloads from URL CommandDownloadURL TransferCommand = 5 // CommandMkdir creates directory CommandMkdir TransferCommand = 6 // CommandOther represents plugin-specific commands CommandOther TransferCommand = 999 )
type TransferType ¶ added in v0.0.4
type TransferType string
TransferType specifies the type of file transfer to query
const ( // TransferTypeInput queries input file transfers TransferTypeInput TransferType = "INPUT" // TransferTypeOutput queries output file transfers TransferTypeOutput TransferType = "OUTPUT" // TransferTypeCheckpoint queries checkpoint file transfers TransferTypeCheckpoint TransferType = "CHECKPOINT" )
type UnmarkedOriginPolicy ¶ added in v0.20.0
type UnmarkedOriginPolicy int32
UnmarkedOriginPolicy says what an unclassified context may do when it reaches the daemon fallback.
It is the dial that stages the migration. Every context in a daemon this large cannot be classified in one change, and a gate that refused the unclassified ones on day one would refuse the daemon's own background work along with the requests it is aimed at. So: Allow is today's behaviour and the default, Warn is the same plus a report per unmarked fallback naming the call, and Deny is the fail-closed end state where forgetting to classify a context breaks loudly rather than quietly running as a queue superuser.
const ( // UnmarkedAllow lets an unclassified context fall back to the daemon's // own configuration, as it always has. UnmarkedAllow UnmarkedOriginPolicy = iota // UnmarkedWarn allows the fallback and reports it, so the remaining // unclassified call sites can be enumerated from a running system // rather than guessed at from the source. UnmarkedWarn // UnmarkedDeny refuses an unclassified context the same way a // user-marked one is refused. UnmarkedDeny )
type UserRecord ¶ added in v0.13.0
type UserRecord struct {
// User is the fully-qualified user name, e.g. "alice@example.org".
User string
// Enabled reports whether the schedd will accept work from this user.
//
// It is a pointer because "the record does not say" is a distinct and
// common answer from "false": the attribute is written when an admin
// acts on the record (condor_qusers -enable/-disable), so an
// auto-created record that nobody has touched may not carry it at all.
// The schedd's own default for an unset value is enabled — its
// JobQueueUserRec initializes `enabled=true`, and placementd reads the
// attribute into a variable pre-set to 1 — so nil must be read as
// "not disabled", never as a denial.
Enabled *bool
// DisableReason is the note an admin attached with
// `condor_qusers -disable <user> -reason "..."`, when there is one.
DisableReason string
// Ad is the full record, for callers that want attributes beyond the
// few lifted out above.
Ad *classad.ClassAd
}
UserRecord is one of the schedd's per-user records, as returned by QUERY_USERREC_ADS. condor_qusers reads and writes the same records.
The schedd creates a record the first time a user submits, so the set of records is "users this schedd has seen", not "users who exist". A user with no record has simply never submitted here; that is not a statement about their standing. See Enabled.
func (*UserRecord) IsDisabled ¶ added in v0.13.0
func (u *UserRecord) IsDisabled() bool
IsDisabled reports whether the record affirmatively says this user is disabled. A record that does not mention Enabled returns false: absence of a statement is not a denial.
type UserRecordQueryOptions ¶ added in v0.13.0
type UserRecordQueryOptions struct {
// Constraint is a ClassAd expression evaluated against each record,
// e.g. `User == "alice@example.org"`.
Constraint string
// Projection limits the attributes returned. Empty returns everything.
// Note that a projection which omits Enabled makes every record look
// un-disabled, so include it whenever the answer matters.
Projection []string
// Limit caps the number of records returned. Zero or negative means
// no limit.
Limit int
}
UserRecordQueryOptions narrows a user-record query.
type WatchEvent ¶ added in v0.5.0
WatchEvent is one item in a collector watch stream (see Collector.WatchAds). Its Kind mirrors the collections engine's event kinds, plus GoingAway:
Upsert - Ad is the added/updated ad for Key
Delete - Key was removed (Ad is nil)
Reset - discard local state; an authoritative snapshot of Upserts follows
Synced - end of the initial snapshot/catch-up; now live. Cursor is durable
Resync - the live stream fell behind; reconnect with the last cursor
GoingAway - the server is shutting down; reconnect (with the last cursor),
possibly to another collector
Cursor, when non-nil (Synced and live events), is an opaque token to persist and pass back to WatchAds to resume without a full replay.
Source Files
¶
- advertise_utils.go
- ccb_trust.go
- ccbdial.go
- client_config.go
- collector.go
- collector_race.go
- collector_watch.go
- config_val.go
- credd.go
- credd_client.go
- credd_errors.go
- credential_origin.go
- credential_reader.go
- credential_renewal.go
- dial.go
- file_transfer.go
- history.go
- history_query.go
- htcondor.go
- locate.go
- master.go
- pagination.go
- ping.go
- placementd.go
- privnet.go
- query_options.go
- schedd.go
- schedd_actions.go
- schedd_aggregate.go
- schedd_edit.go
- schedd_history.go
- schedd_peek.go
- schedd_reschedule.go
- schedd_ssh.go
- schedd_startup_limits.go
- schedd_submit.go
- schedd_transfer.go
- security.go
- signing_keys.go
- startd.go
- submit.go
- submit_queue.go
- testharness.go
- userrec.go
Directories
¶
| Path | Synopsis |
|---|---|
|
Package authz implements HTCondor's host/user authorization: the ALLOW_<PERM>/DENY_<PERM> policy enforced by the C++ IpVerify class.
|
Package authz implements HTCondor's host/user authorization: the ALLOW_<PERM>/DENY_<PERM> policy enforced by the C++ IpVerify class. |
|
Package classadlog provides functionality for reading and parsing HTCondor job_queue.log files.
|
Package classadlog provides functionality for reading and parsing HTCondor job_queue.log files. |
|
Package config implements HTCondor configuration file parsing and management.
|
Package config implements HTCondor configuration file parsing and management. |
|
Package daemon provides the common bootstrap for an HTCondor daemon written in Go: configuration + HTCondor-compatible logging, condor_master integration (DC_SET_READY readiness and the DC_CHILDALIVE keepalive loop), shared-port listener adoption from CONDOR_INHERIT, and a graceful run loop driven by SIGTERM/SIGINT (terminate) and SIGHUP (reconfigure).
|
Package daemon provides the common bootstrap for an HTCondor daemon written in Go: configuration + HTCondor-compatible logging, condor_master integration (DC_SET_READY readiness and the DC_CHILDALIVE keepalive loop), shared-port listener adoption from CONDOR_INHERIT, and a graceful run loop driven by SIGTERM/SIGINT (terminate) and SIGHUP (reconfigure). |
|
Package droppriv provides privilege dropping functionality for Unix-like systems.
|
Package droppriv provides privilege dropping functionality for Unix-like systems. |
|
Example demonstrating metricsd streaming API usage with background collection
|
Example demonstrating metricsd streaming API usage with background collection |
|
classadlog_reader
command
Package main provides an example of using the classadlog package to monitor HTCondor job queue logs.
|
Package main provides an example of using the classadlog package to monitor HTCondor job queue logs. |
|
metrics_demo
command
Package main demonstrates using the metricsd package to collect and export HTCondor metrics
|
Package main demonstrates using the metricsd package to collect and export HTCondor metrics |
|
Package filetransfer implements the direction-neutral core of HTCondor's CEDAR file-transfer wire protocol (FileTransfer::DoUpload / DoDownload in src/condor_utils/file_transfer.cpp), factored out so that both the tool-side spool/receive paths (github.com/bbockelm/golang-htcondor Schedd methods) and the shadow-side transfer server (golang-ap internal/shadow) drive the exact same bytes.
|
Package filetransfer implements the direction-neutral core of HTCondor's CEDAR file-transfer wire protocol (FileTransfer::DoUpload / DoDownload in src/condor_utils/file_transfer.cpp), factored out so that both the tool-side spool/receive paths (github.com/bbockelm/golang-htcondor Schedd methods) and the shadow-side transfer server (golang-ap internal/shadow) drive the exact same bytes. |
|
fuzz
|
|
|
config
Package fuzzconfig holds the differential fuzz harness comparing the native Go config parser (github.com/bbockelm/golang-htcondor/config) against HTCondor's reference C++ parser (libcondor_utils, via the oracle subpackage).
|
Package fuzzconfig holds the differential fuzz harness comparing the native Go config parser (github.com/bbockelm/golang-htcondor/config) against HTCondor's reference C++ parser (libcondor_utils, via the oracle subpackage). |
|
config/oracle
Package oracle (stub build): without the `libcondor_utils` tag the C++ oracle is not linked, so the package still compiles (and `go vet ./...`, editors, and non-fuzz CI work) but ParseExpand is unavailable.
|
Package oracle (stub build): without the `libcondor_utils` tag the C++ oracle is not linked, so the package still compiles (and `go vet ./...`, editors, and non-fuzz CI work) but ParseExpand is unavailable. |
|
Package idmap resolves an identity asserted by an OIDC provider to a local Unix account, by matching the token's subject against accounts' GECOS fields.
|
Package idmap resolves an identity asserted by an OIDC provider to a local Unix account, by matching the token's subject against accounts' GECOS fields. |
|
internal
|
|
|
nullfile
Package nullfile identifies HTCondor's null file: the name a job ad carries for a standard stream that is not a real file.
|
Package nullfile identifies HTCondor's null file: the name a job ad carries for a standard stream that is not a real file. |
|
privatefile
Package privatefile creates and tightens files that other local users must not read, such as the SQLite databases the daemons and the HTTP API server keep session state and keys in.
|
Package privatefile creates and tightens files that other local users must not read, such as the SQLite databases the daemons and the HTTP API server keep session state and keys in. |
|
testdaemon
command
Command testdaemon is a minimal HTCondor daemon built on the daemon framework, used by the daemon-under-condor_master integration test.
|
Command testdaemon is a minimal HTCondor daemon built on the daemon framework, used by the daemon-under-condor_master integration test. |
|
Package jobid is the one place a job's identity becomes text and text becomes a job's identity.
|
Package jobid is the one place a job's identity becomes text and text becomes a job's identity. |
|
Package jobqueue mirrors a schedd's job_queue.log into a watch-enabled collections.Collection, so job ads can be watched -- resumable, constraint filtered, coalesced -- with the same subscription model as the collector's ad watch.
|
Package jobqueue mirrors a schedd's job_queue.log into a watch-enabled collections.Collection, so job ads can be watched -- resumable, constraint filtered, coalesced -- with the same subscription model as the collector's ad watch. |
|
localcredmon
module
|
|
|
Package logging provides structured logging functionality for HTCondor applications.
|
Package logging provides structured logging functionality for HTCondor applications. |
|
Package metricsd provides metrics collection for HTCondor daemons This is inspired by condor_gangliad but designed for more general metric export
|
Package metricsd provides metrics collection for HTCondor daemons This is inspired by condor_gangliad but designed for more general metric export |
|
Package qmgmt holds the shared codec for HTCondor's QMGMT (queue management) wire protocol: the operation constants, the SetAttribute flag bits, and the reply framing convention.
|
Package qmgmt holds the shared codec for HTCondor's QMGMT (queue management) wire protocol: the operation constants, the SetAttribute flag bits, and the reply framing convention. |
|
Package ratelimit provides rate limiting capabilities for HTCondor queries.
|
Package ratelimit provides rate limiting capabilities for HTCondor queries. |
|
Package sandbox provides utilities for creating and extracting HTCondor job sandboxes.
|
Package sandbox provides utilities for creating and extracting HTCondor job sandboxes. |
|
Package sessioncache persists a daemon's CEDAR security session cache so that clients can resume sessions across a restart instead of all re-authenticating at once.
|
Package sessioncache persists a daemon's CEDAR security session cache so that clients can resume sessions across a restart instead of all re-authenticating at once. |
|
sqlite
Package sqlite provides an encrypted-at-rest SQLite implementation of sessioncache.SessionStore.
|
Package sqlite provides an encrypted-at-rest SQLite implementation of sessioncache.SessionStore. |
|
Package sharedport implements the endpoint side of HTCondor's shared_port HTTP/HTTPS forwarding protocol.
|
Package sharedport implements the endpoint side of HTCondor's shared_port HTTP/HTTPS forwarding protocol. |
|
Package startd implements the schedd->startd claim protocol: the CEDAR command exchange a schedd uses to REQUEST_CLAIM a slot, RELEASE_CLAIM it, and DEACTIVATE_CLAIM a running job on it.
|
Package startd implements the schedd->startd claim protocol: the CEDAR command exchange a schedd uses to REQUEST_CLAIM a slot, RELEASE_CLAIM it, and DEACTIVATE_CLAIM a running job on it. |
|
Package syscalls implements the STARTER-side (client) senders for HTCondor's shadow<->starter remote-syscall protocol.
|
Package syscalls implements the STARTER-side (client) senders for HTCondor's shadow<->starter remote-syscall protocol. |
|
Package userlog parses HTCondor user-log files (the file pointed at by `log = ...` in a submit description).
|
Package userlog parses HTCondor user-log files (the file pointed at by `log = ...` in a submit description). |
|
Package version exposes build-time version information for the golang-htcondor binaries.
|
Package version exposes build-time version information for the golang-htcondor binaries. |
|
webapi
module
|