diff --git a/.gitignore b/.gitignore index ad8b3a21113..a2379da89ad 100644 --- a/.gitignore +++ b/.gitignore @@ -43,7 +43,6 @@ stamp-h1 /cf-serverd/Makefile /cf-testd/Makefile /cf-upgrade/Makefile -/cf-watchd/Makefile /cf-reactor/Makefile /contrib/vagrant-ci/centos-9s-x64/Makefile /examples/Makefile @@ -114,8 +113,6 @@ xml_tmp_suite /cf-testd/cf-testd.exe /cf-upgrade/cf-upgrade /cf-upgrade/cf-upgrade.exe -/cf-watchd/cf-watchd -/cf-watchd/cf-watchd.exe /cf-reactor/cf-reactor /cf-reactor/cf-reactor.exe /ext/rpmvercmp @@ -197,3 +194,6 @@ misc/selinux/cfengine-enterprise.pp misc/selinux/cfengine-enterprise.if misc/selinux/cfengine-enterprise.te misc/selinux/tmp + +# nix +contrib/nix/result diff --git a/Makefile.am b/Makefile.am index b7c62cbebc3..07ccc7332cd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -45,7 +45,6 @@ SUBDIRS = \ cf-upgrade \ cf-net \ cf-secret \ - cf-watchd \ cf-reactor \ misc \ python \ diff --git a/cf-watchd/Makefile.am b/cf-watchd/Makefile.am deleted file mode 100644 index beddc62f737..00000000000 --- a/cf-watchd/Makefile.am +++ /dev/null @@ -1,53 +0,0 @@ -# -# Copyright 2021 Northern.tech AS -# -# This file is part of CFEngine 3 - written and maintained by Northern.tech AS. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; version 3. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -# -# To the extent this program is licensed as part of the Enterprise -# versions of CFEngine, the applicable Commercial Open Source License -# (COSL) may apply to this file if you as a licensee so wish it. See -# included file COSL.txt. -# -noinst_LTLIBRARIES = libcf-watchd.la - -AM_CPPFLAGS = -I$(srcdir)/../libpromises -I$(srcdir)/../libntech/libutils \ - -I$(srcdir)/../libcfecompat \ - -I$(srcdir)/../libcfnet \ - $(OPENSSL_CPPFLAGS) \ - $(PCRE2_CPPFLAGS) \ - $(ENTERPRISE_CPPFLAGS) - -AM_CFLAGS = $(CF3_CFLAGS) \ - $(DEBUG_CFLAGS) \ - $(OPENSSL_CFLAGS) \ - $(ENTERPRISE_CFLAGS) - -libcf_watchd_la_LIBADD = ../libpromises/libpromises.la - -libcf_watchd_la_SOURCES = cf-watchd.c - -if !BUILTIN_EXTENSIONS - bin_PROGRAMS = cf-watchd - cf_watchd_LDADD = libcf-watchd.la - cf_watchd_SOURCES = -endif - -CLEANFILES = *.gcno *.gcda - -# -# Some basic clean ups -# -MOSTLYCLEANFILES = *~ *.orig *.rej diff --git a/cf-watchd/cf-watchd.c b/cf-watchd/cf-watchd.c deleted file mode 100644 index 01cb0d9d44f..00000000000 --- a/cf-watchd/cf-watchd.c +++ /dev/null @@ -1,259 +0,0 @@ -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - - -static GenericAgentConfig *CheckOpts(int argc, char **argv); -static void WatchStart(); - -/*****************************************************************************/ -/* Globals */ -/*****************************************************************************/ - -int NO_FORK = false; - -/*******************************************************************/ -/* Command line options */ -/*******************************************************************/ - - -static const char *const CF_WATCHD_SHORT_DESCRIPTION = - "event watching daemon for CFEngine"; - -static const char *const CF_WATCHD_MANPAGE_LONG_DESCRIPTION = - "cf-watchd is the event watching and reacting daemon for CFEngine. It watches specific events defined in the policy " - "and runs policy code on reaction to these events."; - -static const Component COMPONENT = -{ - .name = "cf-watchd", - .website = CF_WEBSITE, - .copyright = CF_COPYRIGHT -}; - -static const struct option OPTIONS[] = -{ - {"help", no_argument, 0, 'h'}, - {"debug", no_argument, 0, 'd'}, - {"verbose", no_argument, 0, 'v'}, - {"version", no_argument, 0, 'V'}, - {"no-lock", no_argument, 0, 'K'}, - {"file", required_argument, 0, 'f'}, - {"log-level", required_argument, 0, 'g'}, - {"inform", no_argument, 0, 'I'}, - {"no-fork", no_argument, 0, 'F'}, - {"man", no_argument, 0, 'M'}, - {"color", optional_argument, 0, 'C'}, - {"timestamp", no_argument, 0, 'l'}, - /* Only long option for the rest */ - {"ignore-preferred-augments", no_argument, 0, 0}, - {NULL, 0, 0, '\0'} -}; - -static const char *const HINTS[] = -{ - "Print the help message", - "Enable debugging output", - "Output verbose information about the behaviour of cf-watchd", - "Output the version of the software", - "Ignore system lock", - "Specify an alternative input file than the default. This option is overridden by FILE if supplied as argument.", - "Specify how detailed logs should be. Possible values: 'error', 'warning', 'notice', 'info', 'verbose', 'debug'", - "Print basic information about changes made to the system, i.e. promises repaired", - "Run process in foreground, not as a daemon", - "Outputs the man page of the program", - "Enable colorized output. Possible values: 'always', 'auto', 'never'. If option is used, the default value is 'auto'", - "Log timestamps on each line of log output", - "Ignore def_preferred.json file in favor of def.json", - NULL -}; - -/*****************************************************************************/ - -int main(int argc, char **argv) -{ - GenericAgentConfig *config = CheckOpts(argc, argv); - EvalContext *ctx = EvalContextNew(); - GenericAgentConfigApply(ctx, config); - -#ifndef __MINGW32__ - pid_t existing_pid = ReadPID("cf-watchd.pid"); - if ((existing_pid != -1) && (kill(existing_pid, 0) == 0)) - { - Log(LOG_LEVEL_ERR, "Another instance of cf-watchd is already running, terminating"); - return 1; - } -#endif - -#ifdef __MINGW32__ - - if (!NO_FORK) - { - Log(LOG_LEVEL_VERBOSE, "Windows does not support starting processes in the background - starting in foreground"); - } - -#else /* !__MINGW32__ */ - - if ((!NO_FORK) && (fork() != 0)) - { - Log(LOG_LEVEL_INFO, "cf-watchd: starting"); - _exit(EXIT_SUCCESS); - } - - if (!NO_FORK) - { - ActAsDaemon(); - } - -#endif /* !__MINGW32__ */ - - - umask(077); - WritePID("cf-watchd.pid"); - - signal(SIGINT, HandleSignalsForDaemon); - signal(SIGTERM, HandleSignalsForDaemon); - signal(SIGBUS, HandleSignalsForDaemon); - signal(SIGHUP, HandleSignalsForDaemon); - signal(SIGPIPE, SIG_IGN); - signal(SIGUSR1, HandleSignalsForDaemon); - signal(SIGUSR2, HandleSignalsForDaemon); - - WatchStart(); - - GenericAgentFinalize(ctx, config); - CallCleanupFunctions(); - - return 0; -} - -static GenericAgentConfig *CheckOpts(int argc, char **argv) -{ - extern char *optarg; - int c; - GenericAgentConfig *config = GenericAgentConfigNewDefault(AGENT_TYPE_WATCH, GetTTYInteractive()); - - int longopt_idx; - while ((c = getopt_long(argc, argv, "dvIf:g:VKMFhC::l", - OPTIONS, &longopt_idx)) != -1) - { - switch (c) - { - case 'f': - GenericAgentConfigSetInputFile(config, GetInputDir(), optarg); - MINUSF = true; - break; - - case 'd': - LogSetGlobalLevel(LOG_LEVEL_DEBUG); - NO_FORK = true; - break; - - case 'K': - config->ignore_locks = true; - break; - - case 'I': - LogSetGlobalLevel(LOG_LEVEL_INFO); - break; - - case 'v': - LogSetGlobalLevel(LOG_LEVEL_VERBOSE); - NO_FORK = true; - break; - - case 'g': - LogSetGlobalLevelArgOrExit(optarg); - break; - - case 'F': - NO_FORK = true; - break; - - case 'V': - { - Writer *w = FileWriter(stdout); - GenericAgentWriteVersion(w); - FileWriterDetach(w); - } - DoCleanupAndExit(EXIT_SUCCESS); - - case 'h': - { - Writer *w = FileWriter(stdout); - WriterWriteHelp(w, &COMPONENT, OPTIONS, HINTS, NULL, false, true); - FileWriterDetach(w); - } - DoCleanupAndExit(EXIT_SUCCESS); - - case 'M': - { - Writer *out = FileWriter(stdout); - ManPageWrite(out, "cf-watchd", time(NULL), - CF_WATCHD_SHORT_DESCRIPTION, - CF_WATCHD_MANPAGE_LONG_DESCRIPTION, - OPTIONS, HINTS, - NULL, false, - true); - FileWriterDetach(out); - DoCleanupAndExit(EXIT_SUCCESS); - } - - case 'C': - if (!GenericAgentConfigParseColor(config, optarg)) - { - DoCleanupAndExit(EXIT_FAILURE); - } - break; - - case 'l': - LoggingEnableTimestamps(true); - break; - - /* long options only */ - case 0: - { - const char *const option_name = OPTIONS[longopt_idx].name; - if (StringEqual(option_name, "ignore-preferred-augments")) - { - config->ignore_preferred_augments = true; - } - break; - } - - default: - { - Writer *w = FileWriter(stdout); - WriterWriteHelp(w, &COMPONENT, OPTIONS, HINTS, NULL, false, true); - FileWriterDetach(w); - } - DoCleanupAndExit(EXIT_FAILURE); - } - } - - if (!GenericAgentConfigParseArguments(config, argc - optind, argv + optind)) - { - Log(LOG_LEVEL_ERR, "Too many arguments"); - DoCleanupAndExit(EXIT_FAILURE); - } - - return config; -} - -static void WatchStart() -{ - for (int i = 0; !IsPendingTermination(); i++) - { - /* Do something */ - Log(LOG_LEVEL_INFO, "cf-watchd: %d", i); - sleep(1); - } -} diff --git a/configure.ac b/configure.ac index 1663bbdb94a..bb7aea7f6fd 100644 --- a/configure.ac +++ b/configure.ac @@ -2019,7 +2019,6 @@ AC_CONFIG_FILES([Makefile cf-testd/Makefile cf-net/Makefile cf-secret/Makefile - cf-watchd/Makefile cf-reactor/Makefile config.post.h contrib/vagrant-ci/centos-9s-x64/Makefile diff --git a/contrib/nix/cf-agent b/contrib/nix/cf-agent new file mode 100644 index 00000000000..c072e5f87f4 --- /dev/null +++ b/contrib/nix/cf-agent @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +set -e +WORKDIR=/tmp/cfengine-test-workdir +mkdir -p "$WORKDIR/bin" +cp ./result/bin/* "$WORKDIR/bin/" +sudo CFENGINE_TEST_OVERRIDE_WORKDIR="$WORKDIR" ./result/bin/cf-agent "$@" diff --git a/contrib/nix/core.nix b/contrib/nix/core.nix new file mode 100644 index 00000000000..89fb5eec284 --- /dev/null +++ b/contrib/nix/core.nix @@ -0,0 +1,75 @@ +{ stdenv +, version +, is-enterprise +, is-hub +, lib +, pkg-config +, autoreconfHook +, bison +, flex +, diffutils +, coreutils +, acl +, attr +, curl +, libxml2 +, libyaml +, lmdb +, openssl +, pcre2 +, zlib +, librsync +, pam +, perl +, shadow +}: + +stdenv.mkDerivation { + pname = "cfengine"; + version = version; + src = ../../.; + + postPatch = '' + echo "${version}" > CFVERSION + ''; + + preBuild = '' + patchShebangs . + ''; + + nativeBuildInputs = [ + pkg-config + autoreconfHook + bison + flex + diffutils + perl + shadow + ]; + + buildInputs = [ + acl + attr + curl + libxml2 + libyaml + lmdb + openssl + pcre2 + zlib + pam + librsync + ]; + + enableParallelBuilding = true; + + configureFlags = [ + "--with-lmdb" + "--enable-debug" + ]; + + postInstall = '' + cp ${coreutils}/bin/date $out/bin/date + cp ${diffutils}/bin/diff $out/bin/diffutils + ''; +} diff --git a/contrib/nix/flake.lock b/contrib/nix/flake.lock new file mode 100644 index 00000000000..4028206977f --- /dev/null +++ b/contrib/nix/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1788179007, + "narHash": "sha256-hn1oU2rue2SYK8dAr8+WNZWtbsz1S2W5mnHlSEuh3bo=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "34ab99075ac4f7e40cf037eef32cb1c360bb85e9", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/contrib/nix/flake.nix b/contrib/nix/flake.nix new file mode 100644 index 00000000000..53f6e8d8c72 --- /dev/null +++ b/contrib/nix/flake.nix @@ -0,0 +1,33 @@ +{ + description = "A multi-platform dev shell using flake-utils"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + self.submodules = true; + }; + + outputs = { self, nixpkgs, flake-utils }: + flake-utils.lib.eachDefaultSystem (system: + let + pkgs = nixpkgs.legacyPackages.${system}; + lib = pkgs.lib; + + baseVersion = lib.strings.trim (builtins.readFile ./../../.CFVERSION); + + shortSha = + if self ? rev then builtins.substring 0 9 self.rev + else if self ? dirtyRev then builtins.substring 0 9 self.dirtyRev + else "unknown0"; + + version = "${baseVersion}a.${shortSha}"; + in + { + packages = { + community-agent = pkgs.callPackage ./core.nix { version = version; is-enterprise = false; is-hub = false; }; + enterprise-agent = pkgs.callPackage ./core.nix { version = version; is-enterprise = true; is-hub = false; }; + enterprise-hub = pkgs.callPackage ./core.nix { version = version; is-enterprise = true; is-hub = true; }; + }; + } + ); +} diff --git a/libpromises/Makefile.am b/libpromises/Makefile.am index 48c21a6635d..6411946f666 100644 --- a/libpromises/Makefile.am +++ b/libpromises/Makefile.am @@ -134,7 +134,6 @@ libpromises_la_SOURCES = \ mod_storage.c mod_storage.h \ mod_knowledge.c mod_knowledge.h \ mod_users.c mod_users.h \ - mod_watch.c mod_watch.h \ mod_reactor.c mod_reactor.h \ modes.c \ monitoring_read.c monitoring_read.h \ diff --git a/libpromises/cf3.defs.h b/libpromises/cf3.defs.h index 2e1b3777636..3c90859fe6a 100644 --- a/libpromises/cf3.defs.h +++ b/libpromises/cf3.defs.h @@ -398,7 +398,6 @@ typedef enum #define CF_RUNC "runagent" #define CF_KEYGEN "keygenerator" #define CF_HUBC "hub" -#define CF_WATCHC "watch" #define CF_REACTORC "reactor" typedef enum @@ -411,7 +410,6 @@ typedef enum AGENT_TYPE_RUNAGENT, AGENT_TYPE_KEYGEN, AGENT_TYPE_HUB, - AGENT_TYPE_WATCH, AGENT_TYPE_REACTOR, AGENT_TYPE_NOAGENT } AgentType; diff --git a/libpromises/constants.c b/libpromises/constants.c index f5abd754322..e7dd3cab4e1 100644 --- a/libpromises/constants.c +++ b/libpromises/constants.c @@ -72,7 +72,6 @@ const char *const CF_AGENTTYPES[] = /* see enum cfagenttype */ CF_RUNC, CF_KEYGEN, CF_HUBC, - CF_WATCHC, CF_REACTORC, "", }; diff --git a/libpromises/mod_common.c b/libpromises/mod_common.c index 34128775314..b3ce69ae73a 100644 --- a/libpromises/mod_common.c +++ b/libpromises/mod_common.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include @@ -551,7 +550,6 @@ const PromiseTypeSyntax *const CF_ALL_PROMISE_TYPES[] = CF_MEASUREMENT_PROMISE_TYPES, /* mod_measurement.c */ CF_KNOWLEDGE_PROMISE_TYPES, /* mod_knowledge.c */ CF_USERS_PROMISE_TYPES, /* mod_users.c */ - CF_WATCH_PROMISE_TYPES, /* mod_watch.c */ CF_REACTOR_PROMISE_TYPES /* mod_reactor.c */ }; diff --git a/libpromises/mod_watch.c b/libpromises/mod_watch.c deleted file mode 100644 index ac659dcd588..00000000000 --- a/libpromises/mod_watch.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - Copyright 2026 Northern.tech AS - - This file is part of CFEngine 3 - written and maintained by Northern.tech AS. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; version 3. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - - To the extent this program is licensed as part of the Enterprise - versions of CFEngine, the applicable Commercial Open Source License - (COSL) may apply to this file if you as a licensee so wish it. See - included file COSL.txt. -*/ - -#include - -#include - -static const ConstraintSyntax when_constraints[] = -{ - CONSTRAINT_SYNTAX_GLOBAL, - - /* Row models */ - ConstraintSyntaxNewStringList("files_deleted", CF_ANYSTRING, "List of files to watch for deletion", SYNTAX_STATUS_NORMAL), - ConstraintSyntaxNewNull() -}; - -static const BodySyntax when_body = BodySyntaxNew("when", when_constraints, NULL, SYNTAX_STATUS_NORMAL); - -static const ConstraintSyntax CF_EVENT_BODIES[] = -{ - ConstraintSyntaxNewBody("when", &when_body, "Event to watch", SYNTAX_STATUS_NORMAL), - ConstraintSyntaxNewBundle("then", "Bundle to run on event", SYNTAX_STATUS_NORMAL), - ConstraintSyntaxNewNull() -}; - -const PromiseTypeSyntax CF_WATCH_PROMISE_TYPES[] = -{ - PromiseTypeSyntaxNew("watch", "events", CF_EVENT_BODIES, NULL, SYNTAX_STATUS_NORMAL), - PromiseTypeSyntaxNewNull() -}; diff --git a/libpromises/mod_watch.h b/libpromises/mod_watch.h deleted file mode 100644 index 2ba6b3a9224..00000000000 --- a/libpromises/mod_watch.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - Copyright 2026 Northern.tech AS - - This file is part of CFEngine 3 - written and maintained by Northern.tech AS. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; version 3. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - - To the extent this program is licensed as part of the Enterprise - versions of CFEngine, the applicable Commercial Open Source License - (COSL) may apply to this file if you as a licensee so wish it. See - included file COSL.txt. -*/ - -#ifndef CFENGINE_MOD_WATCH_H -#define CFENGINE_MOD_WATCH_H - -#include - -extern const PromiseTypeSyntax CF_WATCH_PROMISE_TYPES[]; - -#endif diff --git a/tests/acceptance/32_cf-watchd/syntax.cf b/tests/acceptance/32_cf-watchd/syntax.cf deleted file mode 100644 index d7adbff1517..00000000000 --- a/tests/acceptance/32_cf-watchd/syntax.cf +++ /dev/null @@ -1,28 +0,0 @@ -bundle agent main -{ - reports: - "$(this.promise_filename) Pass"; -} - -body when file_deleted(filename) -{ - files_deleted => { "$(filename)" }; -} - -bundle agent create_file(filename) -{ - files: - "$(filename)" create => "true"; -} - -bundle watch event_handler -{ - events: - "Create /tmp/a" - when => file_deleted("/tmp/a"), - then => create_file("/tmp/a"); - - "Create /tmp/b" - when => file_deleted("/tmp/b"), - then => create_file("/tmp/b"); -}