Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* List new releases * never return null * Channel sequence not release sequence
- Loading branch information
Showing
18 changed files
with
591 additions
and
165 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package main | ||
|
||
import ( | ||
"io/ioutil" | ||
"os" | ||
|
||
"github.com/mholt/archiver" | ||
"github.com/pkg/errors" | ||
kotsv1beta1 "github.com/replicatedhq/kots/kotskinds/apis/kots/v1beta1" | ||
"k8s.io/client-go/kubernetes/scheme" | ||
) | ||
|
||
func extractArchive(rootPath, fromArchivePath string) (*archiver.TarGz, error) { | ||
// extract the current archive to this root | ||
tarGz := &archiver.TarGz{ | ||
Tar: &archiver.Tar{ | ||
ImplicitTopLevelFolder: false, | ||
}, | ||
} | ||
if err := tarGz.Unarchive(fromArchivePath, rootPath); err != nil { | ||
return nil, err | ||
} | ||
|
||
return tarGz, nil | ||
} | ||
|
||
func readCursorFromPath(installationFilePath string) (string, error) { | ||
_, err := os.Stat(installationFilePath) | ||
if os.IsNotExist(err) { | ||
return "", nil | ||
} | ||
if err != nil { | ||
return "", errors.Wrap(err, "failed to open file") | ||
} | ||
|
||
installationData, err := ioutil.ReadFile(installationFilePath) | ||
if err != nil { | ||
return "", errors.Wrap(err, "failed to read update installation file") | ||
} | ||
|
||
decode := scheme.Codecs.UniversalDeserializer().Decode | ||
obj, _, err := decode([]byte(installationData), nil, nil) | ||
if err != nil { | ||
return "", errors.Wrap(err, "failed to devode installation data") | ||
} | ||
|
||
installation := obj.(*kotsv1beta1.Installation) | ||
return installation.Spec.UpdateCursor, nil | ||
} | ||
|
||
func loadLicenseFromPath(expectedLicenseFile string) (*kotsv1beta1.License, error) { | ||
_, err := os.Stat(expectedLicenseFile) | ||
if err != nil { | ||
return nil, errors.New("find license file in archive") | ||
} | ||
licenseData, err := ioutil.ReadFile(expectedLicenseFile) | ||
if err != nil { | ||
return nil, errors.Wrap(err, "read license file") | ||
} | ||
|
||
return loadLicense(string(licenseData)) | ||
} | ||
|
||
func loadLicense(licenseData string) (*kotsv1beta1.License, error) { | ||
decode := scheme.Codecs.UniversalDeserializer().Decode | ||
obj, _, err := decode([]byte(licenseData), nil, nil) | ||
if err != nil { | ||
return nil, errors.Wrap(err, "decode license data") | ||
} | ||
|
||
return obj.(*kotsv1beta1.License), nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
package main | ||
|
||
import "C" | ||
|
||
import ( | ||
"fmt" | ||
"io/ioutil" | ||
"os" | ||
"path/filepath" | ||
|
||
"github.com/replicatedhq/kots/pkg/pull" | ||
) | ||
|
||
//export UpdateDownload | ||
func UpdateDownload(socket, fromArchivePath, cursor string) { | ||
go func() { | ||
var ffiResult *FFIResult | ||
|
||
statusClient, err := connectToStatusServer(socket) | ||
if err != nil { | ||
fmt.Printf("failed to connect to status server: %s\n", err) | ||
return | ||
} | ||
defer func() { | ||
statusClient.end(ffiResult) | ||
}() | ||
|
||
tmpRoot, err := ioutil.TempDir("", "kots") | ||
if err != nil { | ||
fmt.Printf("failed to create temp path: %s\n", err.Error()) | ||
ffiResult = NewFFIResult(-1).WithError(err) | ||
return | ||
} | ||
defer os.RemoveAll(tmpRoot) | ||
|
||
tarGz, err := extractArchive(tmpRoot, fromArchivePath) | ||
if err != nil { | ||
fmt.Printf("failed to extract archive: %s\n", err.Error()) | ||
ffiResult = NewFFIResult(-1).WithError(err) | ||
return | ||
} | ||
|
||
installationFilePath := filepath.Join(tmpRoot, "upstream", "userdata", "installation.yaml") | ||
beforeCursor, err := readCursorFromPath(installationFilePath) | ||
if err != nil { | ||
fmt.Printf("failed to read cursor file: %s\n", err.Error()) | ||
ffiResult = NewFFIResult(-1).WithError(err) | ||
return | ||
} | ||
|
||
expectedLicenseFile := filepath.Join(tmpRoot, "upstream", "userdata", "license.yaml") | ||
license, err := loadLicenseFromPath(expectedLicenseFile) | ||
if err != nil { | ||
fmt.Printf("failed to load license: %s\n", err.Error()) | ||
ffiResult = NewFFIResult(-1).WithError(err) | ||
return | ||
} | ||
|
||
pullOptions := pull.PullOptions{ | ||
LicenseFile: expectedLicenseFile, | ||
ConfigFile: filepath.Join(tmpRoot, "upstream", "userdata", "config.yaml"), | ||
UpdateCursor: cursor, | ||
RootDir: tmpRoot, | ||
ExcludeKotsKinds: true, | ||
ExcludeAdminConsole: true, | ||
CreateAppDir: false, | ||
} | ||
|
||
if _, err := pull.Pull(fmt.Sprintf("replicated://%s", license.Spec.AppSlug), pullOptions); err != nil { | ||
fmt.Printf("failed to pull upstream: %s\n", err.Error()) | ||
ffiResult = NewFFIResult(-1).WithError(err) | ||
return | ||
} | ||
|
||
afterCursor, err := readCursorFromPath(installationFilePath) | ||
if err != nil { | ||
fmt.Printf("failed to read cursor file after update: %s\n", err.Error()) | ||
ffiResult = NewFFIResult(-1).WithError(err) | ||
return | ||
} | ||
|
||
fmt.Printf("Result of checking for updates for %s: Before: %s, After %s\n", license.Spec.AppSlug, beforeCursor, afterCursor) | ||
|
||
isUpdateAvailable := string(beforeCursor) != string(afterCursor) | ||
if !isUpdateAvailable { | ||
ffiResult = NewFFIResult(0) | ||
return | ||
} | ||
|
||
paths := []string{ | ||
filepath.Join(tmpRoot, "upstream"), | ||
filepath.Join(tmpRoot, "base"), | ||
filepath.Join(tmpRoot, "overlays"), | ||
} | ||
|
||
err = os.Remove(fromArchivePath) | ||
if err != nil { | ||
fmt.Printf("failed to delete archive to replace: %s\n", err.Error()) | ||
ffiResult = NewFFIResult(-1).WithError(err) | ||
return | ||
} | ||
|
||
if err := tarGz.Archive(paths, fromArchivePath); err != nil { | ||
fmt.Printf("failed to write archive: %s\n", err.Error()) | ||
ffiResult = NewFFIResult(-1).WithError(err) | ||
return | ||
} | ||
|
||
ffiResult = NewFFIResult(1) | ||
}() | ||
} |
Oops, something went wrong.