diff --git a/cmd/client_node_schedule_create.go b/cmd/client_node_schedule_create.go index 9e6db1809..4c0bf2712 100644 --- a/cmd/client_node_schedule_create.go +++ b/cmd/client_node_schedule_create.go @@ -29,10 +29,10 @@ import ( "github.com/osapi-io/osapi/pkg/sdk/client" ) -// clientNodeScheduleCreateCmd represents the cron create command. +// clientNodeScheduleCreateCmd represents the schedule create command. var clientNodeScheduleCreateCmd = &cobra.Command{ Use: "create", - Short: "Create a cron entry", + Short: "Create a scheduled entry", Run: func(cmd *cobra.Command, _ []string) { ctx := cmd.Context() host, _ := cmd.Flags().GetString("target") @@ -92,7 +92,7 @@ func init() { clientNodeScheduleCmd.AddCommand(clientNodeScheduleCreateCmd) clientNodeScheduleCreateCmd.PersistentFlags(). - String("name", "", "Name for the cron drop-in entry (required)") + String("name", "", "Name for the scheduled entry (required)") clientNodeScheduleCreateCmd.PersistentFlags(). String("object", "", "Name of the uploaded file in the object store (required)") clientNodeScheduleCreateCmd.PersistentFlags(). diff --git a/cmd/client_node_schedule_delete.go b/cmd/client_node_schedule_delete.go index 428a0c9e8..d614ff4ac 100644 --- a/cmd/client_node_schedule_delete.go +++ b/cmd/client_node_schedule_delete.go @@ -28,10 +28,10 @@ import ( "github.com/osapi-io/osapi/internal/cli" ) -// clientNodeScheduleDeleteCmd represents the cron delete command. +// clientNodeScheduleDeleteCmd represents the schedule delete command. var clientNodeScheduleDeleteCmd = &cobra.Command{ Use: "delete", - Short: "Delete a cron entry", + Short: "Delete a scheduled entry", Run: func(cmd *cobra.Command, _ []string) { ctx := cmd.Context() host, _ := cmd.Flags().GetString("target") @@ -79,7 +79,7 @@ func init() { clientNodeScheduleCmd.AddCommand(clientNodeScheduleDeleteCmd) clientNodeScheduleDeleteCmd.PersistentFlags(). - String("name", "", "Name of the cron entry to delete (required)") + String("name", "", "Name of the scheduled entry to delete (required)") _ = clientNodeScheduleDeleteCmd.MarkPersistentFlagRequired("name") } diff --git a/cmd/client_node_schedule_get.go b/cmd/client_node_schedule_get.go index f0a250614..738feadd0 100644 --- a/cmd/client_node_schedule_get.go +++ b/cmd/client_node_schedule_get.go @@ -28,10 +28,10 @@ import ( "github.com/osapi-io/osapi/internal/cli" ) -// clientNodeScheduleGetCmd represents the cron get command. +// clientNodeScheduleGetCmd represents the schedule get command. var clientNodeScheduleGetCmd = &cobra.Command{ Use: "get", - Short: "Get a cron entry by name", + Short: "Get a scheduled entry by name", Run: func(cmd *cobra.Command, _ []string) { ctx := cmd.Context() host, _ := cmd.Flags().GetString("target") @@ -79,7 +79,7 @@ func init() { clientNodeScheduleCmd.AddCommand(clientNodeScheduleGetCmd) clientNodeScheduleGetCmd.PersistentFlags(). - String("name", "", "Name of the cron entry (required)") + String("name", "", "Name of the scheduled entry (required)") _ = clientNodeScheduleGetCmd.MarkPersistentFlagRequired("name") } diff --git a/cmd/client_node_schedule_list.go b/cmd/client_node_schedule_list.go index 25c6d6ce4..784e58364 100644 --- a/cmd/client_node_schedule_list.go +++ b/cmd/client_node_schedule_list.go @@ -28,10 +28,10 @@ import ( "github.com/osapi-io/osapi/internal/cli" ) -// clientNodeScheduleListCmd represents the cron list command. +// clientNodeScheduleListCmd represents the schedule list command. var clientNodeScheduleListCmd = &cobra.Command{ Use: "list", - Short: "List all cron entries", + Short: "List all scheduled entries", Run: func(cmd *cobra.Command, _ []string) { ctx := cmd.Context() host, _ := cmd.Flags().GetString("target") diff --git a/cmd/client_node_schedule_update.go b/cmd/client_node_schedule_update.go index 3eb0ab7cd..d411110d5 100644 --- a/cmd/client_node_schedule_update.go +++ b/cmd/client_node_schedule_update.go @@ -29,10 +29,10 @@ import ( "github.com/osapi-io/osapi/pkg/sdk/client" ) -// clientNodeScheduleUpdateCmd represents the cron update command. +// clientNodeScheduleUpdateCmd represents the schedule update command. var clientNodeScheduleUpdateCmd = &cobra.Command{ Use: "update", - Short: "Update a cron entry", + Short: "Update a scheduled entry", Run: func(cmd *cobra.Command, _ []string) { ctx := cmd.Context() host, _ := cmd.Flags().GetString("target") @@ -89,7 +89,7 @@ func init() { clientNodeScheduleCmd.AddCommand(clientNodeScheduleUpdateCmd) clientNodeScheduleUpdateCmd.PersistentFlags(). - String("name", "", "Name of the cron entry to update (required)") + String("name", "", "Name of the scheduled entry to update (required)") clientNodeScheduleUpdateCmd.PersistentFlags(). String("object", "", "New object to deploy") clientNodeScheduleUpdateCmd.PersistentFlags(). diff --git a/docs/docs/sidebar/features/schedule-management.md b/docs/docs/sidebar/features/schedule-management.md index a692b45b2..5b4374a82 100644 --- a/docs/docs/sidebar/features/schedule-management.md +++ b/docs/docs/sidebar/features/schedule-management.md @@ -4,7 +4,8 @@ sidebar_position: 9 # Schedule Management -OSAPI manages cron entries on target hosts. It supports two placement modes: +OSAPI manages scheduled entries on target hosts. It supports two placement +modes: - **Custom schedule** — writes to `/etc/cron.d/{name}` with a 5-field cron expression @@ -12,17 +13,17 @@ OSAPI manages cron entries on target hosts. It supports two placement modes: as executable scripts Scheduled entries reference scripts stored in the NATS Object Store by name. -Upload a script first with the file management commands, then create a cron -entry pointing at it. This separates script content from scheduling -configuration and enables versioned updates. +Upload a script first with the file management commands, then create an entry +pointing at it. This separates script content from scheduling configuration and +enables versioned updates. ## How It Works ### Object-Based Workflow The cron provider is a **meta provider**: it does not embed script content -directly. Instead, each cron entry holds an `object` name that references a file -in the NATS Object Store. When the agent deploys or updates a cron entry, it: +directly. Instead, each entry holds an `object` name that references a file in +the NATS Object Store. When the agent deploys or updates an entry, it: 1. Fetches the named object from the Object Store. 2. Writes the script content to the appropriate path under `/etc/cron.d/` or @@ -74,7 +75,7 @@ deployed file as a header comment. This means: marker. - The list and get operations query the file-state KV to discover managed entries; manually created files are left untouched. -- State persists in the KV until explicitly removed — deleting a cron entry +- State persists in the KV until explicitly removed — deleting an entry undeploys the file from disk but preserves the file-state record. ### Template Support @@ -102,9 +103,9 @@ Template variables are merged with the agent's system facts and hostname. See | Operation | Description | | --------- | -------------------------------------- | -| List | List all osapi-managed cron entries | +| List | List all osapi-managed entries | | Get | Get a specific entry by name | -| Create | Upload script, then create cron entry | +| Create | Upload script, then create the entry | | Update | Upload new script version, then update | | Delete | Undeploy cron file from disk | @@ -125,7 +126,7 @@ osapi client node schedule create --target web-01 \ --name logrotate --interval daily \ --object logrotate-script -# List all managed cron entries +# List all managed entries osapi client node schedule list --target web-01 # Get a specific entry @@ -158,15 +159,15 @@ Files are created as root (the agent runs as root). Names must not contain dots ## Undeploy Behavior -Deleting a cron entry **undeploys** the file: it is removed from the filesystem, -but the file-state KV record is preserved. This means: +Deleting an entry **undeploys** the file: it is removed from the filesystem, but +the file-state KV record is preserved. This means: - Re-creating the entry with the same name and object will detect the prior state and only write the file if the content differs. - The KV record serves as an audit trail of what was last deployed. To remove the file-state record entirely, delete the corresponding file-state -entry via the file management API after removing the cron entry. +entry via the file management API after removing the scheduled entry. ## Supported Platforms diff --git a/docs/docs/sidebar/sdk/client/client.md b/docs/docs/sidebar/sdk/client/client.md index 70d44ba38..7d7059ba1 100644 --- a/docs/docs/sidebar/sdk/client/client.md +++ b/docs/docs/sidebar/sdk/client/client.md @@ -19,10 +19,10 @@ resp, err := client.Hostname.Get(ctx, "_any") ## Services -| Service | Description | -| ------------------------------ | ---------------------------- | -| [Service](services/service.md) | Service management (systemd) | -| [Cron](services/schedule.md) | Cron schedule management | +| Service | Description | +| -------------------------------- | ---------------------------- | +| [Service](services/service.md) | Service management (systemd) | +| [Schedule](services/schedule.md) | Scheduled entry management | ### Software diff --git a/docs/docs/sidebar/sdk/client/services/schedule.md b/docs/docs/sidebar/sdk/client/services/schedule.md index 11574b082..b89ffb6b4 100644 --- a/docs/docs/sidebar/sdk/client/services/schedule.md +++ b/docs/docs/sidebar/sdk/client/services/schedule.md @@ -2,10 +2,11 @@ sidebar_position: 2 --- -# Cron +# Schedule -The `Cron` service provides methods for managing cron drop-in files on target -hosts. Access via `client.Cron.List()`, `client.Cron.Create()`, etc. +The `Schedule` service provides methods for managing scheduled entries on target +hosts. On Debian family hosts these are cron drop-in files. Access via +`client.Schedule.List()`, `client.Schedule.Create()`, etc. ## Methods @@ -19,11 +20,11 @@ hosts. Access via `client.Cron.List()`, `client.Cron.Create()`, etc. ## Request Types -| Type | Fields | -| ---------------- | --------------------------------------------------------------- | -| `CronCreateOpts` | Name, Object, Schedule\*, Interval\*, User, ContentType, Vars | -| | (\* Schedule and Interval are mutually exclusive; one required) | -| `CronUpdateOpts` | Object, Schedule, User, ContentType, Vars (all optional) | +| Type | Fields | +| -------------------- | --------------------------------------------------------------- | +| `ScheduleCreateOpts` | Name, Object, Schedule\*, Interval\*, User, ContentType, Vars | +| | (\* Schedule and Interval are mutually exclusive; one required) | +| `ScheduleUpdateOpts` | Object, Schedule, User, ContentType, Vars (all optional) | ## Usage @@ -32,19 +33,19 @@ import "github.com/osapi-io/osapi/pkg/sdk/client" c := client.New("http://localhost:8080", token) -// List all managed cron entries -resp, err := c.Cron.List(ctx, "web-01") +// List all managed entries +resp, err := c.Schedule.List(ctx, "web-01") for _, entry := range resp.Data.Results { fmt.Printf("%s: %s %s %s\n", entry.Name, entry.Schedule, entry.User, entry.Object) } // Get a specific entry -resp, err := c.Cron.Get(ctx, "web-01", "backup-daily") +resp, err := c.Schedule.Get(ctx, "web-01", "backup-daily") // Create with custom schedule (/etc/cron.d/) // Object references an uploaded file in the Object Store. -resp, err := c.Cron.Create(ctx, "web-01", client.CronCreateOpts{ +resp, err := c.Schedule.Create(ctx, "web-01", client.ScheduleCreateOpts{ Name: "backup-daily", Schedule: "0 2 * * *", Object: "backup-script", @@ -52,14 +53,14 @@ resp, err := c.Cron.Create(ctx, "web-01", client.CronCreateOpts{ }) // Create with interval (/etc/cron.daily/) -resp, err := c.Cron.Create(ctx, "web-01", client.CronCreateOpts{ +resp, err := c.Schedule.Create(ctx, "web-01", client.ScheduleCreateOpts{ Name: "logrotate", Interval: "daily", Object: "logrotate-script", }) // Create with template rendering -resp, err := c.Cron.Create(ctx, "web-01", client.CronCreateOpts{ +resp, err := c.Schedule.Create(ctx, "web-01", client.ScheduleCreateOpts{ Name: "db-backup", Schedule: "0 4 * * *", Object: "db-backup-template", @@ -69,19 +70,19 @@ resp, err := c.Cron.Create(ctx, "web-01", client.CronCreateOpts{ }) // Update the schedule and object -resp, err := c.Cron.Update(ctx, "web-01", "backup-daily", - client.CronUpdateOpts{ +resp, err := c.Schedule.Update(ctx, "web-01", "backup-daily", + client.ScheduleUpdateOpts{ Schedule: "0 3 * * *", Object: "backup-script-v2", }) // Delete an entry -resp, err := c.Cron.Delete(ctx, "web-01", "backup-daily") +resp, err := c.Schedule.Delete(ctx, "web-01", "backup-daily") ``` ## Example -- [`examples/sdk/client/cron.go`](https://github.com/osapi-io/osapi/blob/main/examples/sdk/client/cron.go) +- [`examples/sdk/client/schedule.go`](https://github.com/osapi-io/osapi/blob/main/examples/sdk/client/schedule.go) ## Permissions @@ -90,7 +91,7 @@ resp, err := c.Cron.Delete(ctx, "web-01", "backup-daily") | List, Get | `schedule:read` | | Create, Update, Delete | `schedule:write` | -Cron management is supported on the Debian OS family (Ubuntu, Debian, Raspbian). -On unsupported platforms (Darwin, generic Linux), operations return +Schedule management is supported on the Debian OS family (Ubuntu, Debian, +Raspbian). On unsupported platforms (Darwin, generic Linux), operations return `status: skipped`. See [Platform Detection](../../platform/detection.md) for details. diff --git a/docs/docs/sidebar/usage/cli/client/node/schedule/schedule.md b/docs/docs/sidebar/usage/cli/client/node/schedule/schedule.md index ec7953e68..8ca6b3a93 100644 --- a/docs/docs/sidebar/usage/cli/client/node/schedule/schedule.md +++ b/docs/docs/sidebar/usage/cli/client/node/schedule/schedule.md @@ -23,7 +23,7 @@ $ osapi client node schedule list --target web-01 ## Get -Get a specific cron entry by name: +Get a specific scheduled entry by name: ```bash $ osapi client node schedule get --target web-01 --name backup-daily @@ -36,7 +36,7 @@ $ osapi client node schedule get --target web-01 --name backup-daily ## Create -Upload the script to the Object Store first, then create the cron entry +Upload the script to the Object Store first, then create the scheduled entry referencing it by object name: ```bash @@ -44,7 +44,7 @@ $ osapi client file upload --name backup-script \ --file /usr/local/bin/backup.sh ``` -Then create the cron entry using `--object` to reference the uploaded file: +Then create the entry using `--object` to reference the uploaded file: ```bash $ osapi client node schedule create --target web-01 \ @@ -66,7 +66,7 @@ should be rendered with agent facts before being written to disk. ## Update -Update an existing cron entry: +Update an existing scheduled entry: ```bash $ osapi client node schedule update --target web-01 \ @@ -83,7 +83,7 @@ Only the fields you specify are updated. If nothing changed, `Changed: false`. ## Delete -Delete a cron entry: +Delete a scheduled entry: ```bash $ osapi client node schedule delete --target web-01 --name backup-daily diff --git a/docs/docusaurus.config.ts b/docs/docusaurus.config.ts index 4eb9cd262..5ab56fe42 100644 --- a/docs/docusaurus.config.ts +++ b/docs/docusaurus.config.ts @@ -263,7 +263,7 @@ const config: Config = { }, { type: 'doc', - label: 'Cron', + label: 'Schedule', docId: 'sidebar/sdk/client/services/schedule' }, {