mirror of
https://github.com/harness/drone.git
synced 2025-05-04 02:01:57 +08:00
* feat: [CDE-681]: Find infra from DB and status from GCP (#3538) * Merge branch 'hybrid' into CDE-681 * feat: [CDE-681]: fix lint * feat: [CDE-681]: fix lint * feat: [CDE-681]: merge * feat: [CDE-681]: fix wiring * feat: [CDE-681]: handle delete and fallback for it * feat: [CDE-681]: handle delete and fallback for it * feat: [CDE-681]: Find infra from DB and status from GCP * feat: [CDE-681]: Find infra from DB and status from GCP * feat: [CDE-681]: Find infra from DB and status from GCP * feat: [CDE-681]: Find infra from DB and status from GCP * feat: [CDE-681]: Find infra from DB and status from GCP * feat: [CDE-681]: merge * feat: [CDE-661]: set starting state by default in resume * Merge branch 'main' into hybrid * feat: [CDE-661]: fix host and port (#3511) * feat: [CDE-661]: fix host and port * feat: [CDE-661]: fix host and port * feat: [CDE-661]: send remove request for hybrid (#3500) * feat: [CDE-661]: add debug logs * feat: [CDE-661]: send remove request for hybrid * feat:
This commit is contained in:
parent
0a573a566c
commit
ff18742bdd
20
app/events/gitspaceoperations/category.go
Normal file
20
app/events/gitspaceoperations/category.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// Copyright 2023 Harness, Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package events
|
||||||
|
|
||||||
|
const (
|
||||||
|
// category defines the event category used for this package.
|
||||||
|
category = "gitspace_operations"
|
||||||
|
)
|
63
app/events/gitspaceoperations/events.go
Normal file
63
app/events/gitspaceoperations/events.go
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// Copyright 2023 Harness, Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package events
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/harness/gitness/events"
|
||||||
|
"github.com/harness/gitness/types"
|
||||||
|
"github.com/harness/gitness/types/enum"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
GitspaceOperationsEvent events.EventType = "gitspace_operations_event"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
GitspaceOperationsEventPayload struct {
|
||||||
|
Type enum.GitspaceOperationsEvent `json:"type"`
|
||||||
|
Infra types.Infrastructure `json:"infra,omitempty"`
|
||||||
|
Response any `json:"response,omitempty"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (r *Reporter) EmitGitspaceOperationsEvent(
|
||||||
|
ctx context.Context,
|
||||||
|
event events.EventType,
|
||||||
|
payload *GitspaceOperationsEventPayload,
|
||||||
|
) error {
|
||||||
|
if payload == nil {
|
||||||
|
return fmt.Errorf("payload can not be nil for event type %s", GitspaceOperationsEvent)
|
||||||
|
}
|
||||||
|
eventID, err := events.ReporterSendEvent(r.innerReporter, ctx, event, payload)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to send %+v event", event)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Ctx(ctx).Debug().Msgf("reported %v event with id '%s'", event, eventID)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Reader) RegisterGitspaceOperationsEvent(
|
||||||
|
fn events.HandlerFunc[*GitspaceOperationsEventPayload],
|
||||||
|
opts ...events.HandlerOption,
|
||||||
|
) error {
|
||||||
|
return events.ReaderRegisterEvent(r.innerReader, GitspaceOperationsEvent, fn, opts...)
|
||||||
|
}
|
38
app/events/gitspaceoperations/reader.go
Normal file
38
app/events/gitspaceoperations/reader.go
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// Copyright 2023 Harness, Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package events
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/harness/gitness/events"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewReaderFactory(eventsSystem *events.System) (*events.ReaderFactory[*Reader], error) {
|
||||||
|
readerFactoryFunc := func(innerReader *events.GenericReader) (*Reader, error) {
|
||||||
|
return &Reader{
|
||||||
|
innerReader: innerReader,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return events.NewReaderFactory(eventsSystem, category, readerFactoryFunc)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reader is the event reader for this package.
|
||||||
|
type Reader struct {
|
||||||
|
innerReader *events.GenericReader
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Reader) Configure(opts ...events.ReaderOption) {
|
||||||
|
r.innerReader.Configure(opts...)
|
||||||
|
}
|
37
app/events/gitspaceoperations/reporter.go
Normal file
37
app/events/gitspaceoperations/reporter.go
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// Copyright 2023 Harness, Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package events
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/harness/gitness/events"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Reporter is the event reporter for this package.
|
||||||
|
type Reporter struct {
|
||||||
|
innerReporter *events.GenericReporter
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewReporter(eventsSystem *events.System) (*Reporter, error) {
|
||||||
|
innerReporter, err := events.NewReporter(eventsSystem, category)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("failed to create new GenericReporter from event system")
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Reporter{
|
||||||
|
innerReporter: innerReporter,
|
||||||
|
}, nil
|
||||||
|
}
|
35
app/events/gitspaceoperations/wire.go
Normal file
35
app/events/gitspaceoperations/wire.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// Copyright 2023 Harness, Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package events
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/harness/gitness/events"
|
||||||
|
|
||||||
|
"github.com/google/wire"
|
||||||
|
)
|
||||||
|
|
||||||
|
// WireSet provides a wire set for this package.
|
||||||
|
var WireSet = wire.NewSet(
|
||||||
|
ProvideReaderFactory,
|
||||||
|
ProvideReporter,
|
||||||
|
)
|
||||||
|
|
||||||
|
func ProvideReaderFactory(eventsSystem *events.System) (*events.ReaderFactory[*Reader], error) {
|
||||||
|
return NewReaderFactory(eventsSystem)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ProvideReporter(eventsSystem *events.System) (*Reporter, error) {
|
||||||
|
return NewReporter(eventsSystem)
|
||||||
|
}
|
@ -28,7 +28,6 @@ import (
|
|||||||
func (i InfraProvisioner) Find(
|
func (i InfraProvisioner) Find(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
gitspaceConfig types.GitspaceConfig,
|
gitspaceConfig types.GitspaceConfig,
|
||||||
requiredGitspacePorts []types.GitspacePort,
|
|
||||||
) (*types.Infrastructure, error) {
|
) (*types.Infrastructure, error) {
|
||||||
infraProviderResource := gitspaceConfig.InfraProviderResource
|
infraProviderResource := gitspaceConfig.InfraProviderResource
|
||||||
infraProviderEntity, err := i.getConfigFromResource(ctx, infraProviderResource)
|
infraProviderEntity, err := i.getConfigFromResource(ctx, infraProviderResource)
|
||||||
@ -41,35 +40,43 @@ func (i InfraProvisioner) Find(
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var inputParams []types.InfraProviderParameter
|
var infra *types.Infrastructure
|
||||||
var configMetadata map[string]any
|
//nolint:nestif
|
||||||
var agentPort = 0
|
|
||||||
if infraProvider.ProvisioningType() == enum.InfraProvisioningTypeNew {
|
if infraProvider.ProvisioningType() == enum.InfraProvisioningTypeNew {
|
||||||
inputParams, configMetadata, err = i.paramsForProvisioningTypeNew(ctx, gitspaceConfig)
|
inputParams, _, err := i.paramsForProvisioningTypeNew(ctx, gitspaceConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
infra, err = i.GetInfraFromStoredInfo(ctx, gitspaceConfig)
|
||||||
// TODO: What if the agent port has deviated from when the last instance was created?
|
if err != nil {
|
||||||
agentPort = i.config.AgentPort
|
return nil, fmt.Errorf("failed to find infrastructure from stored info: %w", err)
|
||||||
|
}
|
||||||
|
status, err := infraProvider.FindInfraStatus(
|
||||||
|
ctx,
|
||||||
|
gitspaceConfig.Identifier,
|
||||||
|
gitspaceConfig.GitspaceInstance.Identifier,
|
||||||
|
inputParams,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to find infra status: %w", err)
|
||||||
|
}
|
||||||
|
if status != nil {
|
||||||
|
infra.Status = *status
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
inputParams, configMetadata, err = i.paramsForProvisioningTypeExisting(ctx, infraProviderResource, infraProvider)
|
inputParams, _, err := i.paramsForProvisioningTypeExisting(ctx, infraProviderResource, infraProvider)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
infra, err = infraProvider.Find(
|
||||||
|
ctx,
|
||||||
infra, err := infraProvider.Find(ctx, gitspaceConfig.SpaceID, gitspaceConfig.SpacePath,
|
gitspaceConfig.SpaceID,
|
||||||
gitspaceConfig.Identifier, gitspaceConfig.GitspaceInstance.Identifier,
|
gitspaceConfig.SpacePath,
|
||||||
agentPort, requiredGitspacePorts, inputParams, configMetadata)
|
gitspaceConfig.Identifier,
|
||||||
|
inputParams,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to find infrastructure: %w", err)
|
return nil, fmt.Errorf("failed to find infrastructure from provider: %w", err)
|
||||||
}
|
|
||||||
|
|
||||||
if infra == nil { // fallback
|
|
||||||
infra, err = i.getInfraFromStoredInfo(ctx, gitspaceConfig)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to build infrastructure from stored info: %w", err)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,7 +150,7 @@ func getGitspaceScheme(ideType enum.IDEType, gitspaceSchemeFromMetadata string)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i InfraProvisioner) getInfraFromStoredInfo(
|
func (i InfraProvisioner) GetInfraFromStoredInfo(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
gitspaceConfig types.GitspaceConfig,
|
gitspaceConfig types.GitspaceConfig,
|
||||||
) (*types.Infrastructure, error) {
|
) (*types.Infrastructure, error) {
|
||||||
|
@ -18,6 +18,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -47,13 +48,13 @@ func (i InfraProvisioner) PostInfraEventComplete(
|
|||||||
enum.InfraEventDeprovision,
|
enum.InfraEventDeprovision,
|
||||||
enum.InfraEventStop,
|
enum.InfraEventStop,
|
||||||
enum.InfraEventCleanup:
|
enum.InfraEventCleanup:
|
||||||
return i.updateInfraProvisioned(ctx, gitspaceConfig.GitspaceInstance.ID, infra)
|
return i.UpdateInfraProvisioned(ctx, gitspaceConfig.GitspaceInstance.ID, infra)
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unsupported event type: %s", eventType)
|
return fmt.Errorf("unsupported event type: %s", eventType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i InfraProvisioner) updateInfraProvisioned(
|
func (i InfraProvisioner) UpdateInfraProvisioned(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
gitspaceInstanceID int64,
|
gitspaceInstanceID int64,
|
||||||
infrastructure types.Infrastructure,
|
infrastructure types.Infrastructure,
|
||||||
@ -72,8 +73,22 @@ func (i InfraProvisioner) updateInfraProvisioned(
|
|||||||
infraProvisionedLatest.InfraStatus = infrastructure.Status
|
infraProvisionedLatest.InfraStatus = infrastructure.Status
|
||||||
infraProvisionedLatest.ServerHostIP = infrastructure.AgentHost
|
infraProvisionedLatest.ServerHostIP = infrastructure.AgentHost
|
||||||
infraProvisionedLatest.ServerHostPort = strconv.Itoa(infrastructure.AgentPort)
|
infraProvisionedLatest.ServerHostPort = strconv.Itoa(infrastructure.AgentPort)
|
||||||
infraProvisionedLatest.ProxyHost = infrastructure.ProxyAgentHost
|
|
||||||
infraProvisionedLatest.ProxyPort = int32(infrastructure.ProxyAgentPort)
|
proxyHost := infrastructure.AgentHost
|
||||||
|
if infrastructure.ProxyAgentHost != "" {
|
||||||
|
proxyHost = infrastructure.ProxyAgentHost
|
||||||
|
}
|
||||||
|
infraProvisionedLatest.ProxyHost = proxyHost
|
||||||
|
|
||||||
|
proxyPort := infrastructure.AgentPort
|
||||||
|
if infrastructure.ProxyAgentPort != 0 {
|
||||||
|
proxyPort = infrastructure.ProxyAgentPort
|
||||||
|
}
|
||||||
|
if proxyPort > math.MaxInt32 || proxyPort < math.MinInt32 {
|
||||||
|
return fmt.Errorf("proxyPort value %d exceeds int32 range", proxyPort)
|
||||||
|
}
|
||||||
|
infraProvisionedLatest.ProxyPort = int32(proxyPort)
|
||||||
|
|
||||||
infraProvisionedLatest.ResponseMetadata = &responseMetaDataJSON
|
infraProvisionedLatest.ResponseMetadata = &responseMetaDataJSON
|
||||||
infraProvisionedLatest.Updated = time.Now().UnixMilli()
|
infraProvisionedLatest.Updated = time.Now().UnixMilli()
|
||||||
|
|
||||||
|
@ -163,6 +163,22 @@ func (i InfraProvisioner) provisionNewInfrastructure(
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
infrastructure := types.Infrastructure{
|
||||||
|
Identifier: gitspaceConfig.GitspaceInstance.Identifier,
|
||||||
|
SpaceID: gitspaceConfig.SpaceID,
|
||||||
|
SpacePath: gitspaceConfig.SpacePath,
|
||||||
|
GitspaceConfigIdentifier: gitspaceConfig.Identifier,
|
||||||
|
GitspaceInstanceIdentifier: gitspaceConfig.GitspaceInstance.Identifier,
|
||||||
|
ProviderType: infraProviderType,
|
||||||
|
InputParameters: allParams,
|
||||||
|
ConfigMetadata: configMetadata,
|
||||||
|
}
|
||||||
|
responseMetadata, err := json.Marshal(infrastructure)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to marshal infra object %+v: %w", responseMetadata, err)
|
||||||
|
}
|
||||||
|
responseMetaDataJSON := string(responseMetadata)
|
||||||
|
|
||||||
infraProvisioned := &types.InfraProvisioned{
|
infraProvisioned := &types.InfraProvisioned{
|
||||||
GitspaceInstanceID: gitspaceConfig.GitspaceInstance.ID,
|
GitspaceInstanceID: gitspaceConfig.GitspaceInstance.ID,
|
||||||
InfraProviderType: infraProviderType,
|
InfraProviderType: infraProviderType,
|
||||||
@ -172,6 +188,7 @@ func (i InfraProvisioner) provisionNewInfrastructure(
|
|||||||
InputParams: paramsBytes,
|
InputParams: paramsBytes,
|
||||||
InfraStatus: enum.InfraStatusPending,
|
InfraStatus: enum.InfraStatusPending,
|
||||||
SpaceID: gitspaceConfig.SpaceID,
|
SpaceID: gitspaceConfig.SpaceID,
|
||||||
|
ResponseMetadata: &responseMetaDataJSON,
|
||||||
}
|
}
|
||||||
|
|
||||||
err = i.infraProvisionedStore.Create(ctx, infraProvisioned)
|
err = i.infraProvisionedStore.Create(ctx, infraProvisioned)
|
||||||
@ -190,7 +207,6 @@ func (i InfraProvisioner) provisionNewInfrastructure(
|
|||||||
agentPort,
|
agentPort,
|
||||||
requiredGitspacePorts,
|
requiredGitspacePorts,
|
||||||
allParams,
|
allParams,
|
||||||
configMetadata,
|
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
infraProvisioned.InfraStatus = enum.InfraStatusUnknown
|
infraProvisioned.InfraStatus = enum.InfraStatusUnknown
|
||||||
@ -216,7 +232,7 @@ func (i InfraProvisioner) provisionExistingInfrastructure(
|
|||||||
gitspaceConfig types.GitspaceConfig,
|
gitspaceConfig types.GitspaceConfig,
|
||||||
requiredGitspacePorts []types.GitspacePort,
|
requiredGitspacePorts []types.GitspacePort,
|
||||||
) error {
|
) error {
|
||||||
allParams, configMetadata, err := i.getAllParamsFromDB(ctx, gitspaceConfig.InfraProviderResource, infraProvider)
|
allParams, _, err := i.getAllParamsFromDB(ctx, gitspaceConfig.InfraProviderResource, infraProvider)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not get all params from DB while provisioning: %w", err)
|
return fmt.Errorf("could not get all params from DB while provisioning: %w", err)
|
||||||
}
|
}
|
||||||
@ -235,7 +251,6 @@ func (i InfraProvisioner) provisionExistingInfrastructure(
|
|||||||
0, // NOTE: Agent port is not required for provisioning type Existing.
|
0, // NOTE: Agent port is not required for provisioning type Existing.
|
||||||
requiredGitspacePorts,
|
requiredGitspacePorts,
|
||||||
allParams,
|
allParams,
|
||||||
configMetadata,
|
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf(
|
return fmt.Errorf(
|
||||||
|
@ -33,13 +33,21 @@ type Orchestrator interface {
|
|||||||
resolvedDetails scm.ResolvedDetails,
|
resolvedDetails scm.ResolvedDetails,
|
||||||
defaultBaseImage string,
|
defaultBaseImage string,
|
||||||
ideService ide.IDE,
|
ideService ide.IDE,
|
||||||
) (*StartResponse, error)
|
) error
|
||||||
|
|
||||||
|
// RetryCreateAndStartGitspaceIfRequired will handle the delegate task response and retry if status code is > 202
|
||||||
|
RetryCreateAndStartGitspaceIfRequired(ctx context.Context)
|
||||||
|
|
||||||
// StopGitspace stops the gitspace container.
|
// StopGitspace stops the gitspace container.
|
||||||
StopGitspace(ctx context.Context, config types.GitspaceConfig, infra types.Infrastructure) error
|
StopGitspace(ctx context.Context, config types.GitspaceConfig, infra types.Infrastructure) error
|
||||||
|
|
||||||
// StopAndRemoveGitspace stops and removes the gitspace container.
|
// StopAndRemoveGitspace stops and removes the gitspace container.
|
||||||
StopAndRemoveGitspace(ctx context.Context, config types.GitspaceConfig, infra types.Infrastructure) error
|
StopAndRemoveGitspace(
|
||||||
|
ctx context.Context,
|
||||||
|
config types.GitspaceConfig,
|
||||||
|
infra types.Infrastructure,
|
||||||
|
canDeleteUserData bool,
|
||||||
|
) error
|
||||||
|
|
||||||
// Status checks if the infra is reachable and ready to orchestrate containers.
|
// Status checks if the infra is reachable and ready to orchestrate containers.
|
||||||
Status(ctx context.Context, infra types.Infrastructure) error
|
Status(ctx context.Context, infra types.Infrastructure) error
|
||||||
|
@ -28,6 +28,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/harness/gitness/app/gitspace/orchestrator/container/response"
|
||||||
"github.com/harness/gitness/app/gitspace/orchestrator/runarg"
|
"github.com/harness/gitness/app/gitspace/orchestrator/runarg"
|
||||||
"github.com/harness/gitness/app/gitspace/orchestrator/utils"
|
"github.com/harness/gitness/app/gitspace/orchestrator/utils"
|
||||||
gitspaceTypes "github.com/harness/gitness/app/gitspace/types"
|
gitspaceTypes "github.com/harness/gitness/app/gitspace/types"
|
||||||
@ -794,7 +795,7 @@ func GetContainerResponse(
|
|||||||
containerName string,
|
containerName string,
|
||||||
portMappings map[int]*types.PortMapping,
|
portMappings map[int]*types.PortMapping,
|
||||||
repoName string,
|
repoName string,
|
||||||
) (*StartResponse, error) {
|
) (*response.StartResponse, error) {
|
||||||
id, ports, remoteUser, err := GetContainerInfo(ctx, containerName, dockerClient, portMappings)
|
id, ports, remoteUser, err := GetContainerInfo(ctx, containerName, dockerClient, portMappings)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -803,7 +804,7 @@ func GetContainerResponse(
|
|||||||
homeDir := GetUserHomeDir(remoteUser)
|
homeDir := GetUserHomeDir(remoteUser)
|
||||||
codeRepoDir := filepath.Join(homeDir, repoName)
|
codeRepoDir := filepath.Join(homeDir, repoName)
|
||||||
|
|
||||||
return &StartResponse{
|
return &response.StartResponse{
|
||||||
ContainerID: id,
|
ContainerID: id,
|
||||||
ContainerName: containerName,
|
ContainerName: containerName,
|
||||||
PublishedPorts: ports,
|
PublishedPorts: ports,
|
||||||
|
@ -20,7 +20,9 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
events "github.com/harness/gitness/app/events/gitspaceoperations"
|
||||||
"github.com/harness/gitness/app/gitspace/logutil"
|
"github.com/harness/gitness/app/gitspace/logutil"
|
||||||
|
"github.com/harness/gitness/app/gitspace/orchestrator/container/response"
|
||||||
"github.com/harness/gitness/app/gitspace/orchestrator/devcontainer"
|
"github.com/harness/gitness/app/gitspace/orchestrator/devcontainer"
|
||||||
"github.com/harness/gitness/app/gitspace/orchestrator/ide"
|
"github.com/harness/gitness/app/gitspace/orchestrator/ide"
|
||||||
"github.com/harness/gitness/app/gitspace/orchestrator/runarg"
|
"github.com/harness/gitness/app/gitspace/orchestrator/runarg"
|
||||||
@ -29,6 +31,7 @@ import (
|
|||||||
gitspaceTypes "github.com/harness/gitness/app/gitspace/types"
|
gitspaceTypes "github.com/harness/gitness/app/gitspace/types"
|
||||||
"github.com/harness/gitness/infraprovider"
|
"github.com/harness/gitness/infraprovider"
|
||||||
"github.com/harness/gitness/types"
|
"github.com/harness/gitness/types"
|
||||||
|
"github.com/harness/gitness/types/enum"
|
||||||
|
|
||||||
"github.com/docker/docker/api/types/mount"
|
"github.com/docker/docker/api/types/mount"
|
||||||
"github.com/docker/docker/client"
|
"github.com/docker/docker/client"
|
||||||
@ -46,6 +49,7 @@ type EmbeddedDockerOrchestrator struct {
|
|||||||
dockerClientFactory *infraprovider.DockerClientFactory
|
dockerClientFactory *infraprovider.DockerClientFactory
|
||||||
statefulLogger *logutil.StatefulLogger
|
statefulLogger *logutil.StatefulLogger
|
||||||
runArgProvider runarg.Provider
|
runArgProvider runarg.Provider
|
||||||
|
eventReporter *events.Reporter
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step represents a single setup action.
|
// Step represents a single setup action.
|
||||||
@ -87,11 +91,13 @@ func NewEmbeddedDockerOrchestrator(
|
|||||||
dockerClientFactory *infraprovider.DockerClientFactory,
|
dockerClientFactory *infraprovider.DockerClientFactory,
|
||||||
statefulLogger *logutil.StatefulLogger,
|
statefulLogger *logutil.StatefulLogger,
|
||||||
runArgProvider runarg.Provider,
|
runArgProvider runarg.Provider,
|
||||||
) Orchestrator {
|
eventReporter *events.Reporter,
|
||||||
return &EmbeddedDockerOrchestrator{
|
) EmbeddedDockerOrchestrator {
|
||||||
|
return EmbeddedDockerOrchestrator{
|
||||||
dockerClientFactory: dockerClientFactory,
|
dockerClientFactory: dockerClientFactory,
|
||||||
statefulLogger: statefulLogger,
|
statefulLogger: statefulLogger,
|
||||||
runArgProvider: runArgProvider,
|
runArgProvider: runArgProvider,
|
||||||
|
eventReporter: eventReporter,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,20 +112,20 @@ func (e *EmbeddedDockerOrchestrator) CreateAndStartGitspace(
|
|||||||
resolvedRepoDetails scm.ResolvedDetails,
|
resolvedRepoDetails scm.ResolvedDetails,
|
||||||
defaultBaseImage string,
|
defaultBaseImage string,
|
||||||
ideService ide.IDE,
|
ideService ide.IDE,
|
||||||
) (*StartResponse, error) {
|
) error {
|
||||||
containerName := GetGitspaceContainerName(gitspaceConfig)
|
containerName := GetGitspaceContainerName(gitspaceConfig)
|
||||||
logger := log.Ctx(ctx).With().Str(loggingKey, containerName).Logger()
|
logger := log.Ctx(ctx).With().Str(loggingKey, containerName).Logger()
|
||||||
|
|
||||||
// Step 1: Validate access key
|
// Step 1: Validate access key
|
||||||
accessKey, err := e.getAccessKey(gitspaceConfig)
|
accessKey, err := e.getAccessKey(gitspaceConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 2: Get Docker client
|
// Step 2: Get Docker client
|
||||||
dockerClient, err := e.getDockerClient(ctx, infra)
|
dockerClient, err := e.getDockerClient(ctx, infra)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
defer e.closeDockerClient(dockerClient)
|
defer e.closeDockerClient(dockerClient)
|
||||||
|
|
||||||
@ -129,7 +135,7 @@ func (e *EmbeddedDockerOrchestrator) CreateAndStartGitspace(
|
|||||||
// Step 3: Check the current state of the container
|
// Step 3: Check the current state of the container
|
||||||
state, err := e.checkContainerState(ctx, dockerClient, containerName)
|
state, err := e.checkContainerState(ctx, dockerClient, containerName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 4: Handle different container states
|
// Step 4: Handle different container states
|
||||||
@ -146,7 +152,7 @@ func (e *EmbeddedDockerOrchestrator) CreateAndStartGitspace(
|
|||||||
accessKey,
|
accessKey,
|
||||||
ideService,
|
ideService,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
case ContainerStateRemoved:
|
case ContainerStateRemoved:
|
||||||
if err = e.createAndStartNewGitspace(
|
if err = e.createAndStartNewGitspace(
|
||||||
@ -158,18 +164,37 @@ func (e *EmbeddedDockerOrchestrator) CreateAndStartGitspace(
|
|||||||
defaultBaseImage,
|
defaultBaseImage,
|
||||||
ideService,
|
ideService,
|
||||||
imagAuthMap); err != nil {
|
imagAuthMap); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
case ContainerStatePaused, ContainerStateCreated, ContainerStateUnknown, ContainerStateDead:
|
case ContainerStatePaused, ContainerStateCreated, ContainerStateUnknown, ContainerStateDead:
|
||||||
// TODO handle the following states
|
// TODO handle the following states
|
||||||
return nil, fmt.Errorf("gitspace %s is in a unhandled state: %s", containerName, state)
|
return fmt.Errorf("gitspace %s is in a unhandled state: %s", containerName, state)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("gitspace %s is in a bad state: %s", containerName, state)
|
return fmt.Errorf("gitspace %s is in a bad state: %s", containerName, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 5: Retrieve container information and return response
|
// Step 5: Retrieve container information and return response
|
||||||
return GetContainerResponse(ctx, dockerClient, containerName, infra.GitspacePortMappings, resolvedRepoDetails.RepoName)
|
startResponse, err := GetContainerResponse(
|
||||||
|
ctx,
|
||||||
|
dockerClient,
|
||||||
|
containerName,
|
||||||
|
infra.GitspacePortMappings,
|
||||||
|
resolvedRepoDetails.RepoName,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.eventReporter.EmitGitspaceOperationsEvent(
|
||||||
|
ctx,
|
||||||
|
events.GitspaceOperationsEvent,
|
||||||
|
&events.GitspaceOperationsEventPayload{
|
||||||
|
Type: enum.GitspaceOperationsEventStart,
|
||||||
|
Infra: infra,
|
||||||
|
Response: *startResponse,
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// startStoppedGitspace starts the Gitspace container if it was stopped.
|
// startStoppedGitspace starts the Gitspace container if it was stopped.
|
||||||
@ -293,8 +318,16 @@ func (e *EmbeddedDockerOrchestrator) StopGitspace(
|
|||||||
return fmt.Errorf("gitspace %s is in a bad state: %s", containerName, state)
|
return fmt.Errorf("gitspace %s is in a bad state: %s", containerName, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = e.eventReporter.EmitGitspaceOperationsEvent(
|
||||||
|
ctx,
|
||||||
|
events.GitspaceOperationsEvent,
|
||||||
|
&events.GitspaceOperationsEventPayload{
|
||||||
|
Type: enum.GitspaceOperationsEventStop,
|
||||||
|
Infra: infra,
|
||||||
|
},
|
||||||
|
)
|
||||||
logger.Debug().Msg("stopped gitspace")
|
logger.Debug().Msg("stopped gitspace")
|
||||||
return nil
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// stopRunningGitspace handles stopping the container when it is in a running state.
|
// stopRunningGitspace handles stopping the container when it is in a running state.
|
||||||
@ -326,6 +359,7 @@ func (e *EmbeddedDockerOrchestrator) StopAndRemoveGitspace(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
gitspaceConfig types.GitspaceConfig,
|
gitspaceConfig types.GitspaceConfig,
|
||||||
infra types.Infrastructure,
|
infra types.Infrastructure,
|
||||||
|
canDeleteUserData bool,
|
||||||
) error {
|
) error {
|
||||||
containerName := GetGitspaceContainerName(gitspaceConfig)
|
containerName := GetGitspaceContainerName(gitspaceConfig)
|
||||||
logger := log.Ctx(ctx).With().Str(loggingKey, containerName).Logger()
|
logger := log.Ctx(ctx).With().Str(loggingKey, containerName).Logger()
|
||||||
@ -373,8 +407,17 @@ func (e *EmbeddedDockerOrchestrator) StopAndRemoveGitspace(
|
|||||||
return fmt.Errorf("failed to remove gitspace %s: %w", containerName, err)
|
return fmt.Errorf("failed to remove gitspace %s: %w", containerName, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = e.eventReporter.EmitGitspaceOperationsEvent(
|
||||||
|
ctx,
|
||||||
|
events.GitspaceOperationsEvent,
|
||||||
|
&events.GitspaceOperationsEventPayload{
|
||||||
|
Type: enum.GitspaceOperationsEventDelete,
|
||||||
|
Infra: infra,
|
||||||
|
Response: &response.DeleteResponse{CanDeleteUserData: canDeleteUserData},
|
||||||
|
},
|
||||||
|
)
|
||||||
logger.Debug().Msg("removed gitspace")
|
logger.Debug().Msg("removed gitspace")
|
||||||
return nil
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *EmbeddedDockerOrchestrator) StreamLogs(
|
func (e *EmbeddedDockerOrchestrator) StreamLogs(
|
||||||
@ -833,3 +876,7 @@ func getImage(devcontainerConfig types.DevcontainerConfig, defaultBaseImage stri
|
|||||||
}
|
}
|
||||||
return imageName
|
return imageName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *EmbeddedDockerOrchestrator) RetryCreateAndStartGitspaceIfRequired(_ context.Context) {
|
||||||
|
// Nothing to do here as the event will be published from CreateAndStartGitspace itself.
|
||||||
|
}
|
||||||
|
43
app/gitspace/orchestrator/container/orchestrator_factory.go
Normal file
43
app/gitspace/orchestrator/container/orchestrator_factory.go
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// Copyright 2023 Harness, Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package container
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/harness/gitness/types/enum"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Factory interface {
|
||||||
|
GetContainerOrchestrator(providerType enum.InfraProviderType) (Orchestrator, error)
|
||||||
|
}
|
||||||
|
type factory struct {
|
||||||
|
containerOrchestrators map[enum.InfraProviderType]Orchestrator
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFactory(embeddedDockerOrchestrator EmbeddedDockerOrchestrator) Factory {
|
||||||
|
containerOrchestrators := make(map[enum.InfraProviderType]Orchestrator)
|
||||||
|
containerOrchestrators[enum.InfraProviderTypeDocker] = &embeddedDockerOrchestrator
|
||||||
|
return &factory{containerOrchestrators: containerOrchestrators}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *factory) GetContainerOrchestrator(infraProviderType enum.InfraProviderType) (Orchestrator, error) {
|
||||||
|
val, exist := f.containerOrchestrators[infraProviderType]
|
||||||
|
if !exist {
|
||||||
|
return nil, fmt.Errorf("unsupported infra provider type: %s", infraProviderType)
|
||||||
|
}
|
||||||
|
|
||||||
|
return val, nil
|
||||||
|
}
|
19
app/gitspace/orchestrator/container/response/delete.go
Normal file
19
app/gitspace/orchestrator/container/response/delete.go
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// Copyright 2023 Harness, Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package response
|
||||||
|
|
||||||
|
type DeleteResponse struct {
|
||||||
|
CanDeleteUserData bool `json:"can_delete_user_data"`
|
||||||
|
}
|
23
app/gitspace/orchestrator/container/response/start.go
Normal file
23
app/gitspace/orchestrator/container/response/start.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// Copyright 2023 Harness, Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package response
|
||||||
|
|
||||||
|
type StartResponse struct {
|
||||||
|
ContainerID string `json:"container_id"`
|
||||||
|
ContainerName string `json:"container_name"`
|
||||||
|
PublishedPorts map[int]string `json:"published_ports"`
|
||||||
|
AbsoluteRepoPath string `json:"absolute_repo_path"`
|
||||||
|
RemoteUser string `json:"remote_user"`
|
||||||
|
}
|
@ -14,14 +14,6 @@
|
|||||||
|
|
||||||
package container
|
package container
|
||||||
|
|
||||||
type StartResponse struct {
|
|
||||||
ContainerID string
|
|
||||||
ContainerName string
|
|
||||||
PublishedPorts map[int]string
|
|
||||||
AbsoluteRepoPath string
|
|
||||||
RemoteUser string
|
|
||||||
}
|
|
||||||
|
|
||||||
type PostAction string
|
type PostAction string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -18,14 +18,17 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/harness/gitness/app/gitspace/orchestrator/container/response"
|
||||||
"github.com/harness/gitness/app/gitspace/orchestrator/devcontainer"
|
"github.com/harness/gitness/app/gitspace/orchestrator/devcontainer"
|
||||||
gitspaceTypes "github.com/harness/gitness/app/gitspace/types"
|
gitspaceTypes "github.com/harness/gitness/app/gitspace/types"
|
||||||
"github.com/harness/gitness/types"
|
"github.com/harness/gitness/types"
|
||||||
|
|
||||||
dockerTypes "github.com/docker/docker/api/types"
|
dockerTypes "github.com/docker/docker/api/types"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -155,3 +158,32 @@ func ExecuteLifecycleCommands(
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ProcessStartResponse(
|
||||||
|
ctx context.Context,
|
||||||
|
config types.GitspaceConfig,
|
||||||
|
resp io.ReadCloser,
|
||||||
|
) (*response.StartResponse, error) {
|
||||||
|
var err error
|
||||||
|
defer func() {
|
||||||
|
err = resp.Close()
|
||||||
|
if err != nil {
|
||||||
|
log.Ctx(ctx).Warn().Err(err).Msgf(
|
||||||
|
"failed to close response after starting gitspace %s", config.Identifier)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
bodyBytes, _ := io.ReadAll(resp)
|
||||||
|
responseBody := string(bodyBytes)
|
||||||
|
|
||||||
|
log.Debug().Msgf("response from %s %s", config.GitspaceInstance.Identifier, responseBody)
|
||||||
|
|
||||||
|
var startResponse response.StartResponse
|
||||||
|
err = json.Unmarshal(bodyBytes, &startResponse)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error unmarshalling start response for gitspace instance %s: %w",
|
||||||
|
config.GitspaceInstance.Identifier, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &startResponse, nil
|
||||||
|
}
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
package container
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
events "github.com/harness/gitness/app/events/gitspaceoperations"
|
||||||
"github.com/harness/gitness/app/gitspace/logutil"
|
"github.com/harness/gitness/app/gitspace/logutil"
|
||||||
"github.com/harness/gitness/app/gitspace/orchestrator/runarg"
|
"github.com/harness/gitness/app/gitspace/orchestrator/runarg"
|
||||||
"github.com/harness/gitness/infraprovider"
|
"github.com/harness/gitness/infraprovider"
|
||||||
@ -24,16 +25,25 @@ import (
|
|||||||
|
|
||||||
var WireSet = wire.NewSet(
|
var WireSet = wire.NewSet(
|
||||||
ProvideEmbeddedDockerOrchestrator,
|
ProvideEmbeddedDockerOrchestrator,
|
||||||
|
ProvideContainerOrchestratorFactory,
|
||||||
)
|
)
|
||||||
|
|
||||||
func ProvideEmbeddedDockerOrchestrator(
|
func ProvideEmbeddedDockerOrchestrator(
|
||||||
dockerClientFactory *infraprovider.DockerClientFactory,
|
dockerClientFactory *infraprovider.DockerClientFactory,
|
||||||
statefulLogger *logutil.StatefulLogger,
|
statefulLogger *logutil.StatefulLogger,
|
||||||
runArgProvdier runarg.Provider,
|
runArgProvider runarg.Provider,
|
||||||
) Orchestrator {
|
eventReporter *events.Reporter,
|
||||||
|
) EmbeddedDockerOrchestrator {
|
||||||
return NewEmbeddedDockerOrchestrator(
|
return NewEmbeddedDockerOrchestrator(
|
||||||
dockerClientFactory,
|
dockerClientFactory,
|
||||||
statefulLogger,
|
statefulLogger,
|
||||||
runArgProvdier,
|
runArgProvider,
|
||||||
|
eventReporter,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ProvideContainerOrchestratorFactory(
|
||||||
|
embeddedDockerOrchestrator EmbeddedDockerOrchestrator,
|
||||||
|
) Factory {
|
||||||
|
return NewFactory(embeddedDockerOrchestrator)
|
||||||
|
}
|
||||||
|
@ -20,11 +20,9 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/harness/gitness/app/gitspace/orchestrator/container"
|
"github.com/harness/gitness/app/gitspace/orchestrator/container/response"
|
||||||
"github.com/harness/gitness/app/gitspace/orchestrator/ide"
|
"github.com/harness/gitness/app/gitspace/orchestrator/ide"
|
||||||
"github.com/harness/gitness/app/gitspace/secret"
|
"github.com/harness/gitness/app/gitspace/orchestrator/utils"
|
||||||
secretenum "github.com/harness/gitness/app/gitspace/secret/enum"
|
|
||||||
"github.com/harness/gitness/app/paths"
|
|
||||||
"github.com/harness/gitness/types"
|
"github.com/harness/gitness/types"
|
||||||
"github.com/harness/gitness/types/enum"
|
"github.com/harness/gitness/types/enum"
|
||||||
|
|
||||||
@ -39,39 +37,16 @@ func (o Orchestrator) ResumeStartGitspace(
|
|||||||
provisionedInfra types.Infrastructure,
|
provisionedInfra types.Infrastructure,
|
||||||
) (types.GitspaceInstance, *types.GitspaceError) {
|
) (types.GitspaceInstance, *types.GitspaceError) {
|
||||||
gitspaceInstance := gitspaceConfig.GitspaceInstance
|
gitspaceInstance := gitspaceConfig.GitspaceInstance
|
||||||
gitspaceInstance.State = enum.GitspaceInstanceStateError
|
gitspaceInstance.State = enum.GitspaceInstanceStateStarting
|
||||||
|
secretValue, err := utils.ResolveSecret(ctx, o.secretResolverFactory, gitspaceConfig)
|
||||||
secretResolver, err := o.getSecretResolver(gitspaceInstance.AccessType)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Err(err).Msgf("could not find secret resolver for type: %s", gitspaceInstance.AccessType)
|
|
||||||
return *gitspaceInstance, &types.GitspaceError{
|
return *gitspaceInstance, &types.GitspaceError{
|
||||||
Error: err,
|
Error: fmt.Errorf("cannot resolve secret for ID %s: %w",
|
||||||
|
gitspaceConfig.InfraProviderResource.UID, err),
|
||||||
ErrorMessage: ptr.String(err.Error()),
|
ErrorMessage: ptr.String(err.Error()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rootSpaceID, _, err := paths.DisectRoot(gitspaceConfig.SpacePath)
|
gitspaceInstance.AccessKey = secretValue
|
||||||
if err != nil {
|
|
||||||
log.Err(err).Msgf("unable to find root space id from space path: %s", gitspaceConfig.SpacePath)
|
|
||||||
return *gitspaceInstance, &types.GitspaceError{
|
|
||||||
Error: err,
|
|
||||||
ErrorMessage: ptr.String(err.Error()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
resolvedSecret, err := secretResolver.Resolve(ctx, secret.ResolutionContext{
|
|
||||||
UserIdentifier: gitspaceConfig.GitspaceUser.Identifier,
|
|
||||||
GitspaceIdentifier: gitspaceConfig.Identifier,
|
|
||||||
SecretRef: *gitspaceInstance.AccessKeyRef,
|
|
||||||
SpaceIdentifier: rootSpaceID,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
log.Err(err).Msgf("could not resolve secret type: %s, ref: %s",
|
|
||||||
gitspaceInstance.AccessType, *gitspaceInstance.AccessKeyRef)
|
|
||||||
return *gitspaceInstance, &types.GitspaceError{
|
|
||||||
Error: err,
|
|
||||||
ErrorMessage: ptr.String(err.Error()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
gitspaceInstance.AccessKey = &resolvedSecret.SecretValue
|
|
||||||
|
|
||||||
ideSvc, err := o.ideFactory.GetIDE(gitspaceConfig.IDE)
|
ideSvc, err := o.ideFactory.GetIDE(gitspaceConfig.IDE)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -118,13 +93,13 @@ func (o Orchestrator) ResumeStartGitspace(
|
|||||||
}
|
}
|
||||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentConnectStart)
|
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentConnectStart)
|
||||||
|
|
||||||
err = o.containerOrchestrator.Status(ctx, provisionedInfra)
|
containerOrchestrator, err := o.containerOrchestratorFactory.GetContainerOrchestrator(provisionedInfra.ProviderType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentConnectFailed)
|
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentConnectFailed)
|
||||||
agentUnreachableErr := fmt.Errorf("couldn't call the agent health API: %w", err)
|
|
||||||
return *gitspaceInstance, &types.GitspaceError{
|
return *gitspaceInstance, &types.GitspaceError{
|
||||||
Error: agentUnreachableErr,
|
Error: fmt.Errorf("failed to get the container orchestrator for infra provider type %s: %w",
|
||||||
ErrorMessage: ptr.String(agentUnreachableErr.Error()),
|
provisionedInfra.ProviderType, err),
|
||||||
|
ErrorMessage: ptr.String(err.Error()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,7 +128,7 @@ func (o Orchestrator) ResumeStartGitspace(
|
|||||||
// NOTE: Currently we use a static identifier as the Gitspace user.
|
// NOTE: Currently we use a static identifier as the Gitspace user.
|
||||||
gitspaceConfig.GitspaceUser.Identifier = harnessUser
|
gitspaceConfig.GitspaceUser.Identifier = harnessUser
|
||||||
|
|
||||||
startResponse, err := o.containerOrchestrator.CreateAndStartGitspace(
|
err = containerOrchestrator.CreateAndStartGitspace(
|
||||||
ctx, gitspaceConfig, provisionedInfra, *scmResolvedDetails, o.config.DefaultBaseImage, ideSvc)
|
ctx, gitspaceConfig, provisionedInfra, *scmResolvedDetails, o.config.DefaultBaseImage, ideSvc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentGitspaceCreationFailed)
|
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentGitspaceCreationFailed)
|
||||||
@ -164,7 +139,26 @@ func (o Orchestrator) ResumeStartGitspace(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return *gitspaceConfig.GitspaceInstance, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FinishResumeStartGitspace needs to be called from the API Handler.
|
||||||
|
func (o Orchestrator) FinishResumeStartGitspace(
|
||||||
|
ctx context.Context,
|
||||||
|
gitspaceConfig types.GitspaceConfig,
|
||||||
|
provisionedInfra types.Infrastructure,
|
||||||
|
startResponse *response.StartResponse,
|
||||||
|
) (types.GitspaceInstance, *types.GitspaceError) {
|
||||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentGitspaceCreationCompleted)
|
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentGitspaceCreationCompleted)
|
||||||
|
gitspaceInstance := gitspaceConfig.GitspaceInstance
|
||||||
|
|
||||||
|
ideSvc, err := o.ideFactory.GetIDE(gitspaceConfig.IDE)
|
||||||
|
if err != nil {
|
||||||
|
return *gitspaceInstance, &types.GitspaceError{
|
||||||
|
Error: err,
|
||||||
|
ErrorMessage: ptr.String(err.Error()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ideURLString := generateIDEURL(provisionedInfra, ideSvc, startResponse)
|
ideURLString := generateIDEURL(provisionedInfra, ideSvc, startResponse)
|
||||||
gitspaceInstance.URL = &ideURLString
|
gitspaceInstance.URL = &ideURLString
|
||||||
@ -183,7 +177,7 @@ func (o Orchestrator) ResumeStartGitspace(
|
|||||||
func generateIDEURL(
|
func generateIDEURL(
|
||||||
provisionedInfra types.Infrastructure,
|
provisionedInfra types.Infrastructure,
|
||||||
ideSvc ide.IDE,
|
ideSvc ide.IDE,
|
||||||
startResponse *container.StartResponse,
|
startResponse *response.StartResponse,
|
||||||
) string {
|
) string {
|
||||||
idePort := ideSvc.Port()
|
idePort := ideSvc.Port()
|
||||||
var forwardedPort string
|
var forwardedPort string
|
||||||
@ -202,19 +196,6 @@ func generateIDEURL(
|
|||||||
return ideSvc.GenerateURL(startResponse.AbsoluteRepoPath, host, forwardedPort, startResponse.RemoteUser)
|
return ideSvc.GenerateURL(startResponse.AbsoluteRepoPath, host, forwardedPort, startResponse.RemoteUser)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o Orchestrator) getSecretResolver(accessType enum.GitspaceAccessType) (secret.Resolver, error) {
|
|
||||||
secretType := secretenum.PasswordSecretType
|
|
||||||
switch accessType {
|
|
||||||
case enum.GitspaceAccessTypeUserCredentials:
|
|
||||||
secretType = secretenum.PasswordSecretType
|
|
||||||
case enum.GitspaceAccessTypeJWTToken:
|
|
||||||
secretType = secretenum.JWTSecretType
|
|
||||||
case enum.GitspaceAccessTypeSSHKey:
|
|
||||||
secretType = secretenum.SSHSecretType
|
|
||||||
}
|
|
||||||
return o.secretResolverFactory.GetSecretResolver(secretType)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResumeStopGitspace saves the deprovisioned infra details.
|
// ResumeStopGitspace saves the deprovisioned infra details.
|
||||||
func (o Orchestrator) ResumeStopGitspace(
|
func (o Orchestrator) ResumeStopGitspace(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
|
@ -26,6 +26,7 @@ import (
|
|||||||
"github.com/harness/gitness/app/gitspace/platformconnector"
|
"github.com/harness/gitness/app/gitspace/platformconnector"
|
||||||
"github.com/harness/gitness/app/gitspace/scm"
|
"github.com/harness/gitness/app/gitspace/scm"
|
||||||
"github.com/harness/gitness/app/gitspace/secret"
|
"github.com/harness/gitness/app/gitspace/secret"
|
||||||
|
"github.com/harness/gitness/app/store"
|
||||||
"github.com/harness/gitness/types"
|
"github.com/harness/gitness/types"
|
||||||
"github.com/harness/gitness/types/enum"
|
"github.com/harness/gitness/types/enum"
|
||||||
|
|
||||||
@ -44,32 +45,35 @@ type Orchestrator struct {
|
|||||||
scm *scm.SCM
|
scm *scm.SCM
|
||||||
platformConnector platformconnector.PlatformConnector
|
platformConnector platformconnector.PlatformConnector
|
||||||
infraProvisioner infrastructure.InfraProvisioner
|
infraProvisioner infrastructure.InfraProvisioner
|
||||||
containerOrchestrator container.Orchestrator
|
containerOrchestratorFactory container.Factory
|
||||||
eventReporter *events.Reporter
|
eventReporter *events.Reporter
|
||||||
config *Config
|
config *Config
|
||||||
ideFactory ide.Factory
|
ideFactory ide.Factory
|
||||||
secretResolverFactory *secret.ResolverFactory
|
secretResolverFactory *secret.ResolverFactory
|
||||||
|
gitspaceInstanceStore store.GitspaceInstanceStore
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewOrchestrator(
|
func NewOrchestrator(
|
||||||
scm *scm.SCM,
|
scm *scm.SCM,
|
||||||
platformConnector platformconnector.PlatformConnector,
|
platformConnector platformconnector.PlatformConnector,
|
||||||
infraProvisioner infrastructure.InfraProvisioner,
|
infraProvisioner infrastructure.InfraProvisioner,
|
||||||
containerOrchestrator container.Orchestrator,
|
containerOrchestratorFactory container.Factory,
|
||||||
eventReporter *events.Reporter,
|
eventReporter *events.Reporter,
|
||||||
config *Config,
|
config *Config,
|
||||||
ideFactory ide.Factory,
|
ideFactory ide.Factory,
|
||||||
secretResolverFactory *secret.ResolverFactory,
|
secretResolverFactory *secret.ResolverFactory,
|
||||||
|
gitspaceInstanceStore store.GitspaceInstanceStore,
|
||||||
) Orchestrator {
|
) Orchestrator {
|
||||||
return Orchestrator{
|
return Orchestrator{
|
||||||
scm: scm,
|
scm: scm,
|
||||||
platformConnector: platformConnector,
|
platformConnector: platformConnector,
|
||||||
infraProvisioner: infraProvisioner,
|
infraProvisioner: infraProvisioner,
|
||||||
containerOrchestrator: containerOrchestrator,
|
containerOrchestratorFactory: containerOrchestratorFactory,
|
||||||
eventReporter: eventReporter,
|
eventReporter: eventReporter,
|
||||||
config: config,
|
config: config,
|
||||||
ideFactory: ideFactory,
|
ideFactory: ideFactory,
|
||||||
secretResolverFactory: secretResolverFactory,
|
secretResolverFactory: secretResolverFactory,
|
||||||
|
gitspaceInstanceStore: gitspaceInstanceStore,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,19 +169,6 @@ func (o Orchestrator) TriggerStopGitspace(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraStopStart)
|
|
||||||
|
|
||||||
err = o.infraProvisioner.TriggerInfraEvent(ctx, enum.InfraEventStop, gitspaceConfig, infra)
|
|
||||||
if err != nil {
|
|
||||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraStopFailed)
|
|
||||||
infraStopErr := fmt.Errorf("cannot trigger stop infrastructure with ID %s: %w",
|
|
||||||
gitspaceConfig.InfraProviderResource.UID, err)
|
|
||||||
return &types.GitspaceError{
|
|
||||||
Error: infraStopErr,
|
|
||||||
ErrorMessage: ptr.String(infraStopErr.Error()), // TODO: Fetch explicit error msg
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,11 +179,10 @@ func (o Orchestrator) stopGitspaceContainer(
|
|||||||
) error {
|
) error {
|
||||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentConnectStart)
|
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentConnectStart)
|
||||||
|
|
||||||
err := o.containerOrchestrator.Status(ctx, infra)
|
containerOrchestrator, err := o.containerOrchestratorFactory.GetContainerOrchestrator(infra.ProviderType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentConnectFailed)
|
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentConnectFailed)
|
||||||
|
return fmt.Errorf("couldn't get the container orchestrator: %w", err)
|
||||||
return fmt.Errorf("couldn't call the agent health API: %w", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentConnectCompleted)
|
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentConnectCompleted)
|
||||||
@ -202,14 +192,35 @@ func (o Orchestrator) stopGitspaceContainer(
|
|||||||
// NOTE: Currently we use a static identifier as the Gitspace user.
|
// NOTE: Currently we use a static identifier as the Gitspace user.
|
||||||
gitspaceConfig.GitspaceUser.Identifier = harnessUser
|
gitspaceConfig.GitspaceUser.Identifier = harnessUser
|
||||||
|
|
||||||
err = o.containerOrchestrator.StopGitspace(ctx, gitspaceConfig, infra)
|
err = containerOrchestrator.StopGitspace(ctx, gitspaceConfig, infra)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentGitspaceStopFailed)
|
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentGitspaceStopFailed)
|
||||||
|
|
||||||
return fmt.Errorf("error stopping the Gitspace container: %w", err)
|
return fmt.Errorf("error stopping the Gitspace container: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Orchestrator) FinishStopGitspaceContainer(
|
||||||
|
ctx context.Context,
|
||||||
|
gitspaceConfig types.GitspaceConfig,
|
||||||
|
infra types.Infrastructure,
|
||||||
|
) *types.GitspaceError {
|
||||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentGitspaceStopCompleted)
|
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentGitspaceStopCompleted)
|
||||||
|
|
||||||
|
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraStopStart)
|
||||||
|
|
||||||
|
err := o.infraProvisioner.TriggerInfraEvent(ctx, enum.InfraEventStop, gitspaceConfig, &infra)
|
||||||
|
if err != nil {
|
||||||
|
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraStopFailed)
|
||||||
|
infraStopErr := fmt.Errorf("cannot trigger stop infrastructure with ID %s: %w",
|
||||||
|
gitspaceConfig.InfraProviderResource.UID, err)
|
||||||
|
return &types.GitspaceError{
|
||||||
|
Error: infraStopErr,
|
||||||
|
ErrorMessage: ptr.String(infraStopErr.Error()), // TODO: Fetch explicit error msg
|
||||||
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,14 +228,14 @@ func (o Orchestrator) stopAndRemoveGitspaceContainer(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
gitspaceConfig types.GitspaceConfig,
|
gitspaceConfig types.GitspaceConfig,
|
||||||
infra types.Infrastructure,
|
infra types.Infrastructure,
|
||||||
|
canDeleteUserData bool,
|
||||||
) error {
|
) error {
|
||||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentConnectStart)
|
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentConnectStart)
|
||||||
|
|
||||||
err := o.containerOrchestrator.Status(ctx, infra)
|
containerOrchestrator, err := o.containerOrchestratorFactory.GetContainerOrchestrator(infra.ProviderType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentConnectFailed)
|
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentConnectFailed)
|
||||||
|
return fmt.Errorf("couldn't get the container orchestrator: %w", err)
|
||||||
return fmt.Errorf("couldn't call the agent health API: %w", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentConnectCompleted)
|
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentConnectCompleted)
|
||||||
@ -234,12 +245,43 @@ func (o Orchestrator) stopAndRemoveGitspaceContainer(
|
|||||||
// NOTE: Currently we use a static identifier as the Gitspace user.
|
// NOTE: Currently we use a static identifier as the Gitspace user.
|
||||||
gitspaceConfig.GitspaceUser.Identifier = harnessUser
|
gitspaceConfig.GitspaceUser.Identifier = harnessUser
|
||||||
|
|
||||||
err = o.containerOrchestrator.StopAndRemoveGitspace(ctx, gitspaceConfig, infra)
|
err = containerOrchestrator.StopAndRemoveGitspace(ctx, gitspaceConfig, infra, canDeleteUserData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentGitspaceDeletionFailed)
|
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentGitspaceDeletionFailed)
|
||||||
log.Err(err).Msgf("error stopping the Gitspace container")
|
log.Err(err).Msgf("error stopping the Gitspace container")
|
||||||
} else {
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Orchestrator) FinishStopAndRemoveGitspaceContainer(
|
||||||
|
ctx context.Context,
|
||||||
|
gitspaceConfig types.GitspaceConfig,
|
||||||
|
infra types.Infrastructure,
|
||||||
|
canDeleteUserData bool,
|
||||||
|
) *types.GitspaceError {
|
||||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentGitspaceDeletionCompleted)
|
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentGitspaceDeletionCompleted)
|
||||||
|
if canDeleteUserData {
|
||||||
|
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraDeprovisioningStart)
|
||||||
|
} else {
|
||||||
|
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraResetStart)
|
||||||
|
}
|
||||||
|
|
||||||
|
opts := infrastructure.InfraEventOpts{CanDeleteUserData: canDeleteUserData}
|
||||||
|
err := o.infraProvisioner.TriggerInfraEventWithOpts(ctx, enum.InfraEventDeprovision, gitspaceConfig, &infra, opts)
|
||||||
|
if err != nil {
|
||||||
|
if canDeleteUserData {
|
||||||
|
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraDeprovisioningFailed)
|
||||||
|
} else {
|
||||||
|
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraResetFailed)
|
||||||
|
}
|
||||||
|
return &types.GitspaceError{
|
||||||
|
Error: fmt.Errorf(
|
||||||
|
"cannot trigger deprovision infrastructure with ID %s: %w",
|
||||||
|
gitspaceConfig.InfraProviderResource.UID,
|
||||||
|
err,
|
||||||
|
),
|
||||||
|
ErrorMessage: ptr.String(err.Error()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -302,19 +344,51 @@ func (o Orchestrator) TriggerDeleteGitspace(
|
|||||||
"unable to find provisioned infra while triggering delete for gitspace instance %s: %w",
|
"unable to find provisioned infra while triggering delete for gitspace instance %s: %w",
|
||||||
gitspaceConfig.GitspaceInstance.Identifier, err)
|
gitspaceConfig.GitspaceInstance.Identifier, err)
|
||||||
}
|
}
|
||||||
if infra.ProviderType == enum.InfraProviderTypeDocker {
|
if err = o.stopAndRemoveGitspaceContainer(ctx, gitspaceConfig, *infra, canDeleteUserData); err != nil {
|
||||||
if err = o.stopAndRemoveGitspaceContainer(ctx, gitspaceConfig, *infra); err != nil {
|
log.Warn().Msgf("error stopping and removing gitspace container: %v", err)
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if canDeleteUserData {
|
|
||||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraDeprovisioningStart)
|
|
||||||
} else {
|
|
||||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraResetStart)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
opts := infrastructure.InfraEventOpts{CanDeleteUserData: canDeleteUserData}
|
// TODO: Add a job for cleanup of infra if stop fails
|
||||||
err = o.infraProvisioner.TriggerInfraEventWithOpts(ctx, enum.InfraEventDeprovision, gitspaceConfig, infra, opts)
|
log.Warn().Msgf(
|
||||||
|
"Checking and force deleting the infra if required for gitspace instance %s",
|
||||||
|
gitspaceConfig.GitspaceInstance.Identifier,
|
||||||
|
)
|
||||||
|
ticker := time.NewTicker(60 * time.Second)
|
||||||
|
timeout := time.After(15 * time.Minute)
|
||||||
|
defer ticker.Stop()
|
||||||
|
ch := make(chan error)
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case msg := <-ch:
|
||||||
|
if msg == nil {
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
case <-ticker.C:
|
||||||
|
instance, err := o.gitspaceInstanceStore.Find(
|
||||||
|
ctx,
|
||||||
|
gitspaceConfig.GitspaceInstance.ID,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf(
|
||||||
|
"failed to find gitspace instance %s: %w",
|
||||||
|
gitspaceConfig.GitspaceInstance.Identifier,
|
||||||
|
err,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if instance.State == enum.GitspaceInstanceStateDeleted ||
|
||||||
|
instance.State == enum.GitspaceInstanceStateCleaned {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
case <-timeout:
|
||||||
|
opts := infrastructure.InfraEventOpts{CanDeleteUserData: true}
|
||||||
|
err := o.infraProvisioner.TriggerInfraEventWithOpts(
|
||||||
|
ctx,
|
||||||
|
enum.InfraEventDeprovision,
|
||||||
|
gitspaceConfig,
|
||||||
|
infra,
|
||||||
|
opts,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if canDeleteUserData {
|
if canDeleteUserData {
|
||||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraDeprovisioningFailed)
|
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraDeprovisioningFailed)
|
||||||
@ -322,11 +396,15 @@ func (o Orchestrator) TriggerDeleteGitspace(
|
|||||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraResetFailed)
|
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraResetFailed)
|
||||||
}
|
}
|
||||||
return fmt.Errorf(
|
return fmt.Errorf(
|
||||||
"cannot trigger deprovision infrastructure with ID %s: %w", gitspaceConfig.InfraProviderResource.UID, err)
|
"cannot trigger deprovision infrastructure with gitspace identifier %s: %w",
|
||||||
|
gitspaceConfig.GitspaceInstance.Identifier,
|
||||||
|
err,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (o Orchestrator) emitGitspaceEvent(
|
func (o Orchestrator) emitGitspaceEvent(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
@ -379,9 +457,14 @@ func (o Orchestrator) GetGitspaceLogs(ctx context.Context, gitspaceConfig types.
|
|||||||
gitspaceConfig.GitspaceInstance.Identifier, err)
|
gitspaceConfig.GitspaceInstance.Identifier, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
containerOrchestrator, err := o.containerOrchestratorFactory.GetContainerOrchestrator(infra.ProviderType)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("couldn't get the container orchestrator: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: Currently we use a static identifier as the Gitspace user.
|
// NOTE: Currently we use a static identifier as the Gitspace user.
|
||||||
gitspaceConfig.GitspaceUser.Identifier = harnessUser
|
gitspaceConfig.GitspaceUser.Identifier = harnessUser
|
||||||
logs, err := o.containerOrchestrator.StreamLogs(ctx, gitspaceConfig, *infra)
|
logs, err := containerOrchestrator.StreamLogs(ctx, gitspaceConfig, *infra)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("error while fetching logs from container orchestrator: %w", err)
|
return "", fmt.Errorf("error while fetching logs from container orchestrator: %w", err)
|
||||||
}
|
}
|
||||||
@ -394,12 +477,7 @@ func (o Orchestrator) getProvisionedInfra(
|
|||||||
gitspaceConfig types.GitspaceConfig,
|
gitspaceConfig types.GitspaceConfig,
|
||||||
expectedStatus []enum.InfraStatus,
|
expectedStatus []enum.InfraStatus,
|
||||||
) (*types.Infrastructure, error) {
|
) (*types.Infrastructure, error) {
|
||||||
requiredGitspacePorts, err := o.getPortsRequiredForGitspace(gitspaceConfig, types.DevcontainerConfig{})
|
infra, err := o.infraProvisioner.Find(ctx, gitspaceConfig)
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("cannot get the ports required for gitspace: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
infra, err := o.infraProvisioner.Find(ctx, gitspaceConfig, requiredGitspacePorts)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot find the provisioned infra: %w", err)
|
return nil, fmt.Errorf("cannot find the provisioned infra: %w", err)
|
||||||
}
|
}
|
||||||
|
67
app/gitspace/orchestrator/utils/secret.go
Normal file
67
app/gitspace/orchestrator/utils/secret.go
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
// Copyright 2023 Harness, Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/harness/gitness/app/gitspace/secret"
|
||||||
|
"github.com/harness/gitness/app/gitspace/secret/enum"
|
||||||
|
"github.com/harness/gitness/app/paths"
|
||||||
|
"github.com/harness/gitness/types"
|
||||||
|
gitnessenum "github.com/harness/gitness/types/enum"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ResolveSecret(ctx context.Context, secretResolverFactory *secret.ResolverFactory, config types.GitspaceConfig) (*string, error) {
|
||||||
|
rootSpaceID, _, err := paths.DisectRoot(config.SpacePath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to find root space id from space path: %s", config.SpacePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
secretType := GetSecretType(config.GitspaceInstance.AccessType)
|
||||||
|
secretResolver, err := secretResolverFactory.GetSecretResolver(secretType)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("could not find secret resolver for type: %s", config.GitspaceInstance.AccessType)
|
||||||
|
}
|
||||||
|
|
||||||
|
resolvedSecret, err := secretResolver.Resolve(ctx, secret.ResolutionContext{
|
||||||
|
UserIdentifier: config.GitspaceUser.Identifier,
|
||||||
|
GitspaceIdentifier: config.Identifier,
|
||||||
|
SecretRef: *config.GitspaceInstance.AccessKeyRef,
|
||||||
|
SpaceIdentifier: rootSpaceID,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf(
|
||||||
|
"could not resolve secret type: %s, ref: %s",
|
||||||
|
config.GitspaceInstance.AccessType,
|
||||||
|
*config.GitspaceInstance.AccessKeyRef,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return &resolvedSecret.SecretValue, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetSecretType(accessType gitnessenum.GitspaceAccessType) enum.SecretType {
|
||||||
|
secretType := enum.PasswordSecretType
|
||||||
|
switch accessType {
|
||||||
|
case gitnessenum.GitspaceAccessTypeUserCredentials:
|
||||||
|
secretType = enum.PasswordSecretType
|
||||||
|
case gitnessenum.GitspaceAccessTypeJWTToken:
|
||||||
|
secretType = enum.JWTSecretType
|
||||||
|
case gitnessenum.GitspaceAccessTypeSSHKey:
|
||||||
|
secretType = enum.SSHSecretType
|
||||||
|
}
|
||||||
|
return secretType
|
||||||
|
}
|
@ -22,6 +22,7 @@ import (
|
|||||||
"github.com/harness/gitness/app/gitspace/platformconnector"
|
"github.com/harness/gitness/app/gitspace/platformconnector"
|
||||||
"github.com/harness/gitness/app/gitspace/scm"
|
"github.com/harness/gitness/app/gitspace/scm"
|
||||||
"github.com/harness/gitness/app/gitspace/secret"
|
"github.com/harness/gitness/app/gitspace/secret"
|
||||||
|
"github.com/harness/gitness/app/store"
|
||||||
|
|
||||||
"github.com/google/wire"
|
"github.com/google/wire"
|
||||||
)
|
)
|
||||||
@ -35,20 +36,22 @@ func ProvideOrchestrator(
|
|||||||
scm *scm.SCM,
|
scm *scm.SCM,
|
||||||
platformConnector platformconnector.PlatformConnector,
|
platformConnector platformconnector.PlatformConnector,
|
||||||
infraProvisioner infrastructure.InfraProvisioner,
|
infraProvisioner infrastructure.InfraProvisioner,
|
||||||
containerOrchestrator container.Orchestrator,
|
containerOrchestratorFactor container.Factory,
|
||||||
reporter *events.Reporter,
|
reporter *events.Reporter,
|
||||||
config *Config,
|
config *Config,
|
||||||
ideFactory ide.Factory,
|
ideFactory ide.Factory,
|
||||||
secretResolverFactory *secret.ResolverFactory,
|
secretResolverFactory *secret.ResolverFactory,
|
||||||
|
gitspaceInstanceStore store.GitspaceInstanceStore,
|
||||||
) Orchestrator {
|
) Orchestrator {
|
||||||
return NewOrchestrator(
|
return NewOrchestrator(
|
||||||
scm,
|
scm,
|
||||||
platformConnector,
|
platformConnector,
|
||||||
infraProvisioner,
|
infraProvisioner,
|
||||||
containerOrchestrator,
|
containerOrchestratorFactor,
|
||||||
reporter,
|
reporter,
|
||||||
config,
|
config,
|
||||||
ideFactory,
|
ideFactory,
|
||||||
secretResolverFactory,
|
secretResolverFactory,
|
||||||
|
gitspaceInstanceStore,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -57,6 +57,7 @@ func (s *Service) handleGitspaceInfraResumeEvent(
|
|||||||
}
|
}
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
|
// TODO: Update would not be needed for provision, stop and deprovision. Needs to be removed later.
|
||||||
updateErr := s.gitspaceSvc.UpdateInstance(ctxWithTimedOut, instance)
|
updateErr := s.gitspaceSvc.UpdateInstance(ctxWithTimedOut, instance)
|
||||||
if updateErr != nil {
|
if updateErr != nil {
|
||||||
log.Err(updateErr).Msgf("failed to update gitspace instance")
|
log.Err(updateErr).Msgf("failed to update gitspace instance")
|
||||||
|
153
app/services/gitspaceoperationsevent/handler.go
Normal file
153
app/services/gitspaceoperationsevent/handler.go
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
// Copyright 2023 Harness, Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package gitspaceoperationsevent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
gitspaceEvents "github.com/harness/gitness/app/events/gitspace"
|
||||||
|
gitspaceOperationsEvents "github.com/harness/gitness/app/events/gitspaceoperations"
|
||||||
|
"github.com/harness/gitness/app/gitspace/orchestrator/container/response"
|
||||||
|
"github.com/harness/gitness/events"
|
||||||
|
"github.com/harness/gitness/types"
|
||||||
|
"github.com/harness/gitness/types/enum"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *Service) handleGitspaceOperationsEvent(
|
||||||
|
ctx context.Context,
|
||||||
|
event *events.Event[*gitspaceOperationsEvents.GitspaceOperationsEventPayload],
|
||||||
|
) error {
|
||||||
|
logr := log.With().Str("event", string(event.Payload.Type)).Logger()
|
||||||
|
logr.Debug().Msg("Received gitspace operations event")
|
||||||
|
|
||||||
|
payload := event.Payload
|
||||||
|
ctxWithTimedOut, cancel := context.WithTimeout(ctx, time.Duration(s.config.TimeoutInMins)*time.Minute)
|
||||||
|
defer cancel()
|
||||||
|
config, fetchErr := s.getConfig(
|
||||||
|
ctxWithTimedOut, payload.Infra.SpacePath, payload.Infra.GitspaceConfigIdentifier)
|
||||||
|
if fetchErr != nil {
|
||||||
|
return fetchErr
|
||||||
|
}
|
||||||
|
|
||||||
|
instance := config.GitspaceInstance
|
||||||
|
if payload.Infra.GitspaceInstanceIdentifier != "" {
|
||||||
|
gitspaceInstance, err := s.gitspaceSvc.FindInstanceByIdentifier(
|
||||||
|
ctxWithTimedOut,
|
||||||
|
payload.Infra.GitspaceInstanceIdentifier,
|
||||||
|
payload.Infra.SpacePath,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to fetch gitspace instance: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
instance = gitspaceInstance
|
||||||
|
config.GitspaceInstance = instance
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
updateErr := s.gitspaceSvc.UpdateInstance(ctxWithTimedOut, instance)
|
||||||
|
if updateErr != nil {
|
||||||
|
log.Err(updateErr).Msgf("failed to update gitspace instance")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
var err error
|
||||||
|
|
||||||
|
switch payload.Type {
|
||||||
|
case enum.GitspaceOperationsEventStart:
|
||||||
|
if config.GitspaceInstance.Identifier != payload.Infra.GitspaceInstanceIdentifier {
|
||||||
|
return fmt.Errorf("gitspace instance is not latest, stopping provisioning")
|
||||||
|
}
|
||||||
|
|
||||||
|
startResponse, ok := payload.Response.(*response.StartResponse)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("failed to cast start response")
|
||||||
|
}
|
||||||
|
updatedInstance, handleResumeStartErr := s.orchestrator.FinishResumeStartGitspace(
|
||||||
|
ctxWithTimedOut,
|
||||||
|
*config,
|
||||||
|
payload.Infra,
|
||||||
|
startResponse,
|
||||||
|
)
|
||||||
|
if handleResumeStartErr != nil {
|
||||||
|
s.emitGitspaceConfigEvent(ctxWithTimedOut, config, enum.GitspaceEventTypeGitspaceActionStartFailed)
|
||||||
|
updatedInstance.ErrorMessage = handleResumeStartErr.ErrorMessage
|
||||||
|
err = fmt.Errorf("failed to finish resume start gitspace: %w", handleResumeStartErr.Error)
|
||||||
|
}
|
||||||
|
instance = &updatedInstance
|
||||||
|
case enum.GitspaceOperationsEventStop:
|
||||||
|
finishStopErr := s.orchestrator.FinishStopGitspaceContainer(ctxWithTimedOut, *config, payload.Infra)
|
||||||
|
if finishStopErr != nil {
|
||||||
|
s.emitGitspaceConfigEvent(ctxWithTimedOut, config, enum.GitspaceEventTypeGitspaceActionStopFailed)
|
||||||
|
instance.ErrorMessage = finishStopErr.ErrorMessage
|
||||||
|
err = fmt.Errorf("failed to finish trigger start gitspace: %w", finishStopErr.Error)
|
||||||
|
}
|
||||||
|
case enum.GitspaceOperationsEventDelete:
|
||||||
|
deleteResponse, ok := payload.Response.(*response.DeleteResponse)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("failed to cast delete response")
|
||||||
|
}
|
||||||
|
finishStopAndRemoveErr := s.orchestrator.FinishStopAndRemoveGitspaceContainer(
|
||||||
|
ctxWithTimedOut,
|
||||||
|
*config,
|
||||||
|
payload.Infra,
|
||||||
|
deleteResponse.CanDeleteUserData,
|
||||||
|
)
|
||||||
|
if finishStopAndRemoveErr != nil {
|
||||||
|
s.emitGitspaceConfigEvent(ctxWithTimedOut, config, enum.GitspaceEventTypeGitspaceActionStopFailed)
|
||||||
|
instance.ErrorMessage = finishStopAndRemoveErr.ErrorMessage
|
||||||
|
err = fmt.Errorf("failed to finish trigger start gitspace: %w", finishStopAndRemoveErr.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unknown event type: %s", event.Payload.Type)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Err(err).Msgf("error while handling gitspace operations event")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) getConfig(
|
||||||
|
ctx context.Context,
|
||||||
|
spaceRef string,
|
||||||
|
identifier string,
|
||||||
|
) (*types.GitspaceConfig, error) {
|
||||||
|
config, err := s.gitspaceSvc.FindWithLatestInstance(ctx, spaceRef, identifier)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf(
|
||||||
|
"failed to find gitspace config during infra event handling, identifier %s: %w", identifier, err)
|
||||||
|
}
|
||||||
|
return config, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) emitGitspaceConfigEvent(ctx context.Context,
|
||||||
|
config *types.GitspaceConfig,
|
||||||
|
eventType enum.GitspaceEventType,
|
||||||
|
) {
|
||||||
|
s.eventReporter.EmitGitspaceEvent(ctx, gitspaceEvents.GitspaceEvent, &gitspaceEvents.GitspaceEventPayload{
|
||||||
|
QueryKey: config.Identifier,
|
||||||
|
EntityID: config.ID,
|
||||||
|
EntityType: enum.GitspaceEntityTypeGitspaceConfig,
|
||||||
|
EventType: eventType,
|
||||||
|
Timestamp: time.Now().UnixNano(),
|
||||||
|
})
|
||||||
|
}
|
77
app/services/gitspaceoperationsevent/service.go
Normal file
77
app/services/gitspaceoperationsevent/service.go
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
// Copyright 2023 Harness, Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package gitspaceoperationsevent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
gitspaceevents "github.com/harness/gitness/app/events/gitspace"
|
||||||
|
gitspaceoperationsevents "github.com/harness/gitness/app/events/gitspaceoperations"
|
||||||
|
"github.com/harness/gitness/app/gitspace/orchestrator"
|
||||||
|
"github.com/harness/gitness/app/services/gitspace"
|
||||||
|
"github.com/harness/gitness/app/services/gitspaceevent"
|
||||||
|
"github.com/harness/gitness/events"
|
||||||
|
"github.com/harness/gitness/stream"
|
||||||
|
)
|
||||||
|
|
||||||
|
const groupGitspaceOperationsEvents = "gitness:gitspaceoperations"
|
||||||
|
|
||||||
|
type Service struct {
|
||||||
|
config *gitspaceevent.Config
|
||||||
|
orchestrator orchestrator.Orchestrator
|
||||||
|
gitspaceSvc *gitspace.Service
|
||||||
|
eventReporter *gitspaceevents.Reporter
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewService(
|
||||||
|
ctx context.Context,
|
||||||
|
config *gitspaceevent.Config,
|
||||||
|
gitspaceOperationsEventReaderFactory *events.ReaderFactory[*gitspaceoperationsevents.Reader],
|
||||||
|
orchestrator orchestrator.Orchestrator,
|
||||||
|
gitspaceSvc *gitspace.Service,
|
||||||
|
eventReporter *gitspaceevents.Reporter,
|
||||||
|
) (*Service, error) {
|
||||||
|
if err := config.Sanitize(); err != nil {
|
||||||
|
return nil, fmt.Errorf("provided gitspace operations event service config is invalid: %w", err)
|
||||||
|
}
|
||||||
|
service := &Service{
|
||||||
|
config: config,
|
||||||
|
orchestrator: orchestrator,
|
||||||
|
gitspaceSvc: gitspaceSvc,
|
||||||
|
eventReporter: eventReporter,
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := gitspaceOperationsEventReaderFactory.Launch(ctx, groupGitspaceOperationsEvents, config.EventReaderName,
|
||||||
|
func(r *gitspaceoperationsevents.Reader) error {
|
||||||
|
var idleTimeout = time.Duration(config.TimeoutInMins) * time.Minute
|
||||||
|
r.Configure(
|
||||||
|
stream.WithConcurrency(config.Concurrency),
|
||||||
|
stream.WithHandlerOptions(
|
||||||
|
stream.WithIdleTimeout(idleTimeout),
|
||||||
|
stream.WithMaxRetries(config.MaxRetries),
|
||||||
|
))
|
||||||
|
|
||||||
|
_ = r.RegisterGitspaceOperationsEvent(service.handleGitspaceOperationsEvent)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to launch gitspace operations event reader: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return service, nil
|
||||||
|
}
|
51
app/services/gitspaceoperationsevent/wire.go
Normal file
51
app/services/gitspaceoperationsevent/wire.go
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
// Copyright 2023 Harness, Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package gitspaceoperationsevent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
gitspaceevents "github.com/harness/gitness/app/events/gitspace"
|
||||||
|
gitspaceoperationsevents "github.com/harness/gitness/app/events/gitspaceoperations"
|
||||||
|
"github.com/harness/gitness/app/gitspace/orchestrator"
|
||||||
|
"github.com/harness/gitness/app/services/gitspace"
|
||||||
|
"github.com/harness/gitness/app/services/gitspaceevent"
|
||||||
|
"github.com/harness/gitness/events"
|
||||||
|
|
||||||
|
"github.com/google/wire"
|
||||||
|
)
|
||||||
|
|
||||||
|
// WireSet provides a wire set for this package.
|
||||||
|
var WireSet = wire.NewSet(
|
||||||
|
ProvideService,
|
||||||
|
)
|
||||||
|
|
||||||
|
func ProvideService(
|
||||||
|
ctx context.Context,
|
||||||
|
config *gitspaceevent.Config,
|
||||||
|
gitspaceInfraEventReaderFactory *events.ReaderFactory[*gitspaceoperationsevents.Reader],
|
||||||
|
orchestrator orchestrator.Orchestrator,
|
||||||
|
gitspaceSvc *gitspace.Service,
|
||||||
|
eventReporter *gitspaceevents.Reporter,
|
||||||
|
) (*Service, error) {
|
||||||
|
return NewService(
|
||||||
|
ctx,
|
||||||
|
config,
|
||||||
|
gitspaceInfraEventReaderFactory,
|
||||||
|
orchestrator,
|
||||||
|
gitspaceSvc,
|
||||||
|
eventReporter,
|
||||||
|
)
|
||||||
|
}
|
@ -17,6 +17,7 @@ package gitspaceservice
|
|||||||
import (
|
import (
|
||||||
"github.com/harness/gitness/app/services/gitspace"
|
"github.com/harness/gitness/app/services/gitspace"
|
||||||
"github.com/harness/gitness/app/services/gitspaceinfraevent"
|
"github.com/harness/gitness/app/services/gitspaceinfraevent"
|
||||||
|
"github.com/harness/gitness/app/services/gitspaceoperationsevent"
|
||||||
"github.com/harness/gitness/app/services/infraprovider"
|
"github.com/harness/gitness/app/services/infraprovider"
|
||||||
|
|
||||||
"github.com/google/wire"
|
"github.com/google/wire"
|
||||||
@ -26,4 +27,5 @@ var WireSet = wire.NewSet(
|
|||||||
gitspace.WireSet,
|
gitspace.WireSet,
|
||||||
gitspaceinfraevent.WireSet,
|
gitspaceinfraevent.WireSet,
|
||||||
infraprovider.WireSet,
|
infraprovider.WireSet,
|
||||||
|
gitspaceoperationsevent.WireSet,
|
||||||
)
|
)
|
||||||
|
@ -19,6 +19,7 @@ import (
|
|||||||
"github.com/harness/gitness/app/services/gitspace"
|
"github.com/harness/gitness/app/services/gitspace"
|
||||||
"github.com/harness/gitness/app/services/gitspaceevent"
|
"github.com/harness/gitness/app/services/gitspaceevent"
|
||||||
"github.com/harness/gitness/app/services/gitspaceinfraevent"
|
"github.com/harness/gitness/app/services/gitspaceinfraevent"
|
||||||
|
"github.com/harness/gitness/app/services/gitspaceoperationsevent"
|
||||||
"github.com/harness/gitness/app/services/infraprovider"
|
"github.com/harness/gitness/app/services/infraprovider"
|
||||||
"github.com/harness/gitness/app/services/instrument"
|
"github.com/harness/gitness/app/services/instrument"
|
||||||
"github.com/harness/gitness/app/services/keywordsearch"
|
"github.com/harness/gitness/app/services/keywordsearch"
|
||||||
@ -61,6 +62,7 @@ type GitspaceServices struct {
|
|||||||
infraProvider *infraprovider.Service
|
infraProvider *infraprovider.Service
|
||||||
gitspace *gitspace.Service
|
gitspace *gitspace.Service
|
||||||
gitspaceInfraEventSvc *gitspaceinfraevent.Service
|
gitspaceInfraEventSvc *gitspaceinfraevent.Service
|
||||||
|
gitspaceOperationsEventSvc *gitspaceoperationsevent.Service
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProvideGitspaceServices(
|
func ProvideGitspaceServices(
|
||||||
@ -68,12 +70,14 @@ func ProvideGitspaceServices(
|
|||||||
infraProviderSvc *infraprovider.Service,
|
infraProviderSvc *infraprovider.Service,
|
||||||
gitspaceSvc *gitspace.Service,
|
gitspaceSvc *gitspace.Service,
|
||||||
gitspaceInfraEventSvc *gitspaceinfraevent.Service,
|
gitspaceInfraEventSvc *gitspaceinfraevent.Service,
|
||||||
|
gitspaceOperationsEventSvc *gitspaceoperationsevent.Service,
|
||||||
) *GitspaceServices {
|
) *GitspaceServices {
|
||||||
return &GitspaceServices{
|
return &GitspaceServices{
|
||||||
GitspaceEvent: gitspaceEventSvc,
|
GitspaceEvent: gitspaceEventSvc,
|
||||||
infraProvider: infraProviderSvc,
|
infraProvider: infraProviderSvc,
|
||||||
gitspace: gitspaceSvc,
|
gitspace: gitspaceSvc,
|
||||||
gitspaceInfraEventSvc: gitspaceInfraEventSvc,
|
gitspaceInfraEventSvc: gitspaceInfraEventSvc,
|
||||||
|
gitspaceOperationsEventSvc: gitspaceOperationsEventSvc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -733,6 +733,7 @@ type (
|
|||||||
Find(ctx context.Context, id int64) (*types.GitspaceInstance, error)
|
Find(ctx context.Context, id int64) (*types.GitspaceInstance, error)
|
||||||
|
|
||||||
// FindByIdentifier returns a gitspace instance given a gitspace instance identifier from the datastore.
|
// FindByIdentifier returns a gitspace instance given a gitspace instance identifier from the datastore.
|
||||||
|
// TODO: Fix this. It needs to use space ID as well.
|
||||||
FindByIdentifier(ctx context.Context, identifier string) (*types.GitspaceInstance, error)
|
FindByIdentifier(ctx context.Context, identifier string) (*types.GitspaceInstance, error)
|
||||||
|
|
||||||
// FindLatestByGitspaceConfigID returns the latest gitspace instance given a gitspace config ID from the datastore.
|
// FindLatestByGitspaceConfigID returns the latest gitspace instance given a gitspace config ID from the datastore.
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE delegate_provision_details DROP COLUMN dpdeta_task_details;
|
@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE delegate_provision_details ADD COLUMN dpdeta_task_details jsonb;
|
@ -0,0 +1,21 @@
|
|||||||
|
DROP TABLE delegate_provision_details;
|
||||||
|
|
||||||
|
CREATE TABLE delegate_provision_details
|
||||||
|
(
|
||||||
|
dpdeta_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
dpdeta_task_id TEXT NOT NULL,
|
||||||
|
dpdeta_action_type TEXT NOT NULL,
|
||||||
|
dpdeta_gitspace_instance_id INTEGER NOT NULL,
|
||||||
|
dpdeta_space_id INTEGER NOT NULL,
|
||||||
|
dpdeta_agent_port INTEGER NOT NULL,
|
||||||
|
dpdeta_created BIGINT NOT NULL,
|
||||||
|
dpdeta_updated BIGINT NOT NULL,
|
||||||
|
CONSTRAINT fk_dpdeta_gitspace_instance_id FOREIGN KEY (dpdeta_gitspace_instance_id)
|
||||||
|
REFERENCES gitspaces (gits_id) MATCH SIMPLE
|
||||||
|
ON UPDATE NO ACTION
|
||||||
|
CONSTRAINT fk_dpdeta_space_id FOREIGN KEY (dpdeta_space_id)
|
||||||
|
REFERENCES spaces (space_id) MATCH SIMPLE
|
||||||
|
ON UPDATE NO ACTION
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE UNIQUE INDEX delegate_provision_details_task_id_space_id ON delegate_provision_details (dpdeta_task_id, dpdeta_space_id);
|
@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE delegate_provision_details ADD COLUMN dpdeta_task_details TEXT;
|
@ -56,6 +56,7 @@ import (
|
|||||||
gitevents "github.com/harness/gitness/app/events/git"
|
gitevents "github.com/harness/gitness/app/events/git"
|
||||||
gitspaceevents "github.com/harness/gitness/app/events/gitspace"
|
gitspaceevents "github.com/harness/gitness/app/events/gitspace"
|
||||||
gitspaceinfraevents "github.com/harness/gitness/app/events/gitspaceinfra"
|
gitspaceinfraevents "github.com/harness/gitness/app/events/gitspaceinfra"
|
||||||
|
gitspaceoperationsevents "github.com/harness/gitness/app/events/gitspaceoperations"
|
||||||
pipelineevents "github.com/harness/gitness/app/events/pipeline"
|
pipelineevents "github.com/harness/gitness/app/events/pipeline"
|
||||||
pullreqevents "github.com/harness/gitness/app/events/pullreq"
|
pullreqevents "github.com/harness/gitness/app/events/pullreq"
|
||||||
repoevents "github.com/harness/gitness/app/events/repo"
|
repoevents "github.com/harness/gitness/app/events/repo"
|
||||||
@ -270,6 +271,7 @@ func initSystem(ctx context.Context, config *types.Config) (*cliserver.System, e
|
|||||||
ide.WireSet,
|
ide.WireSet,
|
||||||
gitspaceinfraevents.WireSet,
|
gitspaceinfraevents.WireSet,
|
||||||
gitspaceservice.WireSet,
|
gitspaceservice.WireSet,
|
||||||
|
gitspaceoperationsevents.WireSet,
|
||||||
cliserver.ProvideGitspaceInfraProvisionerConfig,
|
cliserver.ProvideGitspaceInfraProvisionerConfig,
|
||||||
cliserver.ProvideIDEVSCodeConfig,
|
cliserver.ProvideIDEVSCodeConfig,
|
||||||
cliserver.ProvideIDEJetBrainsConfig,
|
cliserver.ProvideIDEJetBrainsConfig,
|
||||||
|
@ -42,11 +42,12 @@ import (
|
|||||||
"github.com/harness/gitness/app/auth/authz"
|
"github.com/harness/gitness/app/auth/authz"
|
||||||
"github.com/harness/gitness/app/bootstrap"
|
"github.com/harness/gitness/app/bootstrap"
|
||||||
"github.com/harness/gitness/app/connector"
|
"github.com/harness/gitness/app/connector"
|
||||||
events7 "github.com/harness/gitness/app/events/git"
|
events8 "github.com/harness/gitness/app/events/git"
|
||||||
events3 "github.com/harness/gitness/app/events/gitspace"
|
events3 "github.com/harness/gitness/app/events/gitspace"
|
||||||
events4 "github.com/harness/gitness/app/events/gitspaceinfra"
|
events4 "github.com/harness/gitness/app/events/gitspaceinfra"
|
||||||
events5 "github.com/harness/gitness/app/events/pipeline"
|
events5 "github.com/harness/gitness/app/events/gitspaceoperations"
|
||||||
events6 "github.com/harness/gitness/app/events/pullreq"
|
events6 "github.com/harness/gitness/app/events/pipeline"
|
||||||
|
events7 "github.com/harness/gitness/app/events/pullreq"
|
||||||
events2 "github.com/harness/gitness/app/events/repo"
|
events2 "github.com/harness/gitness/app/events/repo"
|
||||||
"github.com/harness/gitness/app/gitspace/infrastructure"
|
"github.com/harness/gitness/app/gitspace/infrastructure"
|
||||||
"github.com/harness/gitness/app/gitspace/logutil"
|
"github.com/harness/gitness/app/gitspace/logutil"
|
||||||
@ -76,6 +77,7 @@ import (
|
|||||||
"github.com/harness/gitness/app/services/gitspace"
|
"github.com/harness/gitness/app/services/gitspace"
|
||||||
"github.com/harness/gitness/app/services/gitspaceevent"
|
"github.com/harness/gitness/app/services/gitspaceevent"
|
||||||
"github.com/harness/gitness/app/services/gitspaceinfraevent"
|
"github.com/harness/gitness/app/services/gitspaceinfraevent"
|
||||||
|
"github.com/harness/gitness/app/services/gitspaceoperationsevent"
|
||||||
"github.com/harness/gitness/app/services/importer"
|
"github.com/harness/gitness/app/services/importer"
|
||||||
infraprovider2 "github.com/harness/gitness/app/services/infraprovider"
|
infraprovider2 "github.com/harness/gitness/app/services/infraprovider"
|
||||||
"github.com/harness/gitness/app/services/instrument"
|
"github.com/harness/gitness/app/services/instrument"
|
||||||
@ -121,7 +123,7 @@ import (
|
|||||||
"github.com/harness/gitness/pubsub"
|
"github.com/harness/gitness/pubsub"
|
||||||
api2 "github.com/harness/gitness/registry/app/api"
|
api2 "github.com/harness/gitness/registry/app/api"
|
||||||
"github.com/harness/gitness/registry/app/api/router"
|
"github.com/harness/gitness/registry/app/api/router"
|
||||||
events8 "github.com/harness/gitness/registry/app/events"
|
events9 "github.com/harness/gitness/registry/app/events"
|
||||||
"github.com/harness/gitness/registry/app/pkg"
|
"github.com/harness/gitness/registry/app/pkg"
|
||||||
"github.com/harness/gitness/registry/app/pkg/docker"
|
"github.com/harness/gitness/registry/app/pkg/docker"
|
||||||
"github.com/harness/gitness/registry/app/pkg/filemanager"
|
"github.com/harness/gitness/registry/app/pkg/filemanager"
|
||||||
@ -332,7 +334,12 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
containerOrchestrator := container.ProvideEmbeddedDockerOrchestrator(dockerClientFactory, statefulLogger, runargProvider)
|
reporter3, err := events5.ProvideReporter(eventsSystem)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
embeddedDockerOrchestrator := container.ProvideEmbeddedDockerOrchestrator(dockerClientFactory, statefulLogger, runargProvider, reporter3)
|
||||||
|
containerFactory := container.ProvideContainerOrchestratorFactory(embeddedDockerOrchestrator)
|
||||||
orchestratorConfig := server.ProvideGitspaceOrchestratorConfig(config)
|
orchestratorConfig := server.ProvideGitspaceOrchestratorConfig(config)
|
||||||
vsCodeConfig := server.ProvideIDEVSCodeConfig(config)
|
vsCodeConfig := server.ProvideIDEVSCodeConfig(config)
|
||||||
vsCode := ide.ProvideVSCodeService(vsCodeConfig)
|
vsCode := ide.ProvideVSCodeService(vsCodeConfig)
|
||||||
@ -343,15 +350,15 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
|
|||||||
ideFactory := ide.ProvideIDEFactory(vsCode, vsCodeWeb, v)
|
ideFactory := ide.ProvideIDEFactory(vsCode, vsCodeWeb, v)
|
||||||
passwordResolver := secret.ProvidePasswordResolver()
|
passwordResolver := secret.ProvidePasswordResolver()
|
||||||
resolverFactory := secret.ProvideResolverFactory(passwordResolver)
|
resolverFactory := secret.ProvideResolverFactory(passwordResolver)
|
||||||
orchestratorOrchestrator := orchestrator.ProvideOrchestrator(scmSCM, platformConnector, infraProvisioner, containerOrchestrator, eventsReporter, orchestratorConfig, ideFactory, resolverFactory)
|
orchestratorOrchestrator := orchestrator.ProvideOrchestrator(scmSCM, platformConnector, infraProvisioner, containerFactory, eventsReporter, orchestratorConfig, ideFactory, resolverFactory, gitspaceInstanceStore)
|
||||||
gitspaceService := gitspace.ProvideGitspace(transactor, gitspaceConfigStore, gitspaceInstanceStore, eventsReporter, gitspaceEventStore, spaceFinder, infraproviderService, orchestratorOrchestrator, scmSCM, config)
|
gitspaceService := gitspace.ProvideGitspace(transactor, gitspaceConfigStore, gitspaceInstanceStore, eventsReporter, gitspaceEventStore, spaceFinder, infraproviderService, orchestratorOrchestrator, scmSCM, config)
|
||||||
usageMetricStore := database.ProvideUsageMetricStore(db)
|
usageMetricStore := database.ProvideUsageMetricStore(db)
|
||||||
spaceController := space.ProvideController(config, transactor, provider, streamer, spaceIdentifier, authorizer, spacePathStore, pipelineStore, secretStore, connectorStore, templateStore, spaceStore, repoStore, principalStore, repoController, membershipStore, listService, spaceFinder, repository, exporterRepository, resourceLimiter, publicaccessService, auditService, gitspaceService, labelService, instrumentService, executionStore, rulesService, usageMetricStore, repoIdentifier)
|
spaceController := space.ProvideController(config, transactor, provider, streamer, spaceIdentifier, authorizer, spacePathStore, pipelineStore, secretStore, connectorStore, templateStore, spaceStore, repoStore, principalStore, repoController, membershipStore, listService, spaceFinder, repository, exporterRepository, resourceLimiter, publicaccessService, auditService, gitspaceService, labelService, instrumentService, executionStore, rulesService, usageMetricStore, repoIdentifier)
|
||||||
reporter3, err := events5.ProvideReporter(eventsSystem)
|
reporter4, err := events6.ProvideReporter(eventsSystem)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
pipelineController := pipeline.ProvideController(triggerStore, authorizer, pipelineStore, reporter3, repoFinder)
|
pipelineController := pipeline.ProvideController(triggerStore, authorizer, pipelineStore, reporter4, repoFinder)
|
||||||
secretController := secret2.ProvideController(encrypter, secretStore, authorizer, spaceFinder)
|
secretController := secret2.ProvideController(encrypter, secretStore, authorizer, spaceFinder)
|
||||||
triggerController := trigger.ProvideController(authorizer, triggerStore, pipelineStore, repoFinder)
|
triggerController := trigger.ProvideController(authorizer, triggerStore, pipelineStore, repoFinder)
|
||||||
scmService := connector.ProvideSCMConnectorHandler(secretStore)
|
scmService := connector.ProvideSCMConnectorHandler(secretStore)
|
||||||
@ -365,25 +372,25 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
|
|||||||
pullReqReviewerStore := database.ProvidePullReqReviewerStore(db, principalInfoCache)
|
pullReqReviewerStore := database.ProvidePullReqReviewerStore(db, principalInfoCache)
|
||||||
userGroupReviewersStore := database.ProvideUserGroupReviewerStore(db, principalInfoCache, userGroupStore)
|
userGroupReviewersStore := database.ProvideUserGroupReviewerStore(db, principalInfoCache, userGroupStore)
|
||||||
pullReqFileViewStore := database.ProvidePullReqFileViewStore(db)
|
pullReqFileViewStore := database.ProvidePullReqFileViewStore(db)
|
||||||
reporter4, err := events6.ProvideReporter(eventsSystem)
|
reporter5, err := events7.ProvideReporter(eventsSystem)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
migrator := codecomments.ProvideMigrator(gitInterface)
|
migrator := codecomments.ProvideMigrator(gitInterface)
|
||||||
readerFactory, err := events7.ProvideReaderFactory(eventsSystem)
|
readerFactory, err := events8.ProvideReaderFactory(eventsSystem)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
eventsReaderFactory, err := events6.ProvideReaderFactory(eventsSystem)
|
eventsReaderFactory, err := events7.ProvideReaderFactory(eventsSystem)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
pullreqService, err := pullreq.ProvideService(ctx, config, readerFactory, eventsReaderFactory, reporter4, gitInterface, repoFinder, repoStore, pullReqStore, pullReqActivityStore, principalInfoCache, codeCommentView, migrator, pullReqFileViewStore, pubSub, provider, streamer)
|
pullreqService, err := pullreq.ProvideService(ctx, config, readerFactory, eventsReaderFactory, reporter5, gitInterface, repoFinder, repoStore, pullReqStore, pullReqActivityStore, principalInfoCache, codeCommentView, migrator, pullReqFileViewStore, pubSub, provider, streamer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
pullReq := migrate.ProvidePullReqImporter(provider, gitInterface, principalStore, spaceStore, repoStore, pullReqStore, pullReqActivityStore, labelStore, labelValueStore, pullReqLabelAssignmentStore, repoFinder, transactor, mutexManager)
|
pullReq := migrate.ProvidePullReqImporter(provider, gitInterface, principalStore, spaceStore, repoStore, pullReqStore, pullReqActivityStore, labelStore, labelValueStore, pullReqLabelAssignmentStore, repoFinder, transactor, mutexManager)
|
||||||
pullreqController := pullreq2.ProvideController(transactor, provider, authorizer, auditService, pullReqStore, pullReqActivityStore, codeCommentView, pullReqReviewStore, pullReqReviewerStore, repoStore, principalStore, userGroupStore, userGroupReviewersStore, principalInfoCache, pullReqFileViewStore, membershipStore, checkStore, gitInterface, repoFinder, reporter4, migrator, pullreqService, listService, protectionManager, streamer, codeownersService, lockerLocker, pullReq, labelService, instrumentService, searchService)
|
pullreqController := pullreq2.ProvideController(transactor, provider, authorizer, auditService, pullReqStore, pullReqActivityStore, codeCommentView, pullReqReviewStore, pullReqReviewerStore, repoStore, principalStore, userGroupStore, userGroupReviewersStore, principalInfoCache, pullReqFileViewStore, membershipStore, checkStore, gitInterface, repoFinder, reporter5, migrator, pullreqService, listService, protectionManager, streamer, codeownersService, lockerLocker, pullReq, labelService, instrumentService, searchService)
|
||||||
webhookConfig := server.ProvideWebhookConfig(config)
|
webhookConfig := server.ProvideWebhookConfig(config)
|
||||||
webhookStore := database.ProvideWebhookStore(db)
|
webhookStore := database.ProvideWebhookStore(db)
|
||||||
webhookExecutionStore := database.ProvideWebhookExecutionStore(db)
|
webhookExecutionStore := database.ProvideWebhookExecutionStore(db)
|
||||||
@ -395,7 +402,7 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
|
|||||||
}
|
}
|
||||||
preprocessor := webhook2.ProvidePreprocessor()
|
preprocessor := webhook2.ProvidePreprocessor()
|
||||||
webhookController := webhook2.ProvideController(authorizer, spaceFinder, repoFinder, webhookService, encrypter, preprocessor)
|
webhookController := webhook2.ProvideController(authorizer, spaceFinder, repoFinder, webhookService, encrypter, preprocessor)
|
||||||
reporter5, err := events7.ProvideReporter(eventsSystem)
|
reporter6, err := events8.ProvideReporter(eventsSystem)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -412,7 +419,7 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
lfsObjectStore := database.ProvideLFSObjectStore(db)
|
lfsObjectStore := database.ProvideLFSObjectStore(db)
|
||||||
githookController := githook.ProvideController(authorizer, principalStore, repoStore, repoFinder, reporter5, reporter, gitInterface, pullReqStore, provider, protectionManager, clientFactory, resourceLimiter, settingsService, preReceiveExtender, updateExtender, postReceiveExtender, streamer, lfsObjectStore)
|
githookController := githook.ProvideController(authorizer, principalStore, repoStore, repoFinder, reporter6, reporter, gitInterface, pullReqStore, provider, protectionManager, clientFactory, resourceLimiter, settingsService, preReceiveExtender, updateExtender, postReceiveExtender, streamer, lfsObjectStore)
|
||||||
serviceaccountController := serviceaccount.NewController(principalUID, authorizer, principalStore, spaceStore, repoStore, tokenStore)
|
serviceaccountController := serviceaccount.NewController(principalUID, authorizer, principalStore, spaceStore, repoStore, tokenStore)
|
||||||
principalController := principal.ProvideController(principalStore, authorizer)
|
principalController := principal.ProvideController(principalStore, authorizer)
|
||||||
usergroupController := usergroup2.ProvideController(userGroupStore, spaceStore, authorizer, searchService)
|
usergroupController := usergroup2.ProvideController(userGroupStore, spaceStore, authorizer, searchService)
|
||||||
@ -457,11 +464,11 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
|
|||||||
layerRepository := database2.ProvideLayerDao(db, mediaTypesRepository)
|
layerRepository := database2.ProvideLayerDao(db, mediaTypesRepository)
|
||||||
eventReporter := docker.ProvideReporter()
|
eventReporter := docker.ProvideReporter()
|
||||||
ociImageIndexMappingRepository := database2.ProvideOCIImageIndexMappingDao(db)
|
ociImageIndexMappingRepository := database2.ProvideOCIImageIndexMappingDao(db)
|
||||||
reporter6, err := events8.ProvideArtifactReporter(eventsSystem)
|
reporter7, err := events9.ProvideArtifactReporter(eventsSystem)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
manifestService := docker.ManifestServiceProvider(registryRepository, manifestRepository, blobRepository, mediaTypesRepository, manifestReferenceRepository, tagRepository, imageRepository, artifactRepository, layerRepository, gcService, transactor, eventReporter, spaceFinder, ociImageIndexMappingRepository, reporter6, provider)
|
manifestService := docker.ManifestServiceProvider(registryRepository, manifestRepository, blobRepository, mediaTypesRepository, manifestReferenceRepository, tagRepository, imageRepository, artifactRepository, layerRepository, gcService, transactor, eventReporter, spaceFinder, ociImageIndexMappingRepository, reporter7, provider)
|
||||||
registryBlobRepository := database2.ProvideRegistryBlobDao(db)
|
registryBlobRepository := database2.ProvideRegistryBlobDao(db)
|
||||||
bandwidthStatRepository := database2.ProvideBandwidthStatDao(db)
|
bandwidthStatRepository := database2.ProvideBandwidthStatDao(db)
|
||||||
downloadStatRepository := database2.ProvideDownloadStatDao(db)
|
downloadStatRepository := database2.ProvideDownloadStatDao(db)
|
||||||
@ -481,7 +488,7 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
|
|||||||
cleanupPolicyRepository := database2.ProvideCleanupPolicyDao(db, transactor)
|
cleanupPolicyRepository := database2.ProvideCleanupPolicyDao(db, transactor)
|
||||||
webhooksRepository := database2.ProvideWebhookDao(db)
|
webhooksRepository := database2.ProvideWebhookDao(db)
|
||||||
webhooksExecutionRepository := database2.ProvideWebhookExecutionDao(db)
|
webhooksExecutionRepository := database2.ProvideWebhookExecutionDao(db)
|
||||||
readerFactory2, err := events8.ProvideReaderFactory(eventsSystem)
|
readerFactory2, err := events9.ProvideReaderFactory(eventsSystem)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -513,7 +520,7 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
|
|||||||
serverServer := server2.ProvideServer(config, routerRouter)
|
serverServer := server2.ProvideServer(config, routerRouter)
|
||||||
publickeyService := publickey.ProvidePublicKey(publicKeyStore, principalInfoCache)
|
publickeyService := publickey.ProvidePublicKey(publicKeyStore, principalInfoCache)
|
||||||
sshServer := ssh.ProvideServer(config, publickeyService, repoController, lfsController)
|
sshServer := ssh.ProvideServer(config, publickeyService, repoController, lfsController)
|
||||||
executionManager := manager.ProvideExecutionManager(config, executionStore, pipelineStore, provider, streamer, fileService, converterService, logStore, logStream, checkStore, repoStore, schedulerScheduler, secretStore, stageStore, stepStore, principalStore, publicaccessService, reporter3)
|
executionManager := manager.ProvideExecutionManager(config, executionStore, pipelineStore, provider, streamer, fileService, converterService, logStore, logStream, checkStore, repoStore, schedulerScheduler, secretStore, stageStore, stepStore, principalStore, publicaccessService, reporter4)
|
||||||
client := manager.ProvideExecutionClient(executionManager, provider, config)
|
client := manager.ProvideExecutionClient(executionManager, provider, config)
|
||||||
resolverManager := resolver.ProvideResolver(config, pluginStore, templateStore, executionStore, repoStore)
|
resolverManager := resolver.ProvideResolver(config, pluginStore, templateStore, executionStore, repoStore)
|
||||||
runtimeRunner, err := runner.ProvideExecutionRunner(config, client, resolverManager)
|
runtimeRunner, err := runner.ProvideExecutionRunner(config, client, resolverManager)
|
||||||
@ -576,7 +583,15 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
gitspaceServices := services.ProvideGitspaceServices(gitspaceeventService, infraproviderService, gitspaceService, gitspaceinfraeventService)
|
readerFactory6, err := events5.ProvideReaderFactory(eventsSystem)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
gitspaceoperationseventService, err := gitspaceoperationsevent.ProvideService(ctx, gitspaceeventConfig, readerFactory6, orchestratorOrchestrator, gitspaceService, eventsReporter)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
gitspaceServices := services.ProvideGitspaceServices(gitspaceeventService, infraproviderService, gitspaceService, gitspaceinfraeventService, gitspaceoperationseventService)
|
||||||
consumer, err := instrument.ProvideGitConsumer(ctx, config, readerFactory, repoStore, principalInfoCache, instrumentService)
|
consumer, err := instrument.ProvideGitConsumer(ctx, config, readerFactory, repoStore, principalInfoCache, instrumentService)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -20,6 +20,8 @@ import (
|
|||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/harness/gitness/app/gitspace/orchestrator/container/response"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GenericReporter represents an event reporter that supports sending typesafe messages
|
// GenericReporter represents an event reporter that supports sending typesafe messages
|
||||||
@ -46,6 +48,8 @@ func ReporterSendEvent[T interface{}](reporter *GenericReporter, ctx context.Con
|
|||||||
|
|
||||||
buff := &bytes.Buffer{}
|
buff := &bytes.Buffer{}
|
||||||
encoder := gob.NewEncoder(buff)
|
encoder := gob.NewEncoder(buff)
|
||||||
|
gob.Register((*response.StartResponse)(nil))
|
||||||
|
gob.Register((*response.DeleteResponse)(nil))
|
||||||
|
|
||||||
if err := encoder.Encode(&event); err != nil {
|
if err := encoder.Encode(&event); err != nil {
|
||||||
return "", fmt.Errorf("failed to encode payload: %w", err)
|
return "", fmt.Errorf("failed to encode payload: %w", err)
|
||||||
|
@ -59,7 +59,6 @@ func (d DockerProvider) Provision(
|
|||||||
_ int,
|
_ int,
|
||||||
requiredGitspacePorts []types.GitspacePort,
|
requiredGitspacePorts []types.GitspacePort,
|
||||||
inputParameters []types.InfraProviderParameter,
|
inputParameters []types.InfraProviderParameter,
|
||||||
_ map[string]any,
|
|
||||||
) error {
|
) error {
|
||||||
dockerClient, err := d.dockerClientFactory.NewDockerClient(ctx, types.Infrastructure{
|
dockerClient, err := d.dockerClientFactory.NewDockerClient(ctx, types.Infrastructure{
|
||||||
ProviderType: enum.InfraProviderTypeDocker,
|
ProviderType: enum.InfraProviderTypeDocker,
|
||||||
@ -125,11 +124,7 @@ func (d DockerProvider) Find(
|
|||||||
spaceID int64,
|
spaceID int64,
|
||||||
spacePath string,
|
spacePath string,
|
||||||
gitspaceConfigIdentifier string,
|
gitspaceConfigIdentifier string,
|
||||||
_ string,
|
|
||||||
_ int,
|
|
||||||
_ []types.GitspacePort,
|
|
||||||
inputParameters []types.InfraProviderParameter,
|
inputParameters []types.InfraProviderParameter,
|
||||||
_ map[string]any,
|
|
||||||
) (*types.Infrastructure, error) {
|
) (*types.Infrastructure, error) {
|
||||||
dockerClient, err := d.dockerClientFactory.NewDockerClient(ctx, types.Infrastructure{
|
dockerClient, err := d.dockerClientFactory.NewDockerClient(ctx, types.Infrastructure{
|
||||||
ProviderType: enum.InfraProviderTypeDocker,
|
ProviderType: enum.InfraProviderTypeDocker,
|
||||||
@ -160,6 +155,13 @@ func (d DockerProvider) Find(
|
|||||||
return infrastructure, nil
|
return infrastructure, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d DockerProvider) FindInfraStatus(_ context.Context,
|
||||||
|
_ string,
|
||||||
|
_ string,
|
||||||
|
_ []types.InfraProviderParameter) (*enum.InfraStatus, error) {
|
||||||
|
return nil, nil //nolint:nilnil
|
||||||
|
}
|
||||||
|
|
||||||
// Stop is NOOP as this provider uses already running docker engine. It does not stop the docker engine.
|
// Stop is NOOP as this provider uses already running docker engine. It does not stop the docker engine.
|
||||||
func (d DockerProvider) Stop(ctx context.Context, infra types.Infrastructure) error {
|
func (d DockerProvider) Stop(ctx context.Context, infra types.Infrastructure) error {
|
||||||
infra.Status = enum.InfraStatusDestroyed
|
infra.Status = enum.InfraStatusDestroyed
|
||||||
|
@ -32,7 +32,6 @@ type InfraProvider interface {
|
|||||||
agentPort int,
|
agentPort int,
|
||||||
requiredGitspacePorts []types.GitspacePort,
|
requiredGitspacePorts []types.GitspacePort,
|
||||||
inputParameters []types.InfraProviderParameter,
|
inputParameters []types.InfraProviderParameter,
|
||||||
configMetadata map[string]any,
|
|
||||||
) error
|
) error
|
||||||
|
|
||||||
// Find finds infrastructure provisioned against a gitspace.
|
// Find finds infrastructure provisioned against a gitspace.
|
||||||
@ -41,13 +40,16 @@ type InfraProvider interface {
|
|||||||
spaceID int64,
|
spaceID int64,
|
||||||
spacePath string,
|
spacePath string,
|
||||||
gitspaceConfigIdentifier string,
|
gitspaceConfigIdentifier string,
|
||||||
gitspaceInstanceIdentifier string,
|
|
||||||
agentPort int,
|
|
||||||
requiredGitspacePorts []types.GitspacePort,
|
|
||||||
inputParameters []types.InfraProviderParameter,
|
inputParameters []types.InfraProviderParameter,
|
||||||
configMetadata map[string]any,
|
|
||||||
) (*types.Infrastructure, error)
|
) (*types.Infrastructure, error)
|
||||||
|
|
||||||
|
FindInfraStatus(
|
||||||
|
ctx context.Context,
|
||||||
|
gitspaceConfigIdentifier string,
|
||||||
|
gitspaceInstanceIdentifier string,
|
||||||
|
inputParameters []types.InfraProviderParameter,
|
||||||
|
) (*enum.InfraStatus, error)
|
||||||
|
|
||||||
// Stop frees up the resources allocated against a gitspace, which can be freed.
|
// Stop frees up the resources allocated against a gitspace, which can be freed.
|
||||||
Stop(ctx context.Context, infra types.Infrastructure) error
|
Stop(ctx context.Context, infra types.Infrastructure) error
|
||||||
|
|
||||||
|
31
types/enum/gitspace_operations_event.go
Normal file
31
types/enum/gitspace_operations_event.go
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// Copyright 2023 Harness, Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package enum
|
||||||
|
|
||||||
|
type GitspaceOperationsEvent string
|
||||||
|
|
||||||
|
func (GitspaceOperationsEvent) Enum() []interface{} {
|
||||||
|
return toInterfaceSlice(gitspaceOperationsEvent)
|
||||||
|
}
|
||||||
|
|
||||||
|
var gitspaceOperationsEvent = []GitspaceOperationsEvent{
|
||||||
|
GitspaceOperationsEventStart, GitspaceOperationsEventStop, GitspaceOperationsEventDelete,
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
GitspaceOperationsEventStart GitspaceOperationsEvent = "start"
|
||||||
|
GitspaceOperationsEventStop GitspaceOperationsEvent = "stop"
|
||||||
|
GitspaceOperationsEventDelete GitspaceOperationsEvent = "delete"
|
||||||
|
)
|
@ -48,6 +48,10 @@ type InstanceInfo struct {
|
|||||||
PoolName string `json:"pool_name"`
|
PoolName string `json:"pool_name"`
|
||||||
Zone string `json:"zone"`
|
Zone string `json:"zone"`
|
||||||
StorageIdentifier string `json:"storage_identifier"`
|
StorageIdentifier string `json:"storage_identifier"`
|
||||||
|
CAKey []byte `json:"ca_key"`
|
||||||
|
CACert []byte `json:"ca_cert"`
|
||||||
|
TLSKey []byte `json:"tls_key"`
|
||||||
|
TLSCert []byte `json:"tls_cert"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Infrastructure struct {
|
type Infrastructure struct {
|
||||||
@ -65,6 +69,8 @@ type Infrastructure struct {
|
|||||||
ProviderType enum.InfraProviderType
|
ProviderType enum.InfraProviderType
|
||||||
// InputParameters which are required by the provider to provision the infra.
|
// InputParameters which are required by the provider to provision the infra.
|
||||||
InputParameters []InfraProviderParameter
|
InputParameters []InfraProviderParameter
|
||||||
|
// ConfigMetadata contains the infra config metadata required by the infra provider to provision the infra.
|
||||||
|
ConfigMetadata map[string]any
|
||||||
// Status of the infra.
|
// Status of the infra.
|
||||||
Status enum.InfraStatus
|
Status enum.InfraStatus
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user