@@ -17,6 +17,7 @@ import (
17
17
)
18
18
19
19
const activePluginsFile = "/internal/active-plugins.txt"
20
+ const updatePluginsFile = "/internal/update-plugins.txt"
20
21
21
22
type PluginInfo struct {
22
23
Name string `json:"name"`
@@ -652,6 +653,114 @@ func (bl *FxBlockchain) setPluginStatus(pluginName, status string) error {
652
653
return nil
653
654
}
654
655
656
+ func (bl * FxBlockchain ) updatePluginImpl (ctx context.Context , pluginName string ) ([]byte , error ) {
657
+ log .Debug ("updatePluginImpl started" )
658
+
659
+ // Check for context cancellation
660
+ select {
661
+ case <- ctx .Done ():
662
+ return json .Marshal (map [string ]interface {}{
663
+ "msg" : "Operation cancelled" ,
664
+ "status" : false ,
665
+ })
666
+ default :
667
+ }
668
+
669
+ // Read existing update plugins
670
+ updatePlugins , err := bl .readUpdatePlugins ()
671
+ if err != nil {
672
+ return json .Marshal (map [string ]interface {}{
673
+ "msg" : fmt .Sprintf ("Failed to read update plugins: %v" , err ),
674
+ "status" : false ,
675
+ })
676
+ }
677
+ log .Debugw ("updatePluginImpl plugins:" , "updatePlugins" , updatePlugins , "pluginName" , pluginName )
678
+
679
+ // Check if plugin already exists in update list
680
+ for _ , p := range updatePlugins {
681
+ if p == pluginName {
682
+ return json .Marshal (map [string ]interface {}{
683
+ "msg" : "Plugin already in update queue" ,
684
+ "status" : true ,
685
+ })
686
+ }
687
+ }
688
+
689
+ // Append new plugin to update list
690
+ updatePlugins = append (updatePlugins , pluginName )
691
+
692
+ // Write updated list back to file
693
+ if err := bl .writeUpdatePlugins (updatePlugins ); err != nil {
694
+ return json .Marshal (map [string ]interface {}{
695
+ "msg" : fmt .Sprintf ("Failed to write update plugins: %v" , err ),
696
+ "status" : false ,
697
+ })
698
+ }
699
+
700
+ return json .Marshal (map [string ]interface {}{
701
+ "msg" : "Plugin update queued successfully" ,
702
+ "status" : true ,
703
+ })
704
+ }
705
+
706
+ func (bl * FxBlockchain ) HandleUpdatePlugin (w http.ResponseWriter , r * http.Request ) {
707
+ var req struct {
708
+ PluginName string `json:"plugin_name"`
709
+ }
710
+ if err := json .NewDecoder (r .Body ).Decode (& req ); err != nil {
711
+ http .Error (w , "Invalid request body" , http .StatusBadRequest )
712
+ return
713
+ }
714
+ result , err := bl .updatePluginImpl (r .Context (), req .PluginName )
715
+ if err != nil {
716
+ http .Error (w , err .Error (), http .StatusInternalServerError )
717
+ return
718
+ }
719
+ w .Header ().Set ("Content-Type" , "application/json" )
720
+ w .Write (result )
721
+ }
722
+
723
+ func (bl * FxBlockchain ) UpdatePlugin (ctx context.Context , to peer.ID , pluginName string ) ([]byte , error ) {
724
+ if bl .allowTransientConnection {
725
+ ctx = network .WithUseTransient (ctx , "fx.blockchain" )
726
+ }
727
+
728
+ var buf bytes.Buffer
729
+ if err := json .NewEncoder (& buf ).Encode (map [string ]string {"plugin_name" : pluginName }); err != nil {
730
+ return nil , err
731
+ }
732
+
733
+ req , err := http .NewRequestWithContext (ctx , http .MethodPost , "http://" + to .String ()+ ".invalid/" + actionUpdatePlugin , & buf )
734
+ if err != nil {
735
+ return nil , err
736
+ }
737
+ resp , err := bl .c .Do (req )
738
+ if err != nil {
739
+ return nil , err
740
+ }
741
+ defer resp .Body .Close ()
742
+ return io .ReadAll (resp .Body )
743
+ }
744
+
745
+ func (bl * FxBlockchain ) readUpdatePlugins () ([]string , error ) {
746
+ content , err := os .ReadFile (updatePluginsFile )
747
+ if err != nil {
748
+ if os .IsNotExist (err ) {
749
+ return []string {}, nil
750
+ }
751
+ return nil , fmt .Errorf ("failed to read update plugins file: %w" , err )
752
+ }
753
+ return strings .Split (strings .TrimSpace (string (content )), "\n " ), nil
754
+ }
755
+
756
+ func (bl * FxBlockchain ) writeUpdatePlugins (plugins []string ) error {
757
+ content := strings .Join (plugins , "\n " )
758
+ if err := os .WriteFile (updatePluginsFile , []byte (content ), 0644 ); err != nil {
759
+ return fmt .Errorf ("failed to write update plugins file: %w" , err )
760
+ }
761
+ return nil
762
+ }
763
+
655
764
func (bl * FxBlockchain ) handlePluginAction (ctx context.Context , from peer.ID , w http.ResponseWriter , r * http.Request , action string ) {
656
765
log := log .With ("action" , action , "from" , from )
657
766
log .Debug ("started handlePluginAction" )
@@ -702,6 +811,9 @@ func (bl *FxBlockchain) handlePluginAction(ctx context.Context, from peer.ID, w
702
811
case actionGetInstallStatus :
703
812
log .Debugw ("handlePluginAction: calling method actionGetInstallStatus" , "PluginName" , req .PluginName )
704
813
result , err = bl .getInstallStatusImpl (ctx , req .PluginName )
814
+ case actionUpdatePlugin :
815
+ log .Debug ("handlePluginAction: calling method actionUpdatePlugin" )
816
+ result , err = bl .updatePluginImpl (ctx , req .PluginName )
705
817
default :
706
818
log .Error ("Invalid action" )
707
819
http .Error (w , "Invalid action" , http .StatusBadRequest )
0 commit comments