Skip to content

Commit

Permalink
feat: install extensions from external registries
Browse files Browse the repository at this point in the history
  • Loading branch information
Marcin Nowak-Liebiediew committed Jul 20, 2023
1 parent d463526 commit da6b933
Show file tree
Hide file tree
Showing 12 changed files with 416 additions and 79 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

78 changes: 78 additions & 0 deletions e2e/tests-dfx/extension.bash
Original file line number Diff line number Diff line change
Expand Up @@ -209,3 +209,81 @@ EOF
assert_command dfx extension run test_extension abc --the-another-param 464646 --the-param 123 456 789
assert_eq "abc --the-another-param 464646 --the-param 123 456 789 --dfx-cache-path $CACHE_DIR"
}

@test "install extension from external registry" {
# strip semver suffix
DFX_VERSION=$(dfx --version | sed 's/-.*//' | cut -d ' ' -f 2)
# find unoocupied port
port=49152
while lsof -i :$port > /dev/null 2>&1
do
port=$((port+1))
done

cat > test_extension << "EOF"
#!/usr/bin/env bash
echo $@
EOF
mkdir -p test_extension-v0.1.0-unknown-linux-gnu-x86_64
mv test_extension test_extension-v0.1.0-unknown-linux-gnu-x86_64
cp -r test_extension-v0.1.0-unknown-linux-gnu-x86_64 test_extension-v0.1.0-aarch64-apple-darwin
cp -r test_extension-v0.1.0-unknown-linux-gnu-x86_64 test_extension-v0.1.0-x86_64-apple-darwin
tar -czf test_extension-v0.1.0-unknown-linux-gnu-x86_64.tar.gz test_extension-v0.1.0-unknown-linux-gnu-x86_64
tar -czf test_extension-v0.1.0-aarch64-apple-darwin.tar.gz test_extension-v0.1.0-aarch64-apple-darwin
tar -czf test_extension-v0.1.0-x86_64-apple-darwin.tar.gz test_extension-v0.1.0-x86_64-apple-darwin
cat > registry.json <<EOF
{
"compatibility": {
"$DFX_VERSION": {
"test_extension": {
"versions": ["0.1.0"]
}
}
},
"extensions": {
"test_extension": {
"0.1.0": {
"homepage": "https://github.com/dfinity/sdk",
"authors": "DFINITY",
"summary": "A foo extension",
"categories": ["development"],
"keywords": ["development"],
"description": "A longer description.",
"subcommands": {},
"binaries": {
"unknow-linux-gnu-x86_64": {
"url": "http://localhost:$port/test_extension-v0.1.0-unknown-linux-gnu-x86_64.tar.gz",
"sha256": "$(shasum -a 256 test_extension-v0.1.0-unknown-linux-gnu-x86_64.tar.gz | cut -d ' ' -f 1)"
},
"apple-darwin-x86_64": {
"url": "http://localhost:$port/test_extension-v0.1.0-x86_64-apple-darwin.tar.gz ",
"sha256": "$(shasum -a 256 test_extension-v0.1.0-x86_64-apple-darwin.tar.gz | cut -d ' ' -f 1)"
},
"apple-darwin-aarch64": {
"url": "http://localhost:$port/test_extension-v0.1.0-aarch64-apple-darwin.tar.gz ",
"sha256": "$(shasum -a 256 test_extension-v0.1.0-aarch64-apple-darwin.tar.gz | cut -d ' ' -f 1)"
}
}
}
}
}
}
EOF

python3 -m http.server "$port" &
pid=$!

# # Wait until the server is up
while ! echo exit | nc localhost "$port"; do sleep 1; done
echo "Server is up"
echo yes | (
assert_command dfx extension install test_extension --registry "http://localhost:$port/registry.json"
)
kill $pid

assert_command dfx extension list
assert_match "test_extension"
assert_command dfx test_extension
assert_eq "--dfx-cache-path $(dfx cache show)"
}
3 changes: 2 additions & 1 deletion src/dfx-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,13 @@ sec1 = { workspace = true, features = ["std"] }
semver = { workspace = true, features = ["serde"] }
serde.workspace = true
serde_json.workspace = true
sha2.workspace = true
slog = { workspace = true, features = ["max_level_trace"] }
tar.workspace = true
tempfile.workspace = true
thiserror.workspace = true
tiny-bip39 = "1.0.0"
url.workspace = true
url = { workspace = true, features = [ "serde" ] }

[dev-dependencies]
proptest = "1.0"
Expand Down
31 changes: 29 additions & 2 deletions src/dfx-core/src/error/extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ use thiserror::Error;

#[derive(Error, Debug)]
pub enum ExtensionError {
#[error(transparent)]
Io(#[from] crate::error::unified_io::UnifiedIoError),

// errors related to extension directory management
#[error("Cannot find cache directory: '{0}'")]
FindCacheDirectoryFailed(crate::error::cache::CacheError),
Expand Down Expand Up @@ -54,12 +57,36 @@ pub enum ExtensionError {
#[error("Cannot create temporary directory at '{0}': {1}")]
CreateTemporaryDirectoryFailed(std::path::PathBuf, std::io::Error),

#[error(transparent)]
Io(#[from] crate::error::fs::FsError),
#[error("Failed to download extension: checksum of the downloaded archive (sha256:{0}) (downloaded from: '{1}') doesn't match the one provided in the manifest (sha256:{2})")]
ChecksumMismatch(String, String, String),

#[error("Platform '{0}' is not supported.")]
PlatformNotSupported(String),

// errors related to installing extensions from 3rd party registries
#[error("Extension manifest URL '{0}' is not valid: {1}")]
InvalidExternalManifestUrl(String, url::ParseError),

#[error("Entry 'binaries' not found in extension manifest entry.")]
BinaryEntryNotFoundInExtensionManifest,

#[error("Entry 'extensions.{0}' not found in extension manifest entry.")]
ExtensionNameNotFoundInManifest(String),

#[error("Extension '{0}' was found in the manifest in both 'comppatibility' and 'extensions' entries, however, the latest compatible version of the extension ({1}) could not be found in 'extensions' entry. Please contact the extension author.")]
MalformedManifestExtensionVersionNotFound(String, semver::Version),

#[error(
"Manifest downloaded from '{}' does not contain 'binaries' object for extension {}-v{}."
, _0.0, _0.1, _0.2)]
BinariesObejectNotFoundInManifest(Box<(url::Url, String, semver::Version)>),

#[error("Platform '{}' and architecture '{}' is not supported for extension '{}' defined in manifest downloaded from '{}'.", _0.0, _0.1, _0.2, _0.3)]
PlatformArchCombinationNotFoundInManifest(Box<(url::Url, String, String, String)>),

#[error("Cannot save extension manifest: {0}")]
SaveExtensionManifestFailed(crate::error::structured_file::StructuredFileError),

// errors related to uninstalling extensions
#[error("Cannot uninstall extension: {0}")]
InsufficientPermissionsToDeleteExtensionDirectory(crate::error::fs::FsError),
Expand Down
Loading

0 comments on commit da6b933

Please sign in to comment.