            "#\n"
            "#  Copyright (C) CFEngine AS\n"
            "#\n"
            "#  This file is part of CFEngine 3 - written and maintained by CFEngine AS.\n"
            "#\n"
            "#  This program is free software; you can redistribute it and/or modify it\n"
            "#  under the terms of the GNU General Public License as published by the\n"
            "#  Free Software Foundation; version 3.\n"
            "#\n"
            "#  This program is distributed in the hope that it will be useful,\n"
            "#  but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
            "#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
            "#  GNU General Public License for more details.\n"
            "#\n"
            "# You should have received a copy of the GNU General Public License\n"
            "# along with this program; if not, write to the Free Software\n"
            "# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA\n"
            "#\n"
            "# To the extent this program is licensed as part of the Enterprise\n"
            "# versions of CFEngine, the applicable Commercial Open Source License\n"
            "# (COSL) may apply to this file if you as a licensee so wish it. See\n"
            "# included file COSL.txt.\n"
            "\n"
            "########## CFEngine Bootstrap / Failsafe Policy ##############################\n"
            "# This file (failsafe.cf) is re-generated inside \"inputs\" directory every time\n"
            "# you bootstrap. This means that custom changes will be overwritten.\n"
            "#\n"
            "# The role of this standalone policy file is to fetch the main promises from\n"
            "# the policy hub for the first time when bootstrapping, and to recover the\n"
            "# system by fetching policies in case the standard agent run fails.\n"
            "##############################################################################\n"
            "\n"
            "\n"
            "body common control\n"
            "{\n"
            "      bundlesequence => {\n"
            "                          \"failsafe_cfe_internal_checkkeys\",\n"
            "                          \"failsafe_cfe_internal_update\",\n"
            "                          \"failsafe_cfe_internal_call_update\"\n"
            "                        };\n"
            "}\n"
            "\n"
            "body agent control\n"
            "{\n"
            "      skipidentify => \"true\";\n"
            "\n"
            "      # Bootstrapping can't continue without keys\n"
            "      abortclasses => { \"no_ppkeys_ABORT\" };\n"
            "}\n"
            "\n"
            "################################################################################\n"
            "\n"
            "bundle agent failsafe_cfe_internal_checkkeys\n"
            "{\n"
            "  classes:\n"
            "      \"have_ppkeys\"\n"
            "        expression => fileexists(\"$(sys.workdir)/ppkeys/localhost.pub\"),\n"
            "        handle     => \"failsafe_cfe_internal_bootstrap_checkkeys_classes_have_ppkeys\";\n"
            "\n"
            "  reports:\n"
            "    !have_ppkeys::\n"
            "      \"No public/private key pair is loaded, please create one by running \\\"cf-key\\\"\"\n"
            "        classes => failsafe_kept(\"no_ppkeys_ABORT\");\n"
            "}\n"
            "\n"
            "################################################################################\n"
            "\n"
            "bundle agent failsafe_cfe_internal_update\n"
            "{\n"
            "  vars:\n"
            "\n"
            "    policy_server::\n"
            "\n"
            "      # policy server cannot use shortcut feature to resolve masterfiles since cf-serverd is not yet up\n"
            "      \"masterfiles_dir_remote\" string => \"$(sys.masterdir)\";\n"
            "\n"
            "    !policy_server::\n"
            "\n"
            "      \"masterfiles_dir_remote\" string => \"masterfiles\";\n"
            "\n"
            "\n"
            "  classes:\n"
            "\n"
            "    any::\n"
            "\n"
            "      \"have_promises_cf\"\n"
            "      expression => fileexists(\"$(sys.inputdir)/promises.cf\"),\n"
            "      handle => \"failsafe_cfe_internal_bootstrap_update_classes_have_promises_cf\";\n"
            "\n"
            "\n"
            "  files:\n"
            "\n"
            "      \"$(sys.inputdir)\"\n"
            "      handle => \"failsafe_cfe_internal_bootstrap_update_files_sys_workdir_inputs_shortcut\",\n"
            "      copy_from => failsafe_scp(\"$(masterfiles_dir_remote)\"),\n"
            "      depth_search => failsafe_recurse(\"inf\"),\n"
            "      classes => failsafe_repaired(\"got_policy\");\n"
            "\n"
            "    !windows.got_policy_failed::\n"
            "\n"
            "      \"$(sys.inputdir)\"\n"
            "      handle => \"failsafe_cfe_internal_bootstrap_update_files_sys_workdir_inputs_not_windows\",\n"
            "      copy_from => failsafe_scp(\"$(sys.masterdir)\"),\n"
            "      depth_search => failsafe_recurse(\"inf\"),\n"
            "      classes => failsafe_repaired(\"got_policy\");\n"
            "\n"
            "    windows.got_policy_failed::\n"
            "\n"
            "      \"$(sys.inputdir)\"\n"
            "      handle => \"failsafe_cfe_internal_bootstrap_update_files_sys_workdir_inputs_windows\",\n"
            "      copy_from => failsafe_scp(\"/var/cfengine/masterfiles\"), # Not $(sys.masterdir) when referring to remote host.\n"
            "      depth_search => failsafe_recurse(\"inf\"),\n"
            "      classes => failsafe_repaired(\"got_policy\");\n"
            "\n"
            "    windows::\n"
            "\n"
            "      \"$(sys.workdir)\\\\bin-twin\\\\.\"\n"
            "      handle => \"failsafe_cfe_internal_bootstrap_update_files_sys_workdir_bin_twin_windows\",\n"
            "      comment => \"Make sure we maintain a clone of the binaries and libraries for updating\",\n"
            "      copy_from => failsafe_cp(\"$(sys.workdir)\\\\bin\\\\.\"),\n"
            "      depth_search => failsafe_recurse(\"1\");\n"
            "\n"
            "\n"
            "  processes:\n"
            "\n"
            "    !windows.got_policy::\n"
            "\n"
            "      \"cf-execd\" restart_class => \"start_exec\",\n"
            "      handle => \"failsafe_cfe_internal_bootstrap_update_processes_start_cf_execd\";\n"
            "\n"
            "    am_policy_hub.got_policy::\n"
            "\n"
            "      \"cf-serverd\" restart_class => \"start_server\",\n"
            "      handle => \"failsafe_cfe_internal_bootstrap_update_processes_start_cf_serverd\";\n"
            "\n"
            "\n"
            "  commands:\n"
            "\n"
            "    start_exec.!windows.!systemd::\n"
            "\n"
            "      \"$(sys.cf_execd)\"\n"
            "      handle => \"failsafe_cfe_internal_bootstrap_update_commands_check_sys_cf_execd_start\",\n"
            "      classes => failsafe_repaired(\"executor_started\");\n"
            "\n"
            "    start_server.!systemd::\n"
            "\n"
            "      \"$(sys.cf_serverd)\"\n"
            "      handle => \"failsafe_cfe_internal_bootstrap_update_commands_check_sys_cf_serverd_start\",\n"
            "      action => failsafe_ifwin_bg,\n"
            "      classes => failsafe_repaired(\"server_started\");\n"
            "\n"
            "    start_exec.systemd::\n"
            "\n"
            "      # We explicitly use \"restart\", because it is possible that cf-serverd\n"
            "      # is running, even if cf-execd isn't, for example. Here we want to be\n"
            "      # sure we relaunch everything.\n"
            "\n"
            "      \"/bin/systemctl restart cfengine3\"\n"
            "      handle => \"failsafe_cfe_internal_bootstrap_update_commands_systemd_cfe_start\",\n"
            "      classes => failsafe_repaired_two(\"executor_started\", \"server_started\");\n"
            "\n"
            "\n"
            "  services:\n"
            "\n"
            "    windows.got_policy::\n"
            "\n"
            "      \"CfengineNovaExec\"\n"
            "      handle => \"failsafe_cfe_internal_bootstrap_update_services_windows_executor\",\n"
            "      service_policy => \"start\",\n"
            "      service_method => failsafe_bootstart,\n"
            "      classes => failsafe_repaired(\"executor_started\");\n"
            "\n"
            "\n"
            "  reports:\n"
            "\n"
            "    !bootstrap_mode::\n"
            "      \"Built-in failsafe policy triggered\"\n"
            "        handle => \"failsafe_cfe_internal_bootstrap_update_reports_failsafe_notification\",\n"
            "        comment => \"Be sure to inform the user that the failsafe policy has\n"
            "                    been triggered. This typically indicates that the agent has\n"
            "                    received broken policy. It may also indicate legacy\n"
            "                    configuration in body executor control.\";\n"
            "\n"
            "    bootstrap_mode::\n"
            "      \"Bootstrapping from host '$(sys.policy_hub)' via built-in policy '$(this.promise_filename)'\"\n"
            "        handle => \"failsafe_cfe_internal_bootstrap_update_reports_bootstrap_notification\",\n"
            "        comment => \"Be sure to inform the user that they have triggerd a bootstrap.\";\n"
            "\n"
            "    bootstrap_mode.am_policy_hub::\n"
            "\n"
            "      \"This host assumes the role of policy server\"\n"
            "      handle => \"failsafe_cfe_internal_bootstrap_update_reports_assume_policy_hub\";\n"
            "\n"
            "    bootstrap_mode.!am_policy_hub::\n"
            "\n"
            "      \"This autonomous node assumes the role of voluntary client\"\n"
            "      handle => \"failsafe_cfe_internal_bootstrap_update_reports_assume_voluntary_client\";\n"
            "\n"
            "    got_policy::\n"
            "\n"
            "      \"Updated local policy from policy server\"\n"
            "      handle => \"failsafe_cfe_internal_bootstrap_update_reports_got_policy\";\n"
            "\n"
            "    !got_policy.!have_promises_cf::\n"
            "\n"
            "      \"Failed to copy policy from policy server at $(sys.policy_hub):$(sys.masterdir)\n"
            "       Please check\n"
            "       * cf-serverd is running on $(sys.policy_hub)\n"
            "       * CFEngine version on the policy hub is 3.6.0 or latest - otherwise you need to tweak the protocol_version setting\n"
            "       * network connectivity to $(sys.policy_hub) on port 5308\n"
            "       * masterfiles 'body server control' - in particular allowconnects, trustkeysfrom and skipverify\n"
            "       * masterfiles 'bundle server' -> access: -> masterfiles -> admit/deny\n"
            "       It is often useful to restart cf-serverd in verbose mode (cf-serverd -v) on $(sys.policy_hub) to diagnose connection issues.\n"
            "       When updating masterfiles, wait (usually 5 minutes) for files to propagate to inputs on $(sys.policy_hub) before retrying.\"\n"
            "      handle => \"failsafe_cfe_internal_bootstrap_update_reports_did_not_get_policy\";\n"
            "\n"
            "    server_started::\n"
            "\n"
            "      \"Started the server\"\n"
            "      handle => \"failsafe_cfe_internal_bootstrap_update_reports_started_serverd\";\n"
            "\n"
            "    am_policy_hub.!server_started.!have_promises_cf::\n"
            "\n"
            "      \"Failed to start the server\"\n"
            "      handle => \"failsafe_cfe_internal_bootstrap_update_reports_failed_to_start_serverd\";\n"
            "\n"
            "    executor_started::\n"
            "\n"
            "      \"Started the scheduler\"\n"
            "      handle => \"failsafe_cfe_internal_bootstrap_update_reports_started_execd\";\n"
            "\n"
            "    !executor_started.!have_promises_cf::\n"
            "\n"
            "      \"Did not start the scheduler\"\n"
            "      handle => \"failsafe_cfe_internal_bootstrap_update_reports_failed_to_start_execd\";\n"
            "\n"
            "}\n"
            "\n"
            "################################################################################\n"
            "bundle agent failsafe_cfe_internal_call_update\n"
            "{\n"
            "  vars:\n"
            "\n"
            "    \"mode\" string => ifelse(\"bootstrap_mode\", \"bootstrap_mode\", \"failsafe_mode\");\n"
            "\n"
            "  commands:\n"
            "\n"
            "    # On Windows we need cf-execd to call update.cf, otherwise the daemons will\n"
            "    # not run under the SYSTEM account.\n"
            "    !windows::\n"
            "      \"$(sys.cf_agent) -f $(sys.update_policy_path) --define $(mode)\"\n"
            "        handle => \"failsafe_cfe_internal_call_update_commands_call_update_cf\",\n"
            "        if => fileexists( $(sys.update_policy_path) ),\n"
            "        comment => \"We run update.cf in order to prepare system information for\n"
            "                    collection into CFEngine Enterprise more quickly.\";\n"
            "\n"
            "}\n"
            "############################################\n"
            "body classes failsafe_kept(x)\n"
            "{\n"
            "      promise_kept => {\"$(x)\"};\n"
            "}\n"
            "############################################\n"
            "body classes failsafe_repaired(x)\n"
            "{\n"
            "      promise_repaired => {\"$(x)\"};\n"
            "      repair_failed => {\"$(x)_failed\"};\n"
            "}\n"
            "############################################\n"
            "body classes failsafe_repaired_two(x,y)\n"
            "{\n"
            "      promise_repaired => {\"$(x)\", \"$(y)\"};\n"
            "      repair_failed => {\"$(x)_failed\"};\n"
            "}\n"
            "############################################\n"
            "body perms failsafe_p(p)\n"
            "{\n"
            "      mode  => \"$(p)\";\n"
            "}\n"
            "#############################################\n"
            "body copy_from failsafe_scp(from)\n"
            "{\n"
            "      source      => \"$(from)\";\n"
            "      compare     => \"digest\";\n"
            "    # This class is always set when bootstrapping. You can deactivate\n"
            "    # this class with --trust-server=no when bootstrapping\n"
            "    trust_server::\n"
            "      trustkey    => \"true\";\n"
            "    !am_policy_hub::\n"
            "      servers => { \"$(sys.policy_hub)\" };\n"
            "}\n"
            "############################################\n"
            "body action failsafe_background\n"
            "{\n"
            "      background => \"true\";\n"
            "}\n"
            "############################################\n"
            "body depth_search failsafe_recurse(d)\n"
            "{\n"
            "      depth => \"$(d)\";\n"
            "      exclude_dirs => { \"\\.svn\", \"\\.git\" };\n"
            "}\n"
            "############################################\n"
            "body service_method failsafe_bootstart\n"
            "{\n"
            "      service_autostart_policy => \"boot_time\";\n"
            "}\n"
            "############################################\n"
            "body action failsafe_ifwin_bg\n"
            "{\n"
            "    windows::\n"
            "      background => \"true\";\n"
            "}\n"
            "############################################\n"
            "body copy_from failsafe_cp(from)\n"
            "{\n"
            "      source          => \"$(from)\";\n"
            "      compare         => \"digest\";\n"
            "      copy_backup     => \"false\";\n"
            "}\n"
