Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
5 changes: 5 additions & 0 deletions cmd/harbor/root/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/goharbor/harbor-cli/cmd/harbor/root/context"
"github.com/goharbor/harbor-cli/cmd/harbor/root/cve"
"github.com/goharbor/harbor-cli/cmd/harbor/root/instance"
"github.com/goharbor/harbor-cli/cmd/harbor/root/jobservice"
"github.com/goharbor/harbor-cli/cmd/harbor/root/labels"
"github.com/goharbor/harbor-cli/cmd/harbor/root/ldap"
"github.com/goharbor/harbor-cli/cmd/harbor/root/project"
Expand Down Expand Up @@ -203,6 +204,10 @@ harbor help
cmd.GroupID = "system"
root.AddCommand(cmd)

cmd = jobservice.JobService()
cmd.GroupID = "system"
root.AddCommand(cmd)

// Utils
cmd = versionCommand()
cmd.GroupID = "utils"
Expand Down
37 changes: 37 additions & 0 deletions cmd/harbor/root/jobservice/cmd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright Project Harbor Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package jobservice

import (
"github.com/goharbor/harbor-cli/cmd/harbor/root/jobservice/schedules"
"github.com/spf13/cobra"
)

// JobService creates the jobservice command
func JobService() *cobra.Command {
cmd := &cobra.Command{
Use: "jobservice",
Short: "Manage Harbor job service (admin only)",
Long: `Manage Harbor job service components including worker pools, job queues, schedules, and job logs.
This requires system admin privileges.

Use "harbor jobservice [command] --help" for detailed examples and flags per subcommand.`,
}

cmd.AddCommand(
schedules.SchedulesCommand(),
)

return cmd
}
34 changes: 34 additions & 0 deletions cmd/harbor/root/jobservice/schedules/cmd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright Project Harbor Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package schedules

import "github.com/spf13/cobra"

// SchedulesCommand creates the schedules subcommand
func SchedulesCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "schedules",
Short: "Manage schedules (list/status/pause-all/resume-all)",
Long: "List schedules and manage global scheduler status.",
}

cmd.AddCommand(
ListCommand(),
StatusCommand(),
PauseAllCommand(),
ResumeAllCommand(),
)

return cmd
}
70 changes: 70 additions & 0 deletions cmd/harbor/root/jobservice/schedules/list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright Project Harbor Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package schedules

import (
"fmt"

"github.com/goharbor/harbor-cli/pkg/api"
"github.com/goharbor/harbor-cli/pkg/utils"
"github.com/goharbor/harbor-cli/pkg/views/jobservice/schedules"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

// ListCommand lists all schedules
func ListCommand() *cobra.Command {
var page int64 = 1
var pageSize int64 = 20

cmd := &cobra.Command{
Use: "list",
Short: "List schedules (supports --page and --page-size)",
Long: "Display all job schedules with pagination support.",
Example: "harbor jobservice schedules list --page 1 --page-size 20",
RunE: func(cmd *cobra.Command, args []string) error {
if page < 1 {
return fmt.Errorf("page must be >= 1")
}
if pageSize < 1 || pageSize > 100 {
return fmt.Errorf("page-size must be between 1 and 100")
}

response, err := api.ListSchedules(page, pageSize)
if err != nil {
return formatScheduleError("failed to retrieve schedules", err, "ActionList")
}

if response == nil || response.Payload == nil || len(response.Payload) == 0 {
fmt.Println("No schedules found.")
return nil
}

formatFlag := viper.GetString("output-format")
if formatFlag != "" {
return utils.PrintFormat(response.Payload, formatFlag)
}

totalCount := response.XTotalCount
schedules.ListSchedules(response.Payload, page, pageSize, totalCount)
return nil
},
}

flags := cmd.Flags()
flags.Int64Var(&page, "page", 1, "Page number")
flags.Int64Var(&pageSize, "page-size", 20, "Number of items per page")

return cmd
}
42 changes: 42 additions & 0 deletions cmd/harbor/root/jobservice/schedules/pause_all.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright Project Harbor Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package schedules

import (
"fmt"

"github.com/goharbor/harbor-cli/pkg/api"
"github.com/spf13/cobra"
)

// PauseAllCommand pauses all schedules
func PauseAllCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "pause-all",
Short: "Pause all schedules",
Long: "Pause the global scheduler and all schedules.",
Example: "harbor jobservice schedules pause-all",
RunE: func(cmd *cobra.Command, args []string) error {
fmt.Println("Pausing all schedules...")
err := api.ActionJobQueue("SCHEDULER", "pause")
if err != nil {
return formatScheduleError("failed to pause all schedules", err, "ActionStop")
}
fmt.Println("✓ All schedules paused successfully.")
return nil
},
}

return cmd
}
42 changes: 42 additions & 0 deletions cmd/harbor/root/jobservice/schedules/resume_all.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright Project Harbor Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package schedules

import (
"fmt"

"github.com/goharbor/harbor-cli/pkg/api"
"github.com/spf13/cobra"
)

// ResumeAllCommand resumes all schedules
func ResumeAllCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "resume-all",
Short: "Resume all schedules",
Long: "Resume the global scheduler and all schedules.",
Example: "harbor jobservice schedules resume-all",
RunE: func(cmd *cobra.Command, args []string) error {
fmt.Println("Resuming all schedules...")
err := api.ActionJobQueue("SCHEDULER", "resume")
if err != nil {
return formatScheduleError("failed to resume all schedules", err, "ActionStop")
}
fmt.Println("✓ All schedules resumed successfully.")
return nil
},
}

return cmd
}
55 changes: 55 additions & 0 deletions cmd/harbor/root/jobservice/schedules/status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright Project Harbor Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package schedules

import (
"fmt"

"github.com/goharbor/harbor-cli/pkg/api"
"github.com/goharbor/harbor-cli/pkg/utils"
"github.com/goharbor/harbor-cli/pkg/views/jobservice/schedules"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

// StatusCommand shows the global scheduler status
func StatusCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "status",
Short: "Show scheduler status",
Long: "Display whether the global scheduler is paused or running.",
Example: "harbor jobservice schedules status",
RunE: func(cmd *cobra.Command, args []string) error {
response, err := api.GetSchedulePaused()
if err != nil {
return formatScheduleError("failed to retrieve scheduler status", err, "authenticated")
}

if response == nil || response.Payload == nil {
fmt.Println("Unable to determine scheduler status.")
return nil
}

formatFlag := viper.GetString("output-format")
if formatFlag != "" {
return utils.PrintFormat(response.Payload, formatFlag)
}

schedules.PrintScheduleStatus(response.Payload)
return nil
},
}

return cmd
}
48 changes: 48 additions & 0 deletions cmd/harbor/root/jobservice/schedules/utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright Project Harbor Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package schedules

import (
"fmt"

"github.com/goharbor/harbor-cli/pkg/utils"
)

func formatScheduleError(operation string, err error, requiredPermission string) error {
errorCode := utils.ParseHarborErrorCode(err)

switch errorCode {
case "400":
return fmt.Errorf("%s: invalid request. For schedule status use job_type=all; for queue action use stop|pause|resume", operation)
case "401":
return fmt.Errorf("%s: authentication required. Please run 'harbor login' and try again", operation)
case "403":
if requiredPermission == "authenticated" {
return fmt.Errorf("%s: permission denied. Your account is authenticated but lacks access", operation)
}
return fmt.Errorf("%s: permission denied. This operation requires %s on jobservice-monitor", operation, requiredPermission)
case "404":
return fmt.Errorf("%s: resource not found or not accessible in current context", operation)
case "422":
return fmt.Errorf("%s: request validation failed. Please check request body and action values", operation)
case "500":
return fmt.Errorf("%s: Harbor internal error. Retry and check Harbor server logs", operation)
default:
msg := utils.ParseHarborErrorMsg(err)
if msg == "" {
msg = err.Error()
}
return fmt.Errorf("%s: %s", operation, msg)
}
}
44 changes: 44 additions & 0 deletions doc/cli-docs/harbor-jobservice-schedules-list.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
title: harbor jobservice schedules list
weight: 10
---
## harbor jobservice schedules list

### Description

##### List schedules (supports --page and --page-size)

### Synopsis

Display all job schedules with pagination support.

```sh
harbor jobservice schedules list [flags]
```

### Examples

```sh
harbor jobservice schedules list --page 1 --page-size 20
```

### Options

```sh
-h, --help help for list
--page int Page number (default 1)
--page-size int Number of items per page (default 20)
```

### Options inherited from parent commands

```sh
-c, --config string config file (default is $HOME/.config/harbor-cli/config.yaml)
-o, --output-format string Output format. One of: json|yaml
-v, --verbose verbose output
```

### SEE ALSO

* [harbor jobservice schedules](harbor-jobservice-schedules.md) - Manage schedules (list/status/pause-all/resume-all)

Loading
Loading