diff --git a/pkg/instance/build.go b/pkg/instance/build.go index 56990d2..1a3ad1c 100644 --- a/pkg/instance/build.go +++ b/pkg/instance/build.go @@ -5,7 +5,6 @@ import ( "fmt" "path/filepath" "sync" - "time" "github.com/google/uuid" "github.com/sirupsen/logrus" @@ -47,7 +46,7 @@ func (b *build) SetImagePullPolicy(pullPolicy v1.PullPolicy) { // SetImage sets the image of the instance. // It is only allowed in the 'None' and 'Preparing' states. func (b *build) SetImage(ctx context.Context, image string) error { - if !b.instance.IsInState(StateNone, StatePreparing) { + if !b.instance.IsInState(StateNone, StatePreparing, StateStopped) { if b.instance.sidecars.IsSidecar() { return ErrSettingImageNotAllowedForSidecarsStarted } @@ -95,7 +94,7 @@ func (b *build) SetGitRepo(ctx context.Context, gitContext builder.GitContext) e // SetStartCommand sets the command to run in the instance // This function can only be called when the instance is in state 'Preparing' or 'Committed' func (b *build) SetStartCommand(command ...string) error { - if !b.instance.IsInState(StatePreparing, StateCommitted) { + if !b.instance.IsInState(StatePreparing, StateCommitted, StateStopped) { return ErrSettingCommand.WithParams(b.instance.state.String()) } b.command = command @@ -105,7 +104,7 @@ func (b *build) SetStartCommand(command ...string) error { // SetArgs sets the arguments passed to the instance // This function can only be called in the states 'Preparing' or 'Committed' func (b *build) SetArgs(args ...string) error { - if !b.instance.IsInState(StatePreparing, StateCommitted) { + if !b.instance.IsInState(StatePreparing, StateCommitted, StateStopped) { return ErrSettingArgsNotAllowed.WithParams(b.instance.state.String()) } b.args = args @@ -228,7 +227,7 @@ func (b *build) addFileToBuilder(src, dest, chown string) { // SetEnvironmentVariable sets the given environment variable in the instance // This function can only be called in the states 'Preparing' and 'Committed' func (b *build) SetEnvironmentVariable(key, value string) error { - if !b.instance.IsInState(StatePreparing, StateCommitted) { + if !b.instance.IsInState(StatePreparing, StateCommitted, StateStopped) { return ErrSettingEnvNotAllowed.WithParams(b.instance.state.String()) } b.instance.Logger.WithFields(logrus.Fields{ @@ -245,29 +244,6 @@ func (b *build) SetEnvironmentVariable(key, value string) error { return nil } -// setImageWithGracePeriod sets the image of the instance with a grace period -func (b *build) setImageWithGracePeriod(ctx context.Context, imageName string, gracePeriod time.Duration) error { - b.imageName = imageName - - var gracePeriodInSecondsPtr *int64 - if gracePeriod != 0 { - gpInSeconds := int64(gracePeriod.Seconds()) - gracePeriodInSecondsPtr = &gpInSeconds - } - _, err := b.instance.K8sClient.ReplaceReplicaSetWithGracePeriod(ctx, b.instance.execution.prepareReplicaSetConfig(), gracePeriodInSecondsPtr) - if err != nil { - return ErrReplacingPod.Wrap(err) - } - - if err := b.instance.execution.WaitInstanceIsRunning(ctx); err != nil { - return ErrWaitingInstanceIsRunning.Wrap(err) - } - - return nil -} - -// imageCache maps image hash values to image names - // checkImageHashInCache checks if the given image hash exists in the cache. func (b *build) checkImageHashInCache(imageHash string) (string, bool) { value, exists := b.imageCache.Load(imageHash) diff --git a/pkg/instance/errors.go b/pkg/instance/errors.go index 87982a0..497c09b 100644 --- a/pkg/instance/errors.go +++ b/pkg/instance/errors.go @@ -217,6 +217,7 @@ var ( ErrSidecarInstanceIsNil = errors.New("SidecarInstanceIsNil", "sidecar instance is nil for instance '%s'") ErrFailedToDeletePersistentVolumeClaim = errors.New("FailedToDeletePersistentVolumeClaim", "failed to delete persistent volume claim") ErrUpgradingImageNotAllowed = errors.New("UpgradingImageNotAllowed", "upgrading image is only allowed in state 'Started'. Current state is '%s'") + ErrAddingHostToProxyNotAllowed = errors.New("AddingHostToProxyNotAllowed", "adding host to proxy is only allowed in state 'Started' and 'Preparing'. Current state is '%s'") ErrInstanceNameAlreadyExists = errors.New("InstanceNameAlreadyExists", "instance name '%s' already exists") ErrSettingSidecarName = errors.New("SettingSidecarName", "error setting sidecar name with prefix '%s' for instance '%s'") ) diff --git a/pkg/instance/execution.go b/pkg/instance/execution.go index 7b5cc0b..f105834 100644 --- a/pkg/instance/execution.go +++ b/pkg/instance/execution.go @@ -216,6 +216,10 @@ func (e *execution) Stop(ctx context.Context) error { return nil } +func (b *execution) SetImage(ctx context.Context, image string) error { + return b.instance.build.SetImage(ctx, image) +} + // Labels returns the labels for the instance func (e *execution) Labels() map[string]string { return map[string]string{ @@ -264,18 +268,6 @@ func (e *execution) Destroy(ctx context.Context) error { return nil } -func (e *execution) UpgradeImage(ctx context.Context, image string) error { - return e.UpgradeImageWithGracePeriod(ctx, image, 0) -} - -func (e *execution) UpgradeImageWithGracePeriod(ctx context.Context, image string, gracePeriod time.Duration) error { - if !e.instance.IsInState(StateStarted) { - return ErrUpgradingImageNotAllowed.WithParams(e.instance.state.String()) - } - - return e.instance.build.setImageWithGracePeriod(ctx, image, gracePeriod) -} - // BatchDestroy destroys a list of instances. func BatchDestroy(ctx context.Context, instances ...*Instance) error { if os.Getenv("KNUU_SKIP_CLEANUP") == "true" { diff --git a/pkg/instance/monitoring.go b/pkg/instance/monitoring.go index d4840be..b2361a7 100644 --- a/pkg/instance/monitoring.go +++ b/pkg/instance/monitoring.go @@ -76,7 +76,7 @@ func (m *monitoring) SetStartupProbe(startupProbe *v1.Probe) error { // checkStateForProbe checks if the current state is allowed for setting a probe func (m *monitoring) checkStateForProbe() error { - if !m.instance.IsInState(StatePreparing, StateCommitted) { + if !m.instance.IsInState(StatePreparing, StateCommitted, StateStopped) { return ErrSettingProbeNotAllowed.WithParams(m.instance.state.String()) } return nil diff --git a/pkg/instance/network.go b/pkg/instance/network.go index 266ec33..584a3b4 100644 --- a/pkg/instance/network.go +++ b/pkg/instance/network.go @@ -21,9 +21,9 @@ func (i *Instance) Network() *network { } // AddPortTCP adds a TCP port to the instance -// This function can be called in the states 'Preparing' and 'Committed' +// This function can be called in the states 'Preparing', 'Committed' and 'Stopped' func (n *network) AddPortTCP(port int) error { - if !n.instance.IsInState(StatePreparing, StateCommitted) { + if !n.instance.IsInState(StatePreparing, StateCommitted, StateStopped) { return ErrAddingPortNotAllowed.WithParams(n.instance.state.String()) } @@ -97,9 +97,9 @@ func (n *network) PortForwardTCP(ctx context.Context, port int) (int, error) { } // AddPortUDP adds a UDP port to the instance -// This function can be called in the states 'Preparing' and 'Committed' +// This function can be called in the states 'Preparing', 'Committed' and 'Stopped' func (n *network) AddPortUDP(port int) error { - if !n.instance.IsInState(StatePreparing, StateCommitted) { + if !n.instance.IsInState(StatePreparing, StateCommitted, StateStopped) { return ErrAddingPortNotAllowed.WithParams(n.instance.state.String()) } diff --git a/pkg/instance/proxy.go b/pkg/instance/proxy.go index 79a3760..58342af 100644 --- a/pkg/instance/proxy.go +++ b/pkg/instance/proxy.go @@ -11,6 +11,10 @@ const ( ) func (n *network) AddHost(ctx context.Context, port int) (host string, err error) { + if !n.instance.IsInState(StateStarted, StatePreparing, StateCommitted) { + return "", ErrAddingHostToProxyNotAllowed.WithParams(n.instance.state.String()) + } + if n.instance.Proxy == nil { return "", ErrProxyNotInitialized } diff --git a/pkg/instance/resources.go b/pkg/instance/resources.go index 1ca6a55..9497b1f 100644 --- a/pkg/instance/resources.go +++ b/pkg/instance/resources.go @@ -20,9 +20,9 @@ func (i *Instance) Resources() *resources { } // SetMemory sets the memory of the instance -// This function can only be called in the states 'Preparing' and 'Committed' +// This function can only be called in the states 'Preparing', 'Committed' and 'Stopped' func (r *resources) SetMemory(request, limit resource.Quantity) error { - if !r.instance.IsInState(StatePreparing, StateCommitted) { + if !r.instance.IsInState(StatePreparing, StateCommitted, StateStopped) { return ErrSettingMemoryNotAllowed.WithParams(r.instance.state.String()) } r.memoryRequest = request @@ -36,9 +36,9 @@ func (r *resources) SetMemory(request, limit resource.Quantity) error { } // SetCPU sets the CPU of the instance -// This function can only be called in the states 'Preparing' and 'Committed' +// This function can only be called in the states 'Preparing', 'Committed' and 'Stopped' func (r *resources) SetCPU(request resource.Quantity) error { - if !r.instance.IsInState(StatePreparing, StateCommitted) { + if !r.instance.IsInState(StatePreparing, StateCommitted, StateStopped) { return ErrSettingCPUNotAllowed.WithParams(r.instance.state.String()) } r.cpuRequest = request diff --git a/pkg/instance/security.go b/pkg/instance/security.go index f2d954e..e451ffc 100644 --- a/pkg/instance/security.go +++ b/pkg/instance/security.go @@ -27,9 +27,9 @@ func (i *Instance) Security() *security { } // AddPolicyRule adds a policy rule to the instance -// This function can only be called in the states 'Preparing' and 'Committed' +// This function can only be called in the states 'Preparing', 'Committed' and 'Stopped' func (s *security) AddPolicyRule(rule rbacv1.PolicyRule) error { - if !s.instance.IsInState(StatePreparing, StateCommitted) { + if !s.instance.IsInState(StatePreparing, StateCommitted, StateStopped) { return ErrAddingPolicyRuleNotAllowed.WithParams(s.instance.state.String()) } s.policyRules = append(s.policyRules, rule) @@ -37,9 +37,9 @@ func (s *security) AddPolicyRule(rule rbacv1.PolicyRule) error { } // SetPrivileged sets the privileged status for the instance -// This function can only be called in the state 'Preparing' or 'Committed' +// This function can only be called in the state 'Preparing', 'Committed' or 'Stopped' func (s *security) SetPrivileged(privileged bool) error { - if !s.instance.IsInState(StatePreparing, StateCommitted) { + if !s.instance.IsInState(StatePreparing, StateCommitted, StateStopped) { return ErrSettingPrivilegedNotAllowed.WithParams(s.instance.state.String()) } s.privileged = privileged @@ -51,9 +51,9 @@ func (s *security) SetPrivileged(privileged bool) error { } // AddKubernetesCapability adds a Kubernetes capability to the instance -// This function can only be called in the state 'Preparing' or 'Committed' +// This function can only be called in the state 'Preparing', 'Committed' or 'Stopped' func (s *security) AddKubernetesCapability(capability string) error { - if !s.instance.IsInState(StatePreparing, StateCommitted) { + if !s.instance.IsInState(StatePreparing, StateCommitted, StateStopped) { return ErrAddingCapabilityNotAllowed.WithParams(s.instance.state.String()) } s.capabilitiesAdd = append(s.capabilitiesAdd, capability) @@ -65,9 +65,9 @@ func (s *security) AddKubernetesCapability(capability string) error { } // AddKubernetesCapabilities adds multiple Kubernetes capabilities to the instance -// This function can only be called in the state 'Preparing' or 'Committed' +// This function can only be called in the state 'Preparing', 'Committed' or 'Stopped' func (s *security) AddKubernetesCapabilities(capabilities []string) error { - if !s.instance.IsInState(StatePreparing, StateCommitted) { + if !s.instance.IsInState(StatePreparing, StateCommitted, StateStopped) { return ErrAddingCapabilitiesNotAllowed.WithParams(s.instance.state.String()) } s.capabilitiesAdd = append(s.capabilitiesAdd, capabilities...) diff --git a/pkg/instance/sidecars.go b/pkg/instance/sidecars.go index c3e1226..c79c080 100644 --- a/pkg/instance/sidecars.go +++ b/pkg/instance/sidecars.go @@ -36,12 +36,12 @@ func (s *sidecars) IsSidecar() bool { } // Add adds a sidecar to the instance -// This function can only be called in the state 'Preparing' or 'Committed' +// This function can only be called in the state 'Preparing', 'Committed' or 'Stopped' func (s *sidecars) Add(ctx context.Context, sc SidecarManager) error { if sc == nil { return ErrSidecarIsNil } - if !s.instance.IsInState(StatePreparing, StateCommitted) { + if !s.instance.IsInState(StatePreparing, StateCommitted, StateStopped) { return ErrAddingSidecarNotAllowed.WithParams(s.instance.state.String()) } diff --git a/pkg/instance/storage.go b/pkg/instance/storage.go index b24d501..8b515ba 100644 --- a/pkg/instance/storage.go +++ b/pkg/instance/storage.go @@ -50,7 +50,7 @@ func (s *storage) AddFile(src string, dest string, chown string) error { case StatePreparing: s.instance.build.addFileToBuilder(src, dest, chown) return nil - case StateCommitted: + case StateCommitted, StateStopped: return s.addFileToInstance(dstPath, dest, chown) } @@ -64,9 +64,9 @@ func (s *storage) AddFile(src string, dest string, chown string) error { } // AddFolder adds a folder to the instance -// This function can only be called in the state 'Preparing' or 'Committed' +// This function can only be called in the state 'Preparing', 'Committed' or 'Stopped' func (s *storage) AddFolder(src string, dest string, chown string) error { - if !s.instance.IsInState(StatePreparing, StateCommitted) { + if !s.instance.IsInState(StatePreparing, StateCommitted, StateStopped) { return ErrAddingFolderNotAllowed.WithParams(s.instance.state.String()) } @@ -141,7 +141,7 @@ func (s *storage) AddFileBytes(bytes []byte, dest string, chown string) error { // AddVolume adds a volume to the instance // The owner of the volume is set to 0, if you want to set a custom owner use AddVolumeWithOwner -// This function can only be called in the states 'Preparing' and 'Committed' +// This function can only be called in the states 'Preparing', 'Committed' and 'Stopped' func (s *storage) AddVolume(path string, size resource.Quantity) error { // temporary feat, we will remove it once we can add multiple volumes if len(s.volumes) > 0 { @@ -155,9 +155,9 @@ func (s *storage) AddVolume(path string, size resource.Quantity) error { } // AddVolumeWithOwner adds a volume to the instance with the given owner -// This function can only be called in the states 'Preparing' and 'Committed' +// This function can only be called in the states 'Preparing', 'Committed' and 'Stopped' func (s *storage) AddVolumeWithOwner(path string, size resource.Quantity, owner int64) error { - if !s.instance.IsInState(StatePreparing, StateCommitted) { + if !s.instance.IsInState(StatePreparing, StateCommitted, StateStopped) { return ErrAddingVolumeNotAllowed.WithParams(s.instance.state.String()) } // temporary feat, we will remove it once we can add multiple volumes @@ -295,7 +295,7 @@ func (s *storage) addFileToInstance(dstPath, dest, chown string) error { // checkStateForAddingFile checks if the current state allows adding a file func (s *storage) checkStateForAddingFile() error { - if !s.instance.IsInState(StatePreparing, StateCommitted) { + if !s.instance.IsInState(StatePreparing, StateCommitted, StateStopped) { return ErrAddingFileNotAllowed.WithParams(s.instance.state.String()) } return nil