Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 45 additions & 1 deletion src/core/cm/launcher/balancer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,17 @@ void Balancer::Init(InstanceManager& instanceManager, imagemanager::ItemInfoProv
mNetworkManager = &networkManager;
}

bool Balancer::OverrideEnvVars(const OverrideEnvVarsRequest& envVars)
{
if (mEnvVarsOverrides == envVars) {
return false;
}

mEnvVarsOverrides = envVars;

return true;
}

RetWithError<bool> Balancer::SetSubjects(const Array<StaticString<cIDLen>>& subjects)
{
if (auto err = mSubjects.Assign(subjects); !err.IsNone()) {
Expand Down Expand Up @@ -90,7 +101,7 @@ Error Balancer::SetupInstanceInfo(const oci::ServiceConfig& servConf, const Node
const RunInstanceRequest& request, const oci::IndexContentDescriptor& imageDescriptor, const String& runtimeID,
const Instance& instance, aos::InstanceInfo& info)
{
// create instance info, InstanceNetworkParameters are added after network updates
// Create instance info, InstanceNetworkParameters are added after network updates
static_cast<InstanceIdent&>(info) = instance.GetInfo().mInstanceIdent;
info.mManifestDigest = imageDescriptor.mDigest;
info.mRuntimeID = runtimeID;
Expand All @@ -104,6 +115,35 @@ Error Balancer::SetupInstanceInfo(const oci::ServiceConfig& servConf, const Node
return AOS_ERROR_WRAP(err);
}

if (auto err = ApplyEnvVarOverrides(info); !err.IsNone()) {
return AOS_ERROR_WRAP(err);
}

return ErrorEnum::eNone;
}

Error Balancer::ApplyEnvVarOverrides(aos::InstanceInfo& info)
Copy link
Member

@mlohvynenko mlohvynenko Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider the next scenario:

  1. image config has no env vars set
  2. override env var handles ENV1=VAL1, TTL not set (and succeeds)
  3. override env var handles ENV2=VAL2, TTL not set (and succeeds)

What env vars are assigned to the instance after (3): both pairs?

{
for (const auto& item : mEnvVarsOverrides.mItems) {
if (!item.Match(info)) {
continue;
}

for (const auto& envVarInfo : item.mVariables) {
auto found = info.mEnvVars.FindIf(
[&envVarInfo](const EnvVar& existing) { return existing.mName == envVarInfo.mName; });

if (found != info.mEnvVars.end()) {
found->mValue = envVarInfo.mValue;
} else {
auto envVar = EnvVar {envVarInfo.mName, envVarInfo.mValue};
if (auto err = info.mEnvVars.PushBack(envVar); !err.IsNone()) {
return AOS_ERROR_WRAP(err);
}
}
}
}

return ErrorEnum::eNone;
}

Expand Down Expand Up @@ -214,6 +254,8 @@ Error Balancer::ScheduleInstance(
return err;
}

instance.SetEnvVars(imageConfig->mConfig.mEnv);

// Schedule instance.
auto reqCPU = GetRequestedCPU(instance, *node, *serviceConfig);
auto reqRAM = GetRequestedRAM(instance, *node, *serviceConfig);
Expand Down Expand Up @@ -705,6 +747,8 @@ Error Balancer::PerformPolicyBalancing(const Array<RunInstanceRequest>& requests
auto reqRAM = GetRequestedRAM(**instance, *node, *serviceConfig);
auto reqResources = serviceConfig->mResources;

(*instance)->SetEnvVars(imageConfig->mConfig.mEnv);

if (auto err = node->ScheduleInstance(
*instanceInfo, request.mSubjectInfo.mSubjectID, *networkServiceData, reqCPU, reqRAM, reqResources);
!err.IsNone()) {
Expand Down
14 changes: 11 additions & 3 deletions src/core/cm/launcher/balancer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ class Balancer {
*/
RetWithError<bool> SetSubjects(const Array<StaticString<cIDLen>>& subjects);

/**
* Overrides environment variables.
*
* @param envVars environment variables.
* @return bool true if env vars changed, false otherwise.
*/
bool OverrideEnvVars(const OverrideEnvVarsRequest& envVars);

private:
static constexpr auto cAllocatorSize = sizeof(StaticArray<RunInstanceRequest, cMaxNumInstances>)
+ sizeof(StaticArray<Node*, cMaxNumNodes>) + sizeof(oci::ServiceConfig) + sizeof(oci::ImageConfig)
Expand Down Expand Up @@ -100,10 +108,9 @@ class Balancer {
Error RemoveNetworkForDeletedInstances();
Error SetNetworkParams(bool onlyWithExposedPorts);
Error SetupNetworkForNewInstances();

Error ApplyEnvVarOverrides(aos::InstanceInfo& info);
Error PerformPolicyBalancing(const Array<RunInstanceRequest>& instances);

bool IsSubjectEnabled(const Instance& instance);
bool IsSubjectEnabled(const Instance& instance);

ImageInfoProvider mImageInfoProvider;
InstanceManager* mInstanceManager {};
Expand All @@ -112,6 +119,7 @@ class Balancer {
networkmanager::NetworkManagerItf* mNetworkManager {};
InstanceRunnerItf* mRunner {};
SubjectArray mSubjects;
OverrideEnvVarsRequest mEnvVarsOverrides;

StaticAllocator<cAllocatorSize> mAllocator;
};
Expand Down
5 changes: 3 additions & 2 deletions src/core/cm/launcher/instance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,9 @@ Error Instance::Schedule(const aos::InstanceInfo& info, const String& nodeID)
mInfo.mNodeID = nodeID;
mInfo.mUID = info.mUID;
mInfo.mGID = info.mGID;
mInfo.mTimestamp = Time::Now();
mInfo.mState = InstanceStateEnum::eActive;
// Keep original EnvVars, not overridden.
mInfo.mTimestamp = Time::Now();
mInfo.mState = InstanceStateEnum::eActive;

static_cast<InstanceIdent&>(mStatus) = static_cast<const InstanceIdent&>(info);
mStatus.mNodeID = nodeID;
Expand Down
7 changes: 7 additions & 0 deletions src/core/cm/launcher/instance.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,13 @@ class Instance {
*/
void UpdateMonitoringData(const MonitoringData& monitoringData);

/**
* Sets instance environment variables.
*
* @param envVars environment variables.
*/
void SetEnvVars(const EnvVarArray& envVars) { mInfo.mEnvVars = envVars; }

/**
* Removes instance.
*
Expand Down
24 changes: 23 additions & 1 deletion src/core/cm/launcher/itf/storage.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include <core/common/ocispec/itf/imagespec.hpp>
#include <core/common/types/common.hpp>
#include <core/common/types/envvars.hpp>

namespace aos::cm::launcher {

Expand Down Expand Up @@ -91,6 +92,11 @@ struct InstanceInfo {
*/
bool mIsUnitSubject {};

/**
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess no need to comment each field in this struct. It makes this struct too big.

* Environment variables assigned to the instance.
*/
EnvVarArray mEnvVars;

/**
* Compares instance info.
*
Expand All @@ -101,7 +107,8 @@ struct InstanceInfo {
{
return mInstanceIdent == rhs.mInstanceIdent && mManifestDigest == rhs.mManifestDigest && mNodeID == rhs.mNodeID
&& mPrevNodeID == rhs.mPrevNodeID && mRuntimeID == rhs.mRuntimeID && mUID == rhs.mUID && mGID == rhs.mGID
&& mTimestamp == rhs.mTimestamp && mState == rhs.mState && mIsUnitSubject == rhs.mIsUnitSubject;
&& mTimestamp == rhs.mTimestamp && mState == rhs.mState && mIsUnitSubject == rhs.mIsUnitSubject
&& mEnvVars == rhs.mEnvVars;
}

/**
Expand Down Expand Up @@ -163,6 +170,21 @@ class StorageItf {
* @return Error.
*/
virtual Error GetActiveInstances(Array<InstanceInfo>& instances) const = 0;

/**
* Saves override environment variables request.
*
* @param envVars override environment variables request.
* @return Error.
*/
virtual Error SaveOverrideEnvVars(const OverrideEnvVarsRequest& envVars) = 0;

/**
* Gets override environment variables request.
*
* @return override environment variables request.
*/
virtual Error GetOverrideEnvVars(OverrideEnvVarsRequest& envVars) = 0;
};

/** @}*/
Expand Down
48 changes: 45 additions & 3 deletions src/core/cm/launcher/launcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,19 @@ Error Launcher::Start()
// Notify status listeners.
NotifyInstanceStatusListeners(mInstanceStatuses);

// Load override environment variables.
if (auto err = mStorage->GetOverrideEnvVars(mOverrideEnvVars); !err.IsNone()) {
return AOS_ERROR_WRAP(err);
}

mBalancer.OverrideEnvVars(mOverrideEnvVars);

// Start timer to periodically check override environment variables TTLs.
auto onEnvVarsTTLTimerTick = [this](void*) { OverrideEnvVars(mOverrideEnvVars); };
if (auto err = mEnvVarsTTLTimer.Start(Time::cMinutes, onEnvVarsTTLTimerTick, false); !err.IsNone()) {
return AOS_ERROR_WRAP(err);
}

// Start monitoring thread.
mDisableProcessUpdates = false;
mUpdatedNodes.Clear();
Expand Down Expand Up @@ -147,6 +160,11 @@ Error Launcher::Stop()
return AOS_ERROR_WRAP(err);
}

// Stop TTL timer.
if (auto err = mEnvVarsTTLTimer.Stop(); !err.IsNone()) {
return AOS_ERROR_WRAP(err);
}

// Stop managers.
if (auto err = mInstanceManager.Stop(); !err.IsNone()) {
return err;
Expand Down Expand Up @@ -248,11 +266,35 @@ Error Launcher::UnsubscribeListener(instancestatusprovider::ListenerItf& listene

Error Launcher::OverrideEnvVars(const OverrideEnvVarsRequest& envVars)
{
(void)envVars;

LOG_DBG() << "Override env vars";

return ErrorEnum::eNone;
UniqueLock lock {mMutex};

mOverrideEnvVars = envVars;

// Remove variables with expired TTLs.
auto now = Time::Now();

for (auto& item : mOverrideEnvVars.mItems) {
item.mVariables.RemoveIf([&now](const EnvVarInfo& envVarInfo) {
return envVarInfo.mTTL.HasValue() && envVarInfo.mTTL.GetValue() < now;
});
}

mOverrideEnvVars.mItems.RemoveIf([](const EnvVarsInstanceInfo& item) { return item.mVariables.IsEmpty(); });

// Override environment variables.
if (!mBalancer.OverrideEnvVars(mOverrideEnvVars)) {
return ErrorEnum::eNone;
}

// Save override environment variables.
if (auto err = mStorage->SaveOverrideEnvVars(mOverrideEnvVars); !err.IsNone()) {
return AOS_ERROR_WRAP(err);
}

// Rebalance instances.
return Rebalance(lock);
}

/***********************************************************************************************************************
Expand Down
4 changes: 4 additions & 0 deletions src/core/cm/launcher/launcher.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <core/cm/unitconfig/itf/nodeconfigprovider.hpp>
#include <core/common/iamclient/itf/identprovider.hpp>
#include <core/common/ocispec/itf/ocispec.hpp>
#include <core/common/tools/timer.hpp>

#include "itf/envvarhandler.hpp"
#include "itf/instancestatusreceiver.hpp"
Expand Down Expand Up @@ -200,6 +201,9 @@ class Launcher : public LauncherItf,
Optional<SubjectArray> mNewSubjects;
Mutex mNewSubjectsMutex;

OverrideEnvVarsRequest mOverrideEnvVars;
Timer mEnvVarsTTLTimer;

Mutex mMutex;
StaticAllocator<cAllocatorSize> mAllocator;
};
Expand Down
Loading
Loading