Skip to content

Commit 783be00

Browse files
committed
Added 'enable_unsafe_install' option for platforms.
1 parent 7ee4cf7 commit 783be00

11 files changed

+63
-29
lines changed

commands/instances.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ import (
4646
"google.golang.org/grpc/status"
4747
)
4848

49-
func installTool(ctx context.Context, pm *packagemanager.PackageManager, tool *cores.ToolRelease, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) error {
49+
func installTool(ctx context.Context, pm *packagemanager.PackageManager, tool *cores.ToolRelease, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB, checks resources.IntegrityCheckMode) error {
5050
pme, release := pm.NewExplorer()
5151
defer release()
5252

@@ -55,7 +55,7 @@ func installTool(ctx context.Context, pm *packagemanager.PackageManager, tool *c
5555
return errors.New(i18n.Tr("downloading %[1]s tool: %[2]s", tool, err))
5656
}
5757
taskCB(&rpc.TaskProgress{Completed: true})
58-
if err := pme.InstallTool(tool, taskCB, true); err != nil {
58+
if err := pme.InstallTool(tool, taskCB, true, checks); err != nil {
5959
return errors.New(i18n.Tr("installing %[1]s tool: %[2]s", tool, err))
6060
}
6161
return nil
@@ -281,7 +281,7 @@ func (s *arduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCor
281281
// Install builtin tools if necessary
282282
if len(builtinToolsToInstall) > 0 {
283283
for _, toolRelease := range builtinToolsToInstall {
284-
if err := installTool(ctx, pmb.Build(), toolRelease, downloadCallback, taskCallback); err != nil {
284+
if err := installTool(ctx, pmb.Build(), toolRelease, downloadCallback, taskCallback, resources.IntegrityCheckFull); err != nil {
285285
e := &cmderrors.InitFailedError{
286286
Code: codes.Internal,
287287
Cause: err,
@@ -393,7 +393,7 @@ func (s *arduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCor
393393

394394
// Install library
395395
taskCallback(&rpc.TaskProgress{Name: i18n.Tr("Installing library %s", libraryRef)})
396-
if err := libRelease.Resource.Install(pme.DownloadDir, libRoot, libDir); err != nil {
396+
if err := libRelease.Resource.Install(pme.DownloadDir, libRoot, libDir, resources.IntegrityCheckFull); err != nil {
397397
taskCallback(&rpc.TaskProgress{Name: i18n.Tr("Error installing library %s", libraryRef)})
398398
e := &cmderrors.FailedLibraryInstallError{Cause: err}
399399
responseError(e.GRPCStatus())

commands/service_library_install.go

+4-3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"github.com/arduino/arduino-cli/internal/arduino/libraries"
2626
"github.com/arduino/arduino-cli/internal/arduino/libraries/librariesindex"
2727
"github.com/arduino/arduino-cli/internal/arduino/libraries/librariesmanager"
28+
"github.com/arduino/arduino-cli/internal/arduino/resources"
2829
"github.com/arduino/arduino-cli/internal/i18n"
2930
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
3031
"github.com/arduino/go-paths-helper"
@@ -159,7 +160,7 @@ func (s *arduinoCoreServerImpl) LibraryInstall(req *rpc.LibraryInstallRequest, s
159160
if err := downloadLibrary(ctx, downloadsDir, libRelease, downloadCB, taskCB, downloadReason, s.settings); err != nil {
160161
return err
161162
}
162-
if err := installLibrary(lmi, downloadsDir, libRelease, installTask, taskCB); err != nil {
163+
if err := installLibrary(lmi, downloadsDir, libRelease, installTask, taskCB, resources.IntegrityCheckFull); err != nil {
163164
return err
164165
}
165166
}
@@ -179,7 +180,7 @@ func (s *arduinoCoreServerImpl) LibraryInstall(req *rpc.LibraryInstallRequest, s
179180
return nil
180181
}
181182

182-
func installLibrary(lmi *librariesmanager.Installer, downloadsDir *paths.Path, libRelease *librariesindex.Release, installTask *librariesmanager.LibraryInstallPlan, taskCB rpc.TaskProgressCB) error {
183+
func installLibrary(lmi *librariesmanager.Installer, downloadsDir *paths.Path, libRelease *librariesindex.Release, installTask *librariesmanager.LibraryInstallPlan, taskCB rpc.TaskProgressCB, checks resources.IntegrityCheckMode) error {
183184
taskCB(&rpc.TaskProgress{Name: i18n.Tr("Installing %s", libRelease)})
184185
logrus.WithField("library", libRelease).Info("Installing library")
185186

@@ -193,7 +194,7 @@ func installLibrary(lmi *librariesmanager.Installer, downloadsDir *paths.Path, l
193194

194195
installPath := installTask.TargetPath
195196
tmpDirPath := installPath.Parent()
196-
if err := libRelease.Resource.Install(downloadsDir, tmpDirPath, installPath); err != nil {
197+
if err := libRelease.Resource.Install(downloadsDir, tmpDirPath, installPath, checks); err != nil {
197198
return &cmderrors.FailedLibraryInstallError{Cause: err}
198199
}
199200

commands/service_platform_install.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"github.com/arduino/arduino-cli/commands/cmderrors"
2323
"github.com/arduino/arduino-cli/commands/internal/instances"
2424
"github.com/arduino/arduino-cli/internal/arduino/cores/packagemanager"
25+
"github.com/arduino/arduino-cli/internal/arduino/resources"
2526
"github.com/arduino/arduino-cli/internal/i18n"
2627
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
2728
)
@@ -95,7 +96,11 @@ func (s *arduinoCoreServerImpl) PlatformInstall(req *rpc.PlatformInstallRequest,
9596
}
9697
}
9798

98-
if err := pme.DownloadAndInstallPlatformAndTools(ctx, platformRelease, tools, downloadCB, taskCB, req.GetSkipPostInstall(), req.GetSkipPreUninstall()); err != nil {
99+
checks := resources.IntegrityCheckFull
100+
if s.settings.BoardManagerEnableUnsafeInstall() {
101+
checks = resources.IntegrityCheckNone
102+
}
103+
if err := pme.DownloadAndInstallPlatformAndTools(ctx, platformRelease, tools, downloadCB, taskCB, req.GetSkipPostInstall(), req.GetSkipPreUninstall(), checks); err != nil {
99104
return err
100105
}
101106

commands/service_platform_upgrade.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"github.com/arduino/arduino-cli/commands/internal/instances"
2222
"github.com/arduino/arduino-cli/internal/arduino/cores"
2323
"github.com/arduino/arduino-cli/internal/arduino/cores/packagemanager"
24+
"github.com/arduino/arduino-cli/internal/arduino/resources"
2425
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
2526
)
2627

@@ -75,7 +76,11 @@ func (s *arduinoCoreServerImpl) PlatformUpgrade(req *rpc.PlatformUpgradeRequest,
7576
Package: req.GetPlatformPackage(),
7677
PlatformArchitecture: req.GetArchitecture(),
7778
}
78-
platform, err := pme.DownloadAndInstallPlatformUpgrades(ctx, ref, downloadCB, taskCB, req.GetSkipPostInstall(), req.GetSkipPreUninstall())
79+
checks := resources.IntegrityCheckFull
80+
if s.settings.BoardManagerEnableUnsafeInstall() {
81+
checks = resources.IntegrityCheckNone
82+
}
83+
platform, err := pme.DownloadAndInstallPlatformUpgrades(ctx, ref, downloadCB, taskCB, req.GetSkipPostInstall(), req.GetSkipPreUninstall(), checks)
7984
if err != nil {
8085
return platform, err
8186
}

internal/arduino/cores/packagemanager/install_uninstall.go

+12-10
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"github.com/arduino/arduino-cli/commands/cmderrors"
2626
"github.com/arduino/arduino-cli/internal/arduino/cores"
2727
"github.com/arduino/arduino-cli/internal/arduino/cores/packageindex"
28+
"github.com/arduino/arduino-cli/internal/arduino/resources"
2829
"github.com/arduino/arduino-cli/internal/i18n"
2930
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
3031
"github.com/arduino/go-paths-helper"
@@ -40,6 +41,7 @@ func (pme *Explorer) DownloadAndInstallPlatformUpgrades(
4041
taskCB rpc.TaskProgressCB,
4142
skipPostInstall bool,
4243
skipPreUninstall bool,
44+
checks resources.IntegrityCheckMode,
4345
) (*cores.PlatformRelease, error) {
4446
if platformRef.PlatformVersion != nil {
4547
return nil, &cmderrors.InvalidArgumentError{Message: i18n.Tr("Upgrade doesn't accept parameters with version")}
@@ -64,7 +66,7 @@ func (pme *Explorer) DownloadAndInstallPlatformUpgrades(
6466
if err != nil {
6567
return nil, &cmderrors.PlatformNotFoundError{Platform: platformRef.String()}
6668
}
67-
if err := pme.DownloadAndInstallPlatformAndTools(ctx, platformRelease, tools, downloadCB, taskCB, skipPostInstall, skipPreUninstall); err != nil {
69+
if err := pme.DownloadAndInstallPlatformAndTools(ctx, platformRelease, tools, downloadCB, taskCB, skipPostInstall, skipPreUninstall, checks); err != nil {
6870
return nil, err
6971
}
7072

@@ -78,7 +80,7 @@ func (pme *Explorer) DownloadAndInstallPlatformAndTools(
7880
ctx context.Context,
7981
platformRelease *cores.PlatformRelease, requiredTools []*cores.ToolRelease,
8082
downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB,
81-
skipPostInstall bool, skipPreUninstall bool) error {
83+
skipPostInstall bool, skipPreUninstall bool, checks resources.IntegrityCheckMode) error {
8284
log := pme.log.WithField("platform", platformRelease)
8385

8486
// Prerequisite checks before install
@@ -106,7 +108,7 @@ func (pme *Explorer) DownloadAndInstallPlatformAndTools(
106108

107109
// Install tools first
108110
for _, tool := range toolsToInstall {
109-
if err := pme.InstallTool(tool, taskCB, skipPostInstall); err != nil {
111+
if err := pme.InstallTool(tool, taskCB, skipPostInstall, checks); err != nil {
110112
return err
111113
}
112114
}
@@ -138,7 +140,7 @@ func (pme *Explorer) DownloadAndInstallPlatformAndTools(
138140
}
139141

140142
// Install
141-
if err := pme.InstallPlatform(platformRelease); err != nil {
143+
if err := pme.InstallPlatform(platformRelease, checks); err != nil {
142144
log.WithError(err).Error("Cannot install platform")
143145
return &cmderrors.FailedInstallError{Message: i18n.Tr("Cannot install platform"), Cause: err}
144146
}
@@ -196,18 +198,18 @@ func (pme *Explorer) DownloadAndInstallPlatformAndTools(
196198
}
197199

198200
// InstallPlatform installs a specific release of a platform.
199-
func (pme *Explorer) InstallPlatform(platformRelease *cores.PlatformRelease) error {
201+
func (pme *Explorer) InstallPlatform(platformRelease *cores.PlatformRelease, checks resources.IntegrityCheckMode) error {
200202
destDir := pme.PackagesDir.Join(
201203
platformRelease.Platform.Package.Name,
202204
"hardware",
203205
platformRelease.Platform.Architecture,
204206
platformRelease.Version.String())
205-
return pme.InstallPlatformInDirectory(platformRelease, destDir)
207+
return pme.InstallPlatformInDirectory(platformRelease, destDir, checks)
206208
}
207209

208210
// InstallPlatformInDirectory installs a specific release of a platform in a specific directory.
209-
func (pme *Explorer) InstallPlatformInDirectory(platformRelease *cores.PlatformRelease, destDir *paths.Path) error {
210-
if err := platformRelease.Resource.Install(pme.DownloadDir, pme.tempDir, destDir); err != nil {
211+
func (pme *Explorer) InstallPlatformInDirectory(platformRelease *cores.PlatformRelease, destDir *paths.Path, checks resources.IntegrityCheckMode) error {
212+
if err := platformRelease.Resource.Install(pme.DownloadDir, pme.tempDir, destDir, checks); err != nil {
211213
return errors.New(i18n.Tr("installing platform %[1]s: %[2]s", platformRelease, err))
212214
}
213215
if d, err := destDir.Abs(); err == nil {
@@ -320,7 +322,7 @@ func (pme *Explorer) UninstallPlatform(platformRelease *cores.PlatformRelease, t
320322
}
321323

322324
// InstallTool installs a specific release of a tool.
323-
func (pme *Explorer) InstallTool(toolRelease *cores.ToolRelease, taskCB rpc.TaskProgressCB, skipPostInstall bool) error {
325+
func (pme *Explorer) InstallTool(toolRelease *cores.ToolRelease, taskCB rpc.TaskProgressCB, skipPostInstall bool, checks resources.IntegrityCheckMode) error {
324326
log := pme.log.WithField("Tool", toolRelease)
325327

326328
if toolRelease.IsInstalled() {
@@ -343,7 +345,7 @@ func (pme *Explorer) InstallTool(toolRelease *cores.ToolRelease, taskCB rpc.Task
343345
"tools",
344346
toolRelease.Tool.Name,
345347
toolRelease.Version.String())
346-
err := toolResource.Install(pme.DownloadDir, pme.tempDir, destDir)
348+
err := toolResource.Install(pme.DownloadDir, pme.tempDir, destDir, checks)
347349
if err != nil {
348350
log.WithError(err).Warn("Cannot install tool")
349351
return &cmderrors.FailedInstallError{Message: i18n.Tr("Cannot install tool %s", toolRelease), Cause: err}

internal/arduino/cores/packagemanager/profiles.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ func (pmb *Builder) installMissingProfilePlatform(ctx context.Context, platformR
132132

133133
// Perform install
134134
taskCB(&rpc.TaskProgress{Name: i18n.Tr("Installing platform %s", tmpPlatformRelease)})
135-
if err := tmpPme.InstallPlatformInDirectory(tmpPlatformRelease, destDir); err != nil {
135+
if err := tmpPme.InstallPlatformInDirectory(tmpPlatformRelease, destDir, resources.IntegrityCheckFull); err != nil {
136136
taskCB(&rpc.TaskProgress{Name: i18n.Tr("Error installing platform %s", tmpPlatformRelease)})
137137
return &cmderrors.FailedInstallError{Message: i18n.Tr("Error installing platform %s", tmpPlatformRelease), Cause: err}
138138
}
@@ -183,7 +183,7 @@ func (pmb *Builder) installMissingProfileTool(ctx context.Context, toolRelease *
183183

184184
// Install tool
185185
taskCB(&rpc.TaskProgress{Name: i18n.Tr("Installing tool %s", toolRelease)})
186-
if err := toolResource.Install(pmb.DownloadDir, tmp, destDir); err != nil {
186+
if err := toolResource.Install(pmb.DownloadDir, tmp, destDir, resources.IntegrityCheckFull); err != nil {
187187
taskCB(&rpc.TaskProgress{Name: i18n.Tr("Error installing tool %s", toolRelease)})
188188
return &cmderrors.FailedInstallError{Message: i18n.Tr("Error installing tool %s", toolRelease), Cause: err}
189189
}

internal/arduino/resources/install.go

+15-6
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,27 @@ import (
2626
"go.bug.st/cleanup"
2727
)
2828

29+
type IntegrityCheckMode int
30+
31+
const (
32+
IntegrityCheckFull IntegrityCheckMode = iota
33+
IntegrityCheckNone
34+
)
35+
2936
// Install installs the resource in three steps:
3037
// - the archive is unpacked in a temporary subdir of tempPath
3138
// - there should be only one root dir in the unpacked content
3239
// - the only root dir is moved/renamed to/as the destination directory
3340
// Note that tempPath and destDir must be on the same filesystem partition
3441
// otherwise the last step will fail.
35-
func (release *DownloadResource) Install(downloadDir, tempPath, destDir *paths.Path) error {
36-
// Check the integrity of the package
37-
if ok, err := release.TestLocalArchiveIntegrity(downloadDir); err != nil {
38-
return errors.New(i18n.Tr("testing local archive integrity: %s", err))
39-
} else if !ok {
40-
return errors.New(i18n.Tr("checking local archive integrity"))
42+
func (release *DownloadResource) Install(downloadDir, tempPath, destDir *paths.Path, checks IntegrityCheckMode) error {
43+
if checks != IntegrityCheckNone {
44+
// Check the integrity of the package
45+
if ok, err := release.TestLocalArchiveIntegrity(downloadDir); err != nil {
46+
return errors.New(i18n.Tr("testing local archive integrity: %s", err))
47+
} else if !ok {
48+
return errors.New(i18n.Tr("checking local archive integrity"))
49+
}
4150
}
4251

4352
// Create a temporary dir to extract package

internal/arduino/resources/install_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ func TestInstallPlatform(t *testing.T) {
4444
Size: 157,
4545
}
4646

47-
require.NoError(t, r.Install(downloadDir, tempPath, destDir))
47+
require.NoError(t, r.Install(downloadDir, tempPath, destDir, IntegrityCheckFull))
4848
})
4949

5050
tests := []struct {
@@ -82,7 +82,7 @@ func TestInstallPlatform(t *testing.T) {
8282
require.NoError(t, err)
8383
require.NoError(t, os.WriteFile(path.Join(downloadDir.String(), testFileName), origin, 0644))
8484

85-
err = test.downloadResource.Install(downloadDir, tempPath, destDir)
85+
err = test.downloadResource.Install(downloadDir, tempPath, destDir, IntegrityCheckFull)
8686
require.Error(t, err)
8787
require.Contains(t, err.Error(), test.error)
8888
})

internal/cli/configuration/board_manager.go

+7
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,10 @@ func (settings *Settings) BoardManagerAdditionalUrls() []string {
2121
}
2222
return settings.Defaults.GetStringSlice("board_manager.additional_urls")
2323
}
24+
25+
func (settings *Settings) BoardManagerEnableUnsafeInstall() bool {
26+
if v, ok, _ := settings.GetBoolOk("board_manager.enable_unsafe_install"); ok {
27+
return v
28+
}
29+
return settings.Defaults.GetBool("board_manager.enable_unsafe_install")
30+
}

internal/cli/configuration/configuration.schema.json

+4
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313
"type": "string",
1414
"format": "uri"
1515
}
16+
},
17+
"enable_unsafe_install": {
18+
"description": "set to `true` to allow installation of packages that do not pass the checksum test. This is considered an unsafe installation method and should be used only for development purposes.",
19+
"type": "boolean"
1620
}
1721
},
1822
"type": "object"

internal/cli/configuration/defaults.go

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ func SetDefaults(settings *Settings) {
4141

4242
// Boards Manager
4343
setDefaultValueAndKeyTypeSchema("board_manager.additional_urls", []string{})
44+
setDefaultValueAndKeyTypeSchema("board_manager.enable_unsafe_install", false)
4445

4546
// arduino directories
4647
setDefaultValueAndKeyTypeSchema("directories.data", getDefaultArduinoDataDir())

0 commit comments

Comments
 (0)