Compare commits
1 Commits
release/v1
...
release/v1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1304e03a06 |
6
.github/workflows/docker.yaml
vendored
6
.github/workflows/docker.yaml
vendored
@@ -18,13 +18,11 @@ jobs:
|
|||||||
- name: Code checkout
|
- name: Code checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Docker metadata
|
- name: Docker Meta
|
||||||
id: docker_meta
|
id: docker_meta
|
||||||
uses: docker/metadata-action@v4
|
uses: docker/metadata-action@v4
|
||||||
with:
|
with:
|
||||||
images: ghcr.io/pterodactyl/wings
|
images: ghcr.io/pterodactyl/wings
|
||||||
flavor: |
|
|
||||||
latest=false
|
|
||||||
tags: |
|
tags: |
|
||||||
type=raw,value=latest,enable=${{ github.event_name == 'release' && github.event.action == 'published' && github.event.release.prerelease == false }}
|
type=raw,value=latest,enable=${{ github.event_name == 'release' && github.event.action == 'published' && github.event.release.prerelease == false }}
|
||||||
type=ref,event=tag
|
type=ref,event=tag
|
||||||
@@ -33,7 +31,7 @@ jobs:
|
|||||||
- name: Setup QEMU
|
- name: Setup QEMU
|
||||||
uses: docker/setup-qemu-action@v2
|
uses: docker/setup-qemu-action@v2
|
||||||
|
|
||||||
- name: Setup Docker buildx
|
- name: Install buildx
|
||||||
uses: docker/setup-buildx-action@v2
|
uses: docker/setup-buildx-action@v2
|
||||||
|
|
||||||
- name: Login to GitHub Container Registry
|
- name: Login to GitHub Container Registry
|
||||||
|
|||||||
6
.github/workflows/push.yaml
vendored
6
.github/workflows/push.yaml
vendored
@@ -16,7 +16,7 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-20.04]
|
os: [ubuntu-20.04]
|
||||||
go: ["1.18.10", "1.19.5"]
|
go: ["1.18.8", "1.19.3"]
|
||||||
goos: [linux]
|
goos: [linux]
|
||||||
goarch: [amd64, arm64]
|
goarch: [amd64, arm64]
|
||||||
|
|
||||||
@@ -86,14 +86,14 @@ jobs:
|
|||||||
go test -race $(go list ./...)
|
go test -race $(go list ./...)
|
||||||
|
|
||||||
- name: Upload Release Artifact
|
- name: Upload Release Artifact
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v2
|
||||||
if: ${{ github.ref == 'refs/heads/develop' || github.event_name == 'pull_request' }}
|
if: ${{ github.ref == 'refs/heads/develop' || github.event_name == 'pull_request' }}
|
||||||
with:
|
with:
|
||||||
name: wings_linux_${{ matrix.goarch }}
|
name: wings_linux_${{ matrix.goarch }}
|
||||||
path: dist/wings
|
path: dist/wings
|
||||||
|
|
||||||
- name: Upload Debug Artifact
|
- name: Upload Debug Artifact
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v2
|
||||||
if: ${{ github.ref == 'refs/heads/develop' || github.event_name == 'pull_request' }}
|
if: ${{ github.ref == 'refs/heads/develop' || github.event_name == 'pull_request' }}
|
||||||
with:
|
with:
|
||||||
name: wings_linux_${{ matrix.goarch }}_debug
|
name: wings_linux_${{ matrix.goarch }}_debug
|
||||||
|
|||||||
4
.github/workflows/release.yaml
vendored
4
.github/workflows/release.yaml
vendored
@@ -17,7 +17,7 @@ jobs:
|
|||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@v3
|
uses: actions/setup-go@v3
|
||||||
with:
|
with:
|
||||||
go-version: "1.18.10"
|
go-version: "1.18.8"
|
||||||
|
|
||||||
- name: Build release binaries
|
- name: Build release binaries
|
||||||
env:
|
env:
|
||||||
@@ -62,6 +62,8 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
with:
|
with:
|
||||||
|
name: ${{ github.ref }}
|
||||||
|
tag_name: ${{ github.ref }}
|
||||||
draft: true
|
draft: true
|
||||||
prerelease: ${{ contains(github.ref, 'rc') || contains(github.ref, 'beta') || contains(github.ref, 'alpha') }}
|
prerelease: ${{ contains(github.ref, 'rc') || contains(github.ref, 'beta') || contains(github.ref, 'alpha') }}
|
||||||
body_path: ./RELEASE_CHANGELOG
|
body_path: ./RELEASE_CHANGELOG
|
||||||
|
|||||||
17
CHANGELOG.md
17
CHANGELOG.md
@@ -1,22 +1,5 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## v1.11.2
|
|
||||||
### Fixed
|
|
||||||
* Backups being restored from remote storage (s3) erroring out due to a closed stream.
|
|
||||||
* Fix IP validation logic for activity logs filtering out valid IPs instead of invalid IPs
|
|
||||||
|
|
||||||
## v1.11.1
|
|
||||||
### Changed
|
|
||||||
* Release binaries are now built with Go 1.18.10
|
|
||||||
* Timeout when stopping a server before a transfer begins has been reduced to 15 seconds from 1 minute
|
|
||||||
* Removed insecure SSH protocols for use with the SFTP server
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
* Unnecessary Docker client connections being left open, causing a slow leak of file descriptors
|
|
||||||
* Files being left open in parts of the server's filesystem, causing a leak of file descriptors
|
|
||||||
* IPv6 addresses being corrupted by flawed port stripping logic for activity logs, old entries with malformed IPs will be deleted from the local SQLite database automatically
|
|
||||||
* A server that times out while being stopped at the beginning of a transfer no longer causes the server to become stuck in a transferring state
|
|
||||||
|
|
||||||
## v1.11.0
|
## v1.11.0
|
||||||
### Added (since 1.7.2)
|
### Added (since 1.7.2)
|
||||||
* More detailed information returned by the `/api/system` endpoint when using the `?v=2` query parameter.
|
* More detailed information returned by the `/api/system` endpoint when using the `?v=2` query parameter.
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ func (e *Environment) Attach(ctx context.Context) error {
|
|||||||
|
|
||||||
// Set the stream again with the container.
|
// Set the stream again with the container.
|
||||||
if st, err := e.client.ContainerAttach(ctx, e.Id, opts); err != nil {
|
if st, err := e.client.ContainerAttach(ctx, e.Id, opts); err != nil {
|
||||||
return errors.WrapIf(err, "environment/docker: error while attaching to container")
|
return err
|
||||||
} else {
|
} else {
|
||||||
e.SetStream(&st)
|
e.SetStream(&st)
|
||||||
}
|
}
|
||||||
@@ -143,7 +143,7 @@ func (e *Environment) Create() error {
|
|||||||
if _, err := e.ContainerInspect(ctx); err == nil {
|
if _, err := e.ContainerInspect(ctx); err == nil {
|
||||||
return nil
|
return nil
|
||||||
} else if !client.IsErrNotFound(err) {
|
} else if !client.IsErrNotFound(err) {
|
||||||
return errors.WrapIf(err, "environment/docker: failed to inspect container")
|
return errors.Wrap(err, "environment/docker: failed to inspect container")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to pull the requested image before creating the container.
|
// Try to pull the requested image before creating the container.
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ func (e *Environment) ExitState() (uint32, bool, error) {
|
|||||||
if client.IsErrNotFound(err) {
|
if client.IsErrNotFound(err) {
|
||||||
return 1, false, nil
|
return 1, false, nil
|
||||||
}
|
}
|
||||||
return 0, false, errors.WrapIf(err, "environment/docker: failed to inspect container")
|
return 0, false, err
|
||||||
}
|
}
|
||||||
return uint32(c.State.ExitCode), c.State.OOMKilled, nil
|
return uint32(c.State.ExitCode), c.State.OOMKilled, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ func (e *Environment) Start(ctx context.Context) error {
|
|||||||
// exists on the system, and rebuild the container if that is required for server booting to
|
// exists on the system, and rebuild the container if that is required for server booting to
|
||||||
// occur.
|
// occur.
|
||||||
if err := e.OnBeforeStart(ctx); err != nil {
|
if err := e.OnBeforeStart(ctx); err != nil {
|
||||||
return errors.WrapIf(err, "environment/docker: failed to run pre-boot process")
|
return errors.WithStackIf(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we cannot start & attach to the container in 30 seconds something has gone
|
// If we cannot start & attach to the container in 30 seconds something has gone
|
||||||
@@ -119,7 +119,7 @@ func (e *Environment) Start(ctx context.Context) error {
|
|||||||
// By explicitly attaching to the instance before we start it, we can immediately
|
// By explicitly attaching to the instance before we start it, we can immediately
|
||||||
// react to errors/output stopping/etc. when starting.
|
// react to errors/output stopping/etc. when starting.
|
||||||
if err := e.Attach(actx); err != nil {
|
if err := e.Attach(actx); err != nil {
|
||||||
return errors.WrapIf(err, "environment/docker: failed to attach to container")
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := e.client.ContainerStart(actx, e.Id, types.ContainerStartOptions{}); err != nil {
|
if err := e.client.ContainerStart(actx, e.Id, types.ContainerStartOptions{}); err != nil {
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package cron
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"net"
|
|
||||||
|
|
||||||
"emperror.dev/errors"
|
"emperror.dev/errors"
|
||||||
|
|
||||||
@@ -18,9 +17,9 @@ type activityCron struct {
|
|||||||
max int
|
max int
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run executes the cronjob and ensures we fetch and send all the stored activity to the
|
// Run executes the cronjob and ensures we fetch and send all of the stored activity to the
|
||||||
// Panel instance. Once activity is sent it is deleted from the local database instance. Any
|
// Panel instance. Once activity is sent it is deleted from the local database instance. Any
|
||||||
// SFTP specific events are not handled in this cron, they're handled separately to account
|
// SFTP specific events are not handled in this cron, they're handled seperately to account
|
||||||
// for de-duplication and event merging.
|
// for de-duplication and event merging.
|
||||||
func (ac *activityCron) Run(ctx context.Context) error {
|
func (ac *activityCron) Run(ctx context.Context) error {
|
||||||
// Don't execute this cron if there is currently one running. Once this task is completed
|
// Don't execute this cron if there is currently one running. Once this task is completed
|
||||||
@@ -35,6 +34,7 @@ func (ac *activityCron) Run(ctx context.Context) error {
|
|||||||
Where("event NOT LIKE ?", "server:sftp.%").
|
Where("event NOT LIKE ?", "server:sftp.%").
|
||||||
Limit(ac.max).
|
Limit(ac.max).
|
||||||
Find(&activity)
|
Find(&activity)
|
||||||
|
|
||||||
if tx.Error != nil {
|
if tx.Error != nil {
|
||||||
return errors.WithStack(tx.Error)
|
return errors.WithStack(tx.Error)
|
||||||
}
|
}
|
||||||
@@ -42,42 +42,15 @@ func (ac *activityCron) Run(ctx context.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ids to delete from the database.
|
if err := ac.manager.Client().SendActivityLogs(ctx, activity); err != nil {
|
||||||
ids := make([]int, 0, len(activity))
|
|
||||||
// activities to send to the panel.
|
|
||||||
activities := make([]models.Activity, 0, len(activity))
|
|
||||||
for _, v := range activity {
|
|
||||||
// Delete any activity that has an invalid IP address. This is a fix for
|
|
||||||
// a bug that truncated the last octet of an IPv6 address in the database.
|
|
||||||
if ip := net.ParseIP(v.IP); ip == nil {
|
|
||||||
ids = append(ids, v.ID)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
activities = append(activities, v)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(ids) > 0 {
|
|
||||||
tx = database.Instance().WithContext(ctx).Where("id IN ?", ids).Delete(&models.Activity{})
|
|
||||||
if tx.Error != nil {
|
|
||||||
return errors.WithStack(tx.Error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(activities) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := ac.manager.Client().SendActivityLogs(ctx, activities); err != nil {
|
|
||||||
return errors.WrapIf(err, "cron: failed to send activity events to Panel")
|
return errors.WrapIf(err, "cron: failed to send activity events to Panel")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add all the successful activities to the list of IDs to delete.
|
var ids []int
|
||||||
ids = make([]int, len(activities))
|
for _, v := range activity {
|
||||||
for i, v := range activities {
|
ids = append(ids, v.ID)
|
||||||
ids[i] = v.ID
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete all the activities that were sent to the Panel (or that were invalid).
|
|
||||||
tx = database.Instance().WithContext(ctx).Where("id IN ?", ids).Delete(&models.Activity{})
|
tx = database.Instance().WithContext(ctx).Where("id IN ?", ids).Delete(&models.Activity{})
|
||||||
if tx.Error != nil {
|
if tx.Error != nil {
|
||||||
return errors.WithStack(tx.Error)
|
return errors.WithStack(tx.Error)
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
|
||||||
|
"github.com/pterodactyl/wings/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Event string
|
type Event string
|
||||||
@@ -57,9 +57,7 @@ func (a Activity) SetUser(u string) *Activity {
|
|||||||
// is trimmed down to remove any extraneous data, and the timestamp is set to the current
|
// is trimmed down to remove any extraneous data, and the timestamp is set to the current
|
||||||
// system time and then stored as UTC.
|
// system time and then stored as UTC.
|
||||||
func (a *Activity) BeforeCreate(_ *gorm.DB) error {
|
func (a *Activity) BeforeCreate(_ *gorm.DB) error {
|
||||||
if ip, _, err := net.SplitHostPort(strings.TrimSpace(a.IP)); err == nil {
|
a.IP = system.TrimIPSuffix(a.IP)
|
||||||
a.IP = ip
|
|
||||||
}
|
|
||||||
if a.Timestamp.IsZero() {
|
if a.Timestamp.IsZero() {
|
||||||
a.Timestamp = time.Now()
|
a.Timestamp = time.Now()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,7 +95,6 @@ func getDownloadFile(c *gin.Context) {
|
|||||||
middleware.CaptureAndAbort(c, err)
|
middleware.CaptureAndAbort(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer f.Close()
|
|
||||||
|
|
||||||
c.Header("Content-Length", strconv.Itoa(int(st.Size())))
|
c.Header("Content-Length", strconv.Itoa(int(st.Size())))
|
||||||
c.Header("Content-Disposition", "attachment; filename="+strconv.Quote(st.Name()))
|
c.Header("Content-Disposition", "attachment; filename="+strconv.Quote(st.Name()))
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"emperror.dev/errors"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
|
||||||
"github.com/pterodactyl/wings/environment"
|
"github.com/pterodactyl/wings/environment"
|
||||||
@@ -64,11 +63,11 @@ func postServerTransfer(c *gin.Context) {
|
|||||||
if s.Environment.State() != environment.ProcessOfflineState {
|
if s.Environment.State() != environment.ProcessOfflineState {
|
||||||
if err := s.Environment.WaitForStop(
|
if err := s.Environment.WaitForStop(
|
||||||
s.Context(),
|
s.Context(),
|
||||||
time.Second*15,
|
time.Minute,
|
||||||
false,
|
false,
|
||||||
); err != nil && !strings.Contains(strings.ToLower(err.Error()), "no such container") {
|
); err != nil && !strings.Contains(strings.ToLower(err.Error()), "no such container") {
|
||||||
s.SetTransferring(false)
|
notifyPanelOfFailure()
|
||||||
middleware.CaptureAndAbort(c, errors.Wrap(err, "failed to stop server for transfer"))
|
s.Log().WithError(err).Error("failed to stop server for transfer")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ func getServerWebsocket(c *gin.Context) {
|
|||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
break
|
break
|
||||||
case <-s.Context().Done():
|
case <-s.Context().Done():
|
||||||
_ = handler.Connection.WriteControl(ws.CloseMessage, ws.FormatCloseMessage(ws.CloseGoingAway, "server deleted"), time.Now().Add(time.Second*5))
|
handler.Connection.WriteControl(ws.CloseMessage, ws.FormatCloseMessage(ws.CloseGoingAway, "server deleted"), time.Now().Add(time.Second*5))
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
@@ -83,7 +83,7 @@ func getServerWebsocket(c *gin.Context) {
|
|||||||
|
|
||||||
go func(msg websocket.Message) {
|
go func(msg websocket.Message) {
|
||||||
if err := handler.HandleInbound(ctx, msg); err != nil {
|
if err := handler.HandleInbound(ctx, msg); err != nil {
|
||||||
_ = handler.SendErrorJson(msg, err)
|
handler.SendErrorJson(msg, err)
|
||||||
}
|
}
|
||||||
}(j)
|
}(j)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,7 +85,6 @@ func (b *LocalBackup) Restore(ctx context.Context, _ io.Reader, callback Restore
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer f.Close()
|
|
||||||
|
|
||||||
var reader io.Reader = f
|
var reader io.Reader = f
|
||||||
// Steal the logic we use for making backups which will be applied when restoring
|
// Steal the logic we use for making backups which will be applied when restoring
|
||||||
|
|||||||
@@ -6,8 +6,6 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"emperror.dev/errors"
|
|
||||||
|
|
||||||
"github.com/pterodactyl/wings/config"
|
"github.com/pterodactyl/wings/config"
|
||||||
"github.com/pterodactyl/wings/environment"
|
"github.com/pterodactyl/wings/environment"
|
||||||
)
|
)
|
||||||
@@ -59,7 +57,7 @@ func (s *Server) handleServerCrash() error {
|
|||||||
|
|
||||||
exitCode, oomKilled, err := s.Environment.ExitState()
|
exitCode, oomKilled, err := s.Environment.ExitState()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to get exit state for server process")
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the system is not configured to detect a clean exit code as a crash, and the
|
// If the system is not configured to detect a clean exit code as a crash, and the
|
||||||
@@ -87,5 +85,5 @@ func (s *Server) handleServerCrash() error {
|
|||||||
|
|
||||||
s.crasher.SetLastCrash(time.Now())
|
s.crasher.SetLastCrash(time.Now())
|
||||||
|
|
||||||
return errors.Wrap(s.HandlePowerAction(PowerActionStart), "failed to start server after crash detection")
|
return s.HandlePowerAction(PowerActionStart)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ func (fs *Filesystem) DecompressFileUnsafe(ctx context.Context, dir string, file
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer f.Close()
|
// TODO: defer file close?
|
||||||
|
|
||||||
// Identify the type of archive we are dealing with.
|
// Identify the type of archive we are dealing with.
|
||||||
format, input, err := archiver.Identify(filepath.Base(file), f)
|
format, input, err := archiver.Identify(filepath.Base(file), f)
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ func (fs *Filesystem) DirectorySize(dir string) (int64, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !e.IsDir() {
|
if !e.IsDir() {
|
||||||
_ = syscall.Lstat(p, &st)
|
syscall.Lstat(p, &st)
|
||||||
atomic.AddInt64(&size, st.Size)
|
atomic.AddInt64(&size, st.Size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -92,9 +92,6 @@ func (fs *Filesystem) Touch(p string, flag int) (*os.File, error) {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
return f, nil
|
return f, nil
|
||||||
}
|
}
|
||||||
if f != nil {
|
|
||||||
_ = f.Close()
|
|
||||||
}
|
|
||||||
// If the error is not because it doesn't exist then we just need to bail at this point.
|
// If the error is not because it doesn't exist then we just need to bail at this point.
|
||||||
if !errors.Is(err, os.ErrNotExist) {
|
if !errors.Is(err, os.ErrNotExist) {
|
||||||
return nil, errors.Wrap(err, "server/filesystem: touch: failed to open file handle")
|
return nil, errors.Wrap(err, "server/filesystem: touch: failed to open file handle")
|
||||||
|
|||||||
@@ -147,7 +147,6 @@ func (s *Server) Context() context.Context {
|
|||||||
// server instance.
|
// server instance.
|
||||||
func (s *Server) GetEnvironmentVariables() []string {
|
func (s *Server) GetEnvironmentVariables() []string {
|
||||||
out := []string{
|
out := []string{
|
||||||
// TODO: allow this to be overridden by the user.
|
|
||||||
fmt.Sprintf("TZ=%s", config.Get().System.Timezone),
|
fmt.Sprintf("TZ=%s", config.Get().System.Timezone),
|
||||||
fmt.Sprintf("STARTUP=%s", s.Config().Invocation),
|
fmt.Sprintf("STARTUP=%s", s.Config().Invocation),
|
||||||
fmt.Sprintf("SERVER_MEMORY=%d", s.MemoryLimit()),
|
fmt.Sprintf("SERVER_MEMORY=%d", s.MemoryLimit()),
|
||||||
|
|||||||
@@ -68,21 +68,6 @@ func (c *SFTPServer) Run() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
conf := &ssh.ServerConfig{
|
conf := &ssh.ServerConfig{
|
||||||
Config: ssh.Config{
|
|
||||||
KeyExchanges: []string{
|
|
||||||
"curve25519-sha256", "curve25519-sha256@libssh.org",
|
|
||||||
"ecdh-sha2-nistp256", "ecdh-sha2-nistp384", "ecdh-sha2-nistp521",
|
|
||||||
"diffie-hellman-group14-sha256",
|
|
||||||
},
|
|
||||||
Ciphers: []string{
|
|
||||||
"aes128-gcm@openssh.com",
|
|
||||||
"chacha20-poly1305@openssh.com",
|
|
||||||
"aes128-ctr", "aes192-ctr", "aes256-ctr",
|
|
||||||
},
|
|
||||||
MACs: []string{
|
|
||||||
"hmac-sha2-256-etm@openssh.com", "hmac-sha2-256",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
NoClientAuth: false,
|
NoClientAuth: false,
|
||||||
MaxAuthTries: 6,
|
MaxAuthTries: 6,
|
||||||
PasswordCallback: func(conn ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) {
|
PasswordCallback: func(conn ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) {
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
package system
|
package system
|
||||||
|
|
||||||
var Version = "1.11.2"
|
var Version = "1.11.0"
|
||||||
|
|||||||
29
system/strings.go
Normal file
29
system/strings.go
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/rand"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var ipTrimRegex = regexp.MustCompile(`(:\d*)?$`)
|
||||||
|
|
||||||
|
const characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
|
||||||
|
|
||||||
|
// RandomString generates a random string of alpha-numeric characters using a
|
||||||
|
// pseudo-random number generator. The output of this function IS NOT cryptographically
|
||||||
|
// secure, it is used solely for generating random strings outside a security context.
|
||||||
|
func RandomString(n int) string {
|
||||||
|
var b strings.Builder
|
||||||
|
b.Grow(n)
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
b.WriteByte(characters[rand.Intn(len(characters))])
|
||||||
|
}
|
||||||
|
return b.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// TrimIPSuffix removes the internal port value from an IP address to ensure we're only
|
||||||
|
// ever working directly with the IP address.
|
||||||
|
func TrimIPSuffix(s string) string {
|
||||||
|
return ipTrimRegex.ReplaceAllString(s, "")
|
||||||
|
}
|
||||||
@@ -127,7 +127,6 @@ func GetDockerInfo(ctx context.Context) (types.Version, types.Info, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return types.Version{}, types.Info{}, err
|
return types.Version{}, types.Info{}, err
|
||||||
}
|
}
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
dockerVersion, err := c.ServerVersion(ctx)
|
dockerVersion, err := c.ServerVersion(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user