Run executes the PluginInstall action
(_ context.Context, opts *PluginInstallOptions)
| 161 | |
| 162 | // Run executes the PluginInstall action |
| 163 | func (action *PluginInstall) Run(_ context.Context, opts *PluginInstallOptions) (*PluginInstallResult, error) { |
| 164 | action.cfg.Logger.Debug().Str("file", opts.File).Msg("Downloading plugin") |
| 165 | |
| 166 | // create plugins directory if it doesn't exist |
| 167 | pluginsDir := plugins.GetPluginsDir("chainloop") |
| 168 | if err := os.MkdirAll(pluginsDir, 0755); err != nil { |
| 169 | action.cfg.Logger.Error().Err(err).Str("directory", pluginsDir).Msg("Failed to create plugins directory") |
| 170 | return nil, fmt.Errorf("failed to create plugins directory: %w", err) |
| 171 | } |
| 172 | |
| 173 | // determine filename |
| 174 | filename := filepath.Base(opts.File) |
| 175 | if filename == "." || filename == "/" { |
| 176 | action.cfg.Logger.Error().Str("file", opts.File).Msg("Invalid URL or object key, could not determine filename") |
| 177 | return nil, fmt.Errorf("invalid URL or object key, could not determine filename") |
| 178 | } |
| 179 | |
| 180 | filePath := filepath.Join(pluginsDir, filename) |
| 181 | |
| 182 | // create a temporary file for downloading |
| 183 | tempFilePath := filePath + ".tmp" |
| 184 | tempFile, err := os.Create(tempFilePath) |
| 185 | if err != nil { |
| 186 | action.cfg.Logger.Error().Err(err).Str("path", tempFilePath).Msg("Failed to create temporary file") |
| 187 | return nil, fmt.Errorf("failed to create temporary file: %w", err) |
| 188 | } |
| 189 | defer tempFile.Close() |
| 190 | |
| 191 | rawFileContents, err := LoadFileOrURL(opts.File) |
| 192 | if err != nil { |
| 193 | return nil, fmt.Errorf("failed to load file from a given URL: %w", err) |
| 194 | } |
| 195 | |
| 196 | // write to the temporary file |
| 197 | _, err = tempFile.Write(rawFileContents) |
| 198 | if err != nil { |
| 199 | return nil, fmt.Errorf("failed to write file to temporary file: %w", err) |
| 200 | } |
| 201 | |
| 202 | // close the file before renaming |
| 203 | tempFile.Close() |
| 204 | |
| 205 | // rename the temporary file to the final file |
| 206 | if err := os.Rename(tempFilePath, filePath); err != nil { |
| 207 | os.Remove(tempFilePath) |
| 208 | action.cfg.Logger.Error().Err(err).Str("tempPath", tempFilePath).Str("finalPath", filePath).Msg("Failed to rename temporary file") |
| 209 | return nil, fmt.Errorf("failed to rename temporary file: %w", err) |
| 210 | } |
| 211 | |
| 212 | // Set executable permissions for the plugin file |
| 213 | // This is needed, so we can run the plugin and serve the gRPC |
| 214 | if err := os.Chmod(filePath, 0755); err != nil { |
| 215 | action.cfg.Logger.Error().Err(err).Str("path", filePath).Msg("Failed to set executable permissions") |
| 216 | return nil, fmt.Errorf("failed to set executable permissions: %w", err) |
| 217 | } |
| 218 | |
| 219 | action.cfg.Logger.Debug().Str("file", opts.File).Str("path", filePath).Msg("Plugin downloaded successfully") |
| 220 | return &PluginInstallResult{ |
nothing calls this directly
no test coverage detected