code.gitea.io/gitea@v1.22.3/cmd/admin.go (about)

     1  // Copyright 2016 The Gogs Authors. All rights reserved.
     2  // Copyright 2016 The Gitea Authors. All rights reserved.
     3  // SPDX-License-Identifier: MIT
     4  
     5  package cmd
     6  
     7  import (
     8  	"context"
     9  	"fmt"
    10  
    11  	"code.gitea.io/gitea/models/db"
    12  	repo_model "code.gitea.io/gitea/models/repo"
    13  	"code.gitea.io/gitea/modules/git"
    14  	"code.gitea.io/gitea/modules/gitrepo"
    15  	"code.gitea.io/gitea/modules/log"
    16  	repo_module "code.gitea.io/gitea/modules/repository"
    17  
    18  	"github.com/urfave/cli/v2"
    19  )
    20  
    21  var (
    22  	// CmdAdmin represents the available admin sub-command.
    23  	CmdAdmin = &cli.Command{
    24  		Name:  "admin",
    25  		Usage: "Perform common administrative operations",
    26  		Subcommands: []*cli.Command{
    27  			subcmdUser,
    28  			subcmdRepoSyncReleases,
    29  			subcmdRegenerate,
    30  			subcmdAuth,
    31  			subcmdSendMail,
    32  		},
    33  	}
    34  
    35  	subcmdRepoSyncReleases = &cli.Command{
    36  		Name:   "repo-sync-releases",
    37  		Usage:  "Synchronize repository releases with tags",
    38  		Action: runRepoSyncReleases,
    39  	}
    40  
    41  	subcmdRegenerate = &cli.Command{
    42  		Name:  "regenerate",
    43  		Usage: "Regenerate specific files",
    44  		Subcommands: []*cli.Command{
    45  			microcmdRegenHooks,
    46  			microcmdRegenKeys,
    47  		},
    48  	}
    49  
    50  	subcmdAuth = &cli.Command{
    51  		Name:  "auth",
    52  		Usage: "Modify external auth providers",
    53  		Subcommands: []*cli.Command{
    54  			microcmdAuthAddOauth,
    55  			microcmdAuthUpdateOauth,
    56  			microcmdAuthAddLdapBindDn,
    57  			microcmdAuthUpdateLdapBindDn,
    58  			microcmdAuthAddLdapSimpleAuth,
    59  			microcmdAuthUpdateLdapSimpleAuth,
    60  			microcmdAuthAddSMTP,
    61  			microcmdAuthUpdateSMTP,
    62  			microcmdAuthList,
    63  			microcmdAuthDelete,
    64  		},
    65  	}
    66  
    67  	subcmdSendMail = &cli.Command{
    68  		Name:   "sendmail",
    69  		Usage:  "Send a message to all users",
    70  		Action: runSendMail,
    71  		Flags: []cli.Flag{
    72  			&cli.StringFlag{
    73  				Name:  "title",
    74  				Usage: `a title of a message`,
    75  				Value: "",
    76  			},
    77  			&cli.StringFlag{
    78  				Name:  "content",
    79  				Usage: "a content of a message",
    80  				Value: "",
    81  			},
    82  			&cli.BoolFlag{
    83  				Name:    "force",
    84  				Aliases: []string{"f"},
    85  				Usage:   "A flag to bypass a confirmation step",
    86  			},
    87  		},
    88  	}
    89  
    90  	idFlag = &cli.Int64Flag{
    91  		Name:  "id",
    92  		Usage: "ID of authentication source",
    93  	}
    94  )
    95  
    96  func runRepoSyncReleases(_ *cli.Context) error {
    97  	ctx, cancel := installSignals()
    98  	defer cancel()
    99  
   100  	if err := initDB(ctx); err != nil {
   101  		return err
   102  	}
   103  
   104  	if err := git.InitSimple(ctx); err != nil {
   105  		return err
   106  	}
   107  
   108  	log.Trace("Synchronizing repository releases (this may take a while)")
   109  	for page := 1; ; page++ {
   110  		repos, count, err := repo_model.SearchRepositoryByName(ctx, &repo_model.SearchRepoOptions{
   111  			ListOptions: db.ListOptions{
   112  				PageSize: repo_model.RepositoryListDefaultPageSize,
   113  				Page:     page,
   114  			},
   115  			Private: true,
   116  		})
   117  		if err != nil {
   118  			return fmt.Errorf("SearchRepositoryByName: %w", err)
   119  		}
   120  		if len(repos) == 0 {
   121  			break
   122  		}
   123  		log.Trace("Processing next %d repos of %d", len(repos), count)
   124  		for _, repo := range repos {
   125  			log.Trace("Synchronizing repo %s with path %s", repo.FullName(), repo.RepoPath())
   126  			gitRepo, err := gitrepo.OpenRepository(ctx, repo)
   127  			if err != nil {
   128  				log.Warn("OpenRepository: %v", err)
   129  				continue
   130  			}
   131  
   132  			oldnum, err := getReleaseCount(ctx, repo.ID)
   133  			if err != nil {
   134  				log.Warn(" GetReleaseCountByRepoID: %v", err)
   135  			}
   136  			log.Trace(" currentNumReleases is %d, running SyncReleasesWithTags", oldnum)
   137  
   138  			if err = repo_module.SyncReleasesWithTags(ctx, repo, gitRepo); err != nil {
   139  				log.Warn(" SyncReleasesWithTags: %v", err)
   140  				gitRepo.Close()
   141  				continue
   142  			}
   143  
   144  			count, err = getReleaseCount(ctx, repo.ID)
   145  			if err != nil {
   146  				log.Warn(" GetReleaseCountByRepoID: %v", err)
   147  				gitRepo.Close()
   148  				continue
   149  			}
   150  
   151  			log.Trace(" repo %s releases synchronized to tags: from %d to %d",
   152  				repo.FullName(), oldnum, count)
   153  			gitRepo.Close()
   154  		}
   155  	}
   156  
   157  	return nil
   158  }
   159  
   160  func getReleaseCount(ctx context.Context, id int64) (int64, error) {
   161  	return db.Count[repo_model.Release](
   162  		ctx,
   163  		repo_model.FindReleasesOptions{
   164  			RepoID:      id,
   165  			IncludeTags: true,
   166  		},
   167  	)
   168  }