code.gitea.io/gitea@v1.19.3/modules/private/manager.go (about)

     1  // Copyright 2020 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package private
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  	"io"
    10  	"net/http"
    11  	"net/url"
    12  	"strconv"
    13  	"time"
    14  
    15  	"code.gitea.io/gitea/modules/json"
    16  	"code.gitea.io/gitea/modules/setting"
    17  )
    18  
    19  // Shutdown calls the internal shutdown function
    20  func Shutdown(ctx context.Context) (int, string) {
    21  	reqURL := setting.LocalURL + "api/internal/manager/shutdown"
    22  
    23  	req := newInternalRequest(ctx, reqURL, "POST")
    24  	resp, err := req.Response()
    25  	if err != nil {
    26  		return http.StatusInternalServerError, fmt.Sprintf("Unable to contact gitea: %v", err.Error())
    27  	}
    28  	defer resp.Body.Close()
    29  
    30  	if resp.StatusCode != http.StatusOK {
    31  		return resp.StatusCode, decodeJSONError(resp).Err
    32  	}
    33  
    34  	return http.StatusOK, "Shutting down"
    35  }
    36  
    37  // Restart calls the internal restart function
    38  func Restart(ctx context.Context) (int, string) {
    39  	reqURL := setting.LocalURL + "api/internal/manager/restart"
    40  
    41  	req := newInternalRequest(ctx, reqURL, "POST")
    42  	resp, err := req.Response()
    43  	if err != nil {
    44  		return http.StatusInternalServerError, fmt.Sprintf("Unable to contact gitea: %v", err.Error())
    45  	}
    46  	defer resp.Body.Close()
    47  
    48  	if resp.StatusCode != http.StatusOK {
    49  		return resp.StatusCode, decodeJSONError(resp).Err
    50  	}
    51  
    52  	return http.StatusOK, "Restarting"
    53  }
    54  
    55  // FlushOptions represents the options for the flush call
    56  type FlushOptions struct {
    57  	Timeout     time.Duration
    58  	NonBlocking bool
    59  }
    60  
    61  // FlushQueues calls the internal flush-queues function
    62  func FlushQueues(ctx context.Context, timeout time.Duration, nonBlocking bool) (int, string) {
    63  	reqURL := setting.LocalURL + "api/internal/manager/flush-queues"
    64  
    65  	req := newInternalRequest(ctx, reqURL, "POST")
    66  	if timeout > 0 {
    67  		req.SetTimeout(timeout+10*time.Second, timeout+10*time.Second)
    68  	}
    69  	req = req.Header("Content-Type", "application/json")
    70  	jsonBytes, _ := json.Marshal(FlushOptions{
    71  		Timeout:     timeout,
    72  		NonBlocking: nonBlocking,
    73  	})
    74  	req.Body(jsonBytes)
    75  	resp, err := req.Response()
    76  	if err != nil {
    77  		return http.StatusInternalServerError, fmt.Sprintf("Unable to contact gitea: %v", err.Error())
    78  	}
    79  	defer resp.Body.Close()
    80  
    81  	if resp.StatusCode != http.StatusOK {
    82  		return resp.StatusCode, decodeJSONError(resp).Err
    83  	}
    84  
    85  	return http.StatusOK, "Flushed"
    86  }
    87  
    88  // PauseLogging pauses logging
    89  func PauseLogging(ctx context.Context) (int, string) {
    90  	reqURL := setting.LocalURL + "api/internal/manager/pause-logging"
    91  
    92  	req := newInternalRequest(ctx, reqURL, "POST")
    93  	resp, err := req.Response()
    94  	if err != nil {
    95  		return http.StatusInternalServerError, fmt.Sprintf("Unable to contact gitea: %v", err.Error())
    96  	}
    97  	defer resp.Body.Close()
    98  
    99  	if resp.StatusCode != http.StatusOK {
   100  		return resp.StatusCode, decodeJSONError(resp).Err
   101  	}
   102  
   103  	return http.StatusOK, "Logging Paused"
   104  }
   105  
   106  // ResumeLogging resumes logging
   107  func ResumeLogging(ctx context.Context) (int, string) {
   108  	reqURL := setting.LocalURL + "api/internal/manager/resume-logging"
   109  
   110  	req := newInternalRequest(ctx, reqURL, "POST")
   111  	resp, err := req.Response()
   112  	if err != nil {
   113  		return http.StatusInternalServerError, fmt.Sprintf("Unable to contact gitea: %v", err.Error())
   114  	}
   115  	defer resp.Body.Close()
   116  
   117  	if resp.StatusCode != http.StatusOK {
   118  		return resp.StatusCode, decodeJSONError(resp).Err
   119  	}
   120  
   121  	return http.StatusOK, "Logging Restarted"
   122  }
   123  
   124  // ReleaseReopenLogging releases and reopens logging files
   125  func ReleaseReopenLogging(ctx context.Context) (int, string) {
   126  	reqURL := setting.LocalURL + "api/internal/manager/release-and-reopen-logging"
   127  
   128  	req := newInternalRequest(ctx, reqURL, "POST")
   129  	resp, err := req.Response()
   130  	if err != nil {
   131  		return http.StatusInternalServerError, fmt.Sprintf("Unable to contact gitea: %v", err.Error())
   132  	}
   133  	defer resp.Body.Close()
   134  
   135  	if resp.StatusCode != http.StatusOK {
   136  		return resp.StatusCode, decodeJSONError(resp).Err
   137  	}
   138  
   139  	return http.StatusOK, "Logging Restarted"
   140  }
   141  
   142  // SetLogSQL sets database logging
   143  func SetLogSQL(ctx context.Context, on bool) (int, string) {
   144  	reqURL := setting.LocalURL + "api/internal/manager/set-log-sql?on=" + strconv.FormatBool(on)
   145  
   146  	req := newInternalRequest(ctx, reqURL, "POST")
   147  	resp, err := req.Response()
   148  	if err != nil {
   149  		return http.StatusInternalServerError, fmt.Sprintf("Unable to contact gitea: %v", err.Error())
   150  	}
   151  	defer resp.Body.Close()
   152  
   153  	if resp.StatusCode != http.StatusOK {
   154  		return resp.StatusCode, decodeJSONError(resp).Err
   155  	}
   156  
   157  	return http.StatusOK, "Log SQL setting set"
   158  }
   159  
   160  // LoggerOptions represents the options for the add logger call
   161  type LoggerOptions struct {
   162  	Group  string
   163  	Name   string
   164  	Mode   string
   165  	Config map[string]interface{}
   166  }
   167  
   168  // AddLogger adds a logger
   169  func AddLogger(ctx context.Context, group, name, mode string, config map[string]interface{}) (int, string) {
   170  	reqURL := setting.LocalURL + "api/internal/manager/add-logger"
   171  
   172  	req := newInternalRequest(ctx, reqURL, "POST")
   173  	req = req.Header("Content-Type", "application/json")
   174  	jsonBytes, _ := json.Marshal(LoggerOptions{
   175  		Group:  group,
   176  		Name:   name,
   177  		Mode:   mode,
   178  		Config: config,
   179  	})
   180  	req.Body(jsonBytes)
   181  	resp, err := req.Response()
   182  	if err != nil {
   183  		return http.StatusInternalServerError, fmt.Sprintf("Unable to contact gitea: %v", err.Error())
   184  	}
   185  	defer resp.Body.Close()
   186  
   187  	if resp.StatusCode != http.StatusOK {
   188  		return resp.StatusCode, decodeJSONError(resp).Err
   189  	}
   190  
   191  	return http.StatusOK, "Added"
   192  }
   193  
   194  // RemoveLogger removes a logger
   195  func RemoveLogger(ctx context.Context, group, name string) (int, string) {
   196  	reqURL := setting.LocalURL + fmt.Sprintf("api/internal/manager/remove-logger/%s/%s", url.PathEscape(group), url.PathEscape(name))
   197  
   198  	req := newInternalRequest(ctx, reqURL, "POST")
   199  	resp, err := req.Response()
   200  	if err != nil {
   201  		return http.StatusInternalServerError, fmt.Sprintf("Unable to contact gitea: %v", err.Error())
   202  	}
   203  	defer resp.Body.Close()
   204  
   205  	if resp.StatusCode != http.StatusOK {
   206  		return resp.StatusCode, decodeJSONError(resp).Err
   207  	}
   208  
   209  	return http.StatusOK, "Removed"
   210  }
   211  
   212  // Processes return the current processes from this gitea instance
   213  func Processes(ctx context.Context, out io.Writer, flat, noSystem, stacktraces, json bool, cancel string) (int, string) {
   214  	reqURL := setting.LocalURL + fmt.Sprintf("api/internal/manager/processes?flat=%t&no-system=%t&stacktraces=%t&json=%t&cancel-pid=%s", flat, noSystem, stacktraces, json, url.QueryEscape(cancel))
   215  
   216  	req := newInternalRequest(ctx, reqURL, "GET")
   217  	resp, err := req.Response()
   218  	if err != nil {
   219  		return http.StatusInternalServerError, fmt.Sprintf("Unable to contact gitea: %v", err.Error())
   220  	}
   221  	defer resp.Body.Close()
   222  
   223  	if resp.StatusCode != http.StatusOK {
   224  		return resp.StatusCode, decodeJSONError(resp).Err
   225  	}
   226  
   227  	_, err = io.Copy(out, resp.Body)
   228  	if err != nil {
   229  		return http.StatusInternalServerError, err.Error()
   230  	}
   231  	return http.StatusOK, ""
   232  }