Skip to content

Commit

Permalink
Merge branch 'coder:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
projectoperations authored Oct 25, 2024
2 parents 3b76c49 + df34858 commit b161b95
Show file tree
Hide file tree
Showing 194 changed files with 5,394 additions and 1,618 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ jobs:
- "coderd/**"
- "enterprise/**"
- "examples/*"
- "helm/**"
- "provisioner/**"
- "provisionerd/**"
- "provisionersdk/**"
Expand Down Expand Up @@ -970,7 +971,7 @@ jobs:
uses: google-github-actions/setup-gcloud@f0990588f1e5b5af6827153b93673613abdc6ec7 # v2.1.1

- name: Set up Flux CLI
uses: fluxcd/flux2/action@9b3958825a314eb79495c6993ef397ddbf87f32f # v2.2.1
uses: fluxcd/flux2/action@5350425cdcd5fa015337e09fa502153c0275bd4b # v2.4.0
with:
# Keep this and the github action up to date with the version of flux installed in dogfood cluster
version: "2.2.1"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/scorecard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,6 @@ jobs:

# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12
uses: github/codeql-action/upload-sarif@f779452ac5af1c261dce0346a8f964149f49322b # v3.26.13
with:
sarif_file: results.sarif
20 changes: 5 additions & 15 deletions .github/workflows/security.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
uses: ./.github/actions/setup-go

- name: Initialize CodeQL
uses: github/codeql-action/init@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12
uses: github/codeql-action/init@f779452ac5af1c261dce0346a8f964149f49322b # v3.26.13
with:
languages: go, javascript

Expand All @@ -47,7 +47,7 @@ jobs:
rm Makefile
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12
uses: github/codeql-action/analyze@f779452ac5af1c261dce0346a8f964149f49322b # v3.26.13

- name: Send Slack notification on failure
if: ${{ failure() }}
Expand Down Expand Up @@ -96,7 +96,7 @@ jobs:
# version in the comments will differ. This is also defined in
# ci.yaml.
set -x
cd dogfood
cd dogfood/contents
DOCKER_BUILDKIT=1 docker build . --target proto -t protoc
protoc_path=/usr/local/bin/protoc
docker run --rm --entrypoint cat protoc /tmp/bin/protoc > $protoc_path
Expand Down Expand Up @@ -124,15 +124,15 @@ jobs:
echo "image=$(cat "$image_job")" >> $GITHUB_OUTPUT
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@5681af892cd0f4997658e2bacc62bd0a894cf564
uses: aquasecurity/trivy-action@915b19bbe73b92a6cf82a1bc12b087c9a19a5fe2
with:
image-ref: ${{ steps.build.outputs.image }}
format: sarif
output: trivy-results.sarif
severity: "CRITICAL,HIGH"

- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12
uses: github/codeql-action/upload-sarif@f779452ac5af1c261dce0346a8f964149f49322b # v3.26.13
with:
sarif_file: trivy-results.sarif
category: "Trivy"
Expand All @@ -144,16 +144,6 @@ jobs:
path: trivy-results.sarif
retention-days: 7

# Prisma cloud scan runs last because it fails the entire job if it
# detects vulnerabilities. :|
- name: Run Prisma Cloud image scan
uses: PaloAltoNetworks/prisma-cloud-scan@1f38c94d789ff9b01a4e80070b442294ebd3e362 # v1.4.0
with:
pcc_console_url: ${{ secrets.PRISMA_CLOUD_URL }}
pcc_user: ${{ secrets.PRISMA_CLOUD_ACCESS_KEY }}
pcc_pass: ${{ secrets.PRISMA_CLOUD_SECRET_KEY }}
image_name: ${{ steps.build.outputs.image }}

- name: Send Slack notification on failure
if: ${{ failure() }}
run: |
Expand Down
8 changes: 8 additions & 0 deletions agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -1134,11 +1134,19 @@ func (a *agent) trackGoroutine(fn func()) error {
}

func (a *agent) createTailnet(ctx context.Context, agentID uuid.UUID, derpMap *tailcfg.DERPMap, derpForceWebSockets, disableDirectConnections bool) (_ *tailnet.Conn, err error) {
// Inject `CODER_AGENT_HEADER` into the DERP header.
var header http.Header
if client, ok := a.client.(*agentsdk.Client); ok {
if headerTransport, ok := client.SDK.HTTPClient.Transport.(*codersdk.HeaderTransport); ok {
header = headerTransport.Header
}
}
network, err := tailnet.NewConn(&tailnet.Options{
ID: agentID,
Addresses: a.wireguardAddresses(agentID),
DERPMap: derpMap,
DERPForceWebSockets: derpForceWebSockets,
DERPHeader: &header,
Logger: a.logger.Named("net.tailnet"),
ListenPort: a.tailnetListenPort,
BlockEndpoints: disableDirectConnections,
Expand Down
25 changes: 14 additions & 11 deletions coderd/fileszip.go → archive/archive.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package coderd
package archive

import (
"archive/tar"
Expand All @@ -10,29 +10,30 @@ import (
"strings"
)

func CreateTarFromZip(zipReader *zip.Reader) ([]byte, error) {
// CreateTarFromZip converts the given zipReader to a tar archive.
func CreateTarFromZip(zipReader *zip.Reader, maxSize int64) ([]byte, error) {
var tarBuffer bytes.Buffer
err := writeTarArchive(&tarBuffer, zipReader)
err := writeTarArchive(&tarBuffer, zipReader, maxSize)
if err != nil {
return nil, err
}
return tarBuffer.Bytes(), nil
}

func writeTarArchive(w io.Writer, zipReader *zip.Reader) error {
func writeTarArchive(w io.Writer, zipReader *zip.Reader, maxSize int64) error {
tarWriter := tar.NewWriter(w)
defer tarWriter.Close()

for _, file := range zipReader.File {
err := processFileInZipArchive(file, tarWriter)
err := processFileInZipArchive(file, tarWriter, maxSize)
if err != nil {
return err
}
}
return nil
}

func processFileInZipArchive(file *zip.File, tarWriter *tar.Writer) error {
func processFileInZipArchive(file *zip.File, tarWriter *tar.Writer, maxSize int64) error {
fileReader, err := file.Open()
if err != nil {
return err
Expand All @@ -52,24 +53,26 @@ func processFileInZipArchive(file *zip.File, tarWriter *tar.Writer) error {
return err
}

n, err := io.CopyN(tarWriter, fileReader, httpFileMaxBytes)
n, err := io.CopyN(tarWriter, fileReader, maxSize)
log.Println(file.Name, n, err)
if errors.Is(err, io.EOF) {
err = nil
}
return err
}

func CreateZipFromTar(tarReader *tar.Reader) ([]byte, error) {
// CreateZipFromTar converts the given tarReader to a zip archive.
func CreateZipFromTar(tarReader *tar.Reader, maxSize int64) ([]byte, error) {
var zipBuffer bytes.Buffer
err := WriteZipArchive(&zipBuffer, tarReader)
err := WriteZip(&zipBuffer, tarReader, maxSize)
if err != nil {
return nil, err
}
return zipBuffer.Bytes(), nil
}

func WriteZipArchive(w io.Writer, tarReader *tar.Reader) error {
// WriteZip writes the given tarReader to w.
func WriteZip(w io.Writer, tarReader *tar.Reader, maxSize int64) error {
zipWriter := zip.NewWriter(w)
defer zipWriter.Close()

Expand Down Expand Up @@ -100,7 +103,7 @@ func WriteZipArchive(w io.Writer, tarReader *tar.Reader) error {
return err
}

_, err = io.CopyN(zipEntry, tarReader, httpFileMaxBytes)
_, err = io.CopyN(zipEntry, tarReader, maxSize)
if errors.Is(err, io.EOF) {
err = nil
}
Expand Down
109 changes: 12 additions & 97 deletions coderd/fileszip_test.go → archive/archive_test.go
Original file line number Diff line number Diff line change
@@ -1,24 +1,22 @@
package coderd_test
package archive_test

import (
"archive/tar"
"archive/zip"
"bytes"
"io"
"io/fs"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/xerrors"

"github.com/coder/coder/v2/coderd"
"github.com/coder/coder/v2/archive"
"github.com/coder/coder/v2/archive/archivetest"
"github.com/coder/coder/v2/testutil"
)

Expand All @@ -30,18 +28,17 @@ func TestCreateTarFromZip(t *testing.T) {

// Read a zip file we prepared earlier
ctx := testutil.Context(t, testutil.WaitShort)
zipBytes, err := os.ReadFile(filepath.Join("testdata", "test.zip"))
require.NoError(t, err, "failed to read sample zip file")
zipBytes := archivetest.TestZipFileBytes()
// Assert invariant
assertSampleZipFile(t, zipBytes)
archivetest.AssertSampleZipFile(t, zipBytes)

zr, err := zip.NewReader(bytes.NewReader(zipBytes), int64(len(zipBytes)))
require.NoError(t, err, "failed to parse sample zip file")

tarBytes, err := coderd.CreateTarFromZip(zr)
tarBytes, err := archive.CreateTarFromZip(zr, int64(len(zipBytes)))
require.NoError(t, err, "failed to convert zip to tar")

assertSampleTarFile(t, tarBytes)
archivetest.AssertSampleTarFile(t, tarBytes)

tempDir := t.TempDir()
tempFilePath := filepath.Join(tempDir, "test.tar")
Expand All @@ -60,14 +57,13 @@ func TestCreateZipFromTar(t *testing.T) {
}
t.Run("OK", func(t *testing.T) {
t.Parallel()
tarBytes, err := os.ReadFile(filepath.Join(".", "testdata", "test.tar"))
require.NoError(t, err, "failed to read sample tar file")
tarBytes := archivetest.TestTarFileBytes()

tr := tar.NewReader(bytes.NewReader(tarBytes))
zipBytes, err := coderd.CreateZipFromTar(tr)
zipBytes, err := archive.CreateZipFromTar(tr, int64(len(tarBytes)))
require.NoError(t, err)

assertSampleZipFile(t, zipBytes)
archivetest.AssertSampleZipFile(t, zipBytes)

tempDir := t.TempDir()
tempFilePath := filepath.Join(tempDir, "test.zip")
Expand Down Expand Up @@ -99,7 +95,7 @@ func TestCreateZipFromTar(t *testing.T) {

// When: we convert this to a zip
tr := tar.NewReader(&tarBytes)
zipBytes, err := coderd.CreateZipFromTar(tr)
zipBytes, err := archive.CreateZipFromTar(tr, int64(tarBytes.Len()))
require.NoError(t, err)

// Then: the resulting zip should contain a corresponding directory
Expand Down Expand Up @@ -133,7 +129,7 @@ func assertExtractedFiles(t *testing.T, dir string, checkModePerm bool) {
if checkModePerm {
assert.Equal(t, fs.ModePerm&0o755, stat.Mode().Perm(), "expected mode 0755 on directory")
}
assert.Equal(t, archiveRefTime(t).UTC(), stat.ModTime().UTC(), "unexpected modtime of %q", path)
assert.Equal(t, archivetest.ArchiveRefTime(t).UTC(), stat.ModTime().UTC(), "unexpected modtime of %q", path)
case "/test/hello.txt":
stat, err := os.Stat(path)
assert.NoError(t, err, "failed to stat path %q", path)
Expand Down Expand Up @@ -168,84 +164,3 @@ func assertExtractedFiles(t *testing.T, dir string, checkModePerm bool) {
return nil
})
}

func assertSampleTarFile(t *testing.T, tarBytes []byte) {
t.Helper()

tr := tar.NewReader(bytes.NewReader(tarBytes))
for {
hdr, err := tr.Next()
if err != nil {
if err == io.EOF {
return
}
require.NoError(t, err)
}

// Note: ignoring timezones here.
require.Equal(t, archiveRefTime(t).UTC(), hdr.ModTime.UTC())

switch hdr.Name {
case "test/":
require.Equal(t, hdr.Typeflag, byte(tar.TypeDir))
case "test/hello.txt":
require.Equal(t, hdr.Typeflag, byte(tar.TypeReg))
bs, err := io.ReadAll(tr)
if err != nil && !xerrors.Is(err, io.EOF) {
require.NoError(t, err)
}
require.Equal(t, "hello", string(bs))
case "test/dir/":
require.Equal(t, hdr.Typeflag, byte(tar.TypeDir))
case "test/dir/world.txt":
require.Equal(t, hdr.Typeflag, byte(tar.TypeReg))
bs, err := io.ReadAll(tr)
if err != nil && !xerrors.Is(err, io.EOF) {
require.NoError(t, err)
}
require.Equal(t, "world", string(bs))
default:
require.Failf(t, "unexpected file in tar", hdr.Name)
}
}
}

func assertSampleZipFile(t *testing.T, zipBytes []byte) {
t.Helper()

zr, err := zip.NewReader(bytes.NewReader(zipBytes), int64(len(zipBytes)))
require.NoError(t, err)

for _, f := range zr.File {
// Note: ignoring timezones here.
require.Equal(t, archiveRefTime(t).UTC(), f.Modified.UTC())
switch f.Name {
case "test/", "test/dir/":
// directory
case "test/hello.txt":
rc, err := f.Open()
require.NoError(t, err)
bs, err := io.ReadAll(rc)
_ = rc.Close()
require.NoError(t, err)
require.Equal(t, "hello", string(bs))
case "test/dir/world.txt":
rc, err := f.Open()
require.NoError(t, err)
bs, err := io.ReadAll(rc)
_ = rc.Close()
require.NoError(t, err)
require.Equal(t, "world", string(bs))
default:
require.Failf(t, "unexpected file in zip", f.Name)
}
}
}

// archiveRefTime is the Go reference time. The contents of the sample tar and zip files
// in testdata/ all have their modtimes set to the below in some timezone.
func archiveRefTime(t *testing.T) time.Time {
locMST, err := time.LoadLocation("MST")
require.NoError(t, err, "failed to load MST timezone")
return time.Date(2006, 1, 2, 3, 4, 5, 0, locMST)
}
Loading

0 comments on commit b161b95

Please sign in to comment.