Ejemplo n.º 1
0
static void CheckFileChanges(EvalContext *ctx, Policy **policy, GenericAgentConfig *config)
{
    Log(LOG_LEVEL_DEBUG, "Checking file updates for input file '%s'",
        config->input_file);

    time_t validated_at = ReadTimestampFromPolicyValidatedFile(config, NULL);

    bool reload_config = false;

    if (config->agent_specific.daemon.last_validated_at < validated_at)
    {
        Log(LOG_LEVEL_VERBOSE, "New promises detected...");
        reload_config = true;
    }
    if (ReloadConfigRequested())
    {
        Log(LOG_LEVEL_VERBOSE, "Force reload of inputs files...");
        reload_config = true;
    }

    if (reload_config)
    {
        ClearRequestReloadConfig();

        /* Rereading policies now, so update timestamp. */
        config->agent_specific.daemon.last_validated_at = validated_at;

        if (GenericAgentArePromisesValid(config))
        {
            Log(LOG_LEVEL_NOTICE, "Rereading policy file '%s'",
                config->input_file);

            /* STEP 1: Free everything */

            EvalContextClear(ctx);

            strcpy(VDOMAIN, "undefined.domain");

            ClearAuthAndACLs();
            PolicyDestroy(*policy);               *policy = NULL;

            /* STEP 2: Set Environment, Parse and Evaluate policy */

            /*
             * TODO why is this done separately here? What's the difference to
             * calling the same steps as in cf-serverd.c:main()? Those are:
             *   GenericAgentConfigApply();     // not here!
             *   GenericAgentDiscoverContext(); // not here!
             *   EvalContextClassPutHard("server");             // only here!
             *   if (GenericAgentCheckPolicy()) // not here!
             *     policy = LoadPolicy();
             *   ThisAgentInit();               // not here, only calls umask()
             *   ReloadHAConfig();                              // only here!
             *   KeepPromises();
             *   Summarize();
             * Plus the following from within StartServer() which is only
             * called during startup:
             *   InitSignals();                  // not here
             *   ServerTLSInitialize();          // not here
             *   SetServerListenState();         // not here
             *   InitServer()                    // not here
             *   PolicyNew()+AcquireServerLock() // not here
             *   PrepareServer(sd);              // not here
             *   CollectCallStart();  // both
             */

            EvalContextSetPolicyServerFromFile(ctx, GetWorkDir());

            UpdateLastPolicyUpdateTime(ctx);

            DetectEnvironment(ctx);
            KeepHardClasses(ctx);
            LoadAugments(ctx, config);

            /* During startup this is done in GenericAgentDiscoverContext(). */
            EvalContextClassPutHard(ctx, CF_AGENTTYPES[AGENT_TYPE_SERVER], "cfe_internal,source=agent");

            time_t t = SetReferenceTime();
            UpdateTimeClasses(ctx, t);

            /* TODO BUG: this modifies config, but previous config has not
             * been reset/free'd. Ideally we would want LoadPolicy to not
             * modify config at all, but only modify ctx. */
            *policy = LoadPolicy(ctx, config);

            /* Reload HA related configuration */
            ReloadHAConfig();

            KeepPromises(ctx, *policy, config);
            Summarize();
        }
        else
        {
            Log(LOG_LEVEL_INFO, "File changes contain errors -- ignoring");
        }
    }
    else
    {
        Log(LOG_LEVEL_DEBUG, "No new promises found");
    }
}
Ejemplo n.º 2
0
static bool ScheduleRun(EvalContext *ctx, Policy **policy, GenericAgentConfig *config,
                        ExecdConfig **execd_config, ExecConfig **exec_config)
{
    /* 1 Minute resolution is enough */
    MaybeSleepLog(LOG_LEVEL_VERBOSE, "Sleeping for pulse time %u seconds...", CFPULSETIME);

    /*
     * FIXME: this logic duplicates the one from cf-serverd.c. Unify ASAP.
     */

    if (CheckNewPromises(config) == RELOAD_FULL)
    {
        /* Full reload */

        Log(LOG_LEVEL_INFO, "Re-reading promise file '%s'", config->input_file);

        EvalContextClear(ctx);

        strcpy(VDOMAIN, "undefined.domain");

        PolicyDestroy(*policy);
        *policy = NULL;

        EvalContextSetPolicyServerFromFile(ctx, GetWorkDir());
        UpdateLastPolicyUpdateTime(ctx);

        DetectEnvironment(ctx);

        Log(LOG_LEVEL_INFO, "Re-evaluating augments" );
        LoadAugments(ctx, config);

        EvalContextClassPutHard(ctx, CF_AGENTTYPES[AGENT_TYPE_EXECUTOR], "cfe_internal,source=agent");

        time_t t = SetReferenceTime();
        UpdateTimeClasses(ctx, t);

        GenericAgentConfigSetBundleSequence(config, NULL);

        *policy = LoadPolicy(ctx, config);
        ExecConfigDestroy(*exec_config);
        ExecdConfigDestroy(*execd_config);

        *exec_config = ExecConfigNew(!ONCE, ctx, *policy);
        *execd_config = ExecdConfigNew(ctx, *policy);

        SetFacility((*execd_config)->log_facility);
    }
    else
    {
        /* Environment reload */

        EvalContextClear(ctx);

        DetectEnvironment(ctx);

        time_t t = SetReferenceTime();
        UpdateTimeClasses(ctx, t);
    }

    {
        StringSetIterator it = StringSetIteratorInit((*execd_config)->schedule);
        const char *time_context = NULL;
        while ((time_context = StringSetIteratorNext(&it)))
        {
            if (IsDefinedClass(ctx, time_context))
            {
                Log(LOG_LEVEL_VERBOSE, "Waking up the agent at %s ~ %s", ctime(&CFSTARTTIME), time_context);
                return true;
            }
        }
    }

    Log(LOG_LEVEL_VERBOSE, "Nothing to do at %s", ctime(&CFSTARTTIME));
    return false;
}