xpk 0.10.1__py3-none-any.whl → 0.12.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. xpk/commands/cluster.py +270 -8
  2. xpk/commands/cluster_gcluster.py +2 -1
  3. xpk/commands/common.py +3 -3
  4. xpk/commands/info.py +12 -12
  5. xpk/commands/job.py +12 -10
  6. xpk/commands/kjob_common.py +2 -1
  7. xpk/commands/storage.py +1 -1
  8. xpk/commands/workload.py +12 -6
  9. xpk/core/blueprint/blueprint_generator.py +7 -7
  10. xpk/core/blueprint/blueprint_test.py +218 -0
  11. xpk/core/capacity.py +5 -3
  12. xpk/core/cluster.py +9 -7
  13. xpk/core/cluster_private.py +5 -1
  14. xpk/core/commands.py +3 -3
  15. xpk/core/config.py +3 -4
  16. xpk/core/config_test.py +71 -0
  17. xpk/core/docker_manager.py +1 -1
  18. xpk/core/docker_resources.py +1 -1
  19. xpk/core/filestore.py +7 -2
  20. xpk/core/gcloud_context.py +2 -2
  21. xpk/core/jobset.py +1 -1
  22. xpk/core/kjob.py +2 -1
  23. xpk/core/kueue.py +12 -4
  24. xpk/core/nap.py +20 -6
  25. xpk/core/nodepool.py +52 -19
  26. xpk/core/nodepool_test.py +82 -0
  27. xpk/core/resources.py +1 -7
  28. xpk/core/scheduling.py +1 -1
  29. xpk/core/storage.py +14 -14
  30. xpk/core/system_characteristics.py +267 -1081
  31. xpk/core/workload.py +11 -0
  32. xpk/core/workload_decorators/rdma_decorator.py +3 -2
  33. xpk/core/workload_decorators/storage_decorator.py +2 -1
  34. xpk/core/workload_decorators/tcpx_decorator.py +4 -2
  35. xpk/core/workload_decorators/tcpx_decorator_test.py +267 -0
  36. xpk/core/workload_decorators/tcpxo_decorator.py +2 -1
  37. xpk/core/workload_test.py +28 -0
  38. xpk/main.py +9 -10
  39. xpk/parser/cluster.py +67 -49
  40. xpk/parser/common.py +45 -36
  41. xpk/parser/storage.py +12 -13
  42. xpk/parser/workload.py +57 -39
  43. xpk/utils/console.py +2 -1
  44. {xpk-0.10.1.dist-info → xpk-0.12.0.dist-info}/METADATA +4 -1
  45. {xpk-0.10.1.dist-info → xpk-0.12.0.dist-info}/RECORD +49 -44
  46. {xpk-0.10.1.dist-info → xpk-0.12.0.dist-info}/WHEEL +0 -0
  47. {xpk-0.10.1.dist-info → xpk-0.12.0.dist-info}/entry_points.txt +0 -0
  48. {xpk-0.10.1.dist-info → xpk-0.12.0.dist-info}/licenses/LICENSE +0 -0
  49. {xpk-0.10.1.dist-info → xpk-0.12.0.dist-info}/top_level.txt +0 -0
xpk/parser/cluster.py CHANGED
@@ -29,7 +29,7 @@ from ..commands.cluster import (
29
29
  from ..commands.config import xpk_cfg
30
30
  from ..core.config import CFG_BUCKET_KEY
31
31
  from ..core.vertex import DEFAULT_VERTEX_TENSORBOARD_NAME
32
- from .common import add_shared_arguments
32
+ from .common import add_shared_arguments, ParserOrArgumentGroup
33
33
  from .validators import name_type
34
34
 
35
35
 
@@ -208,6 +208,14 @@ def set_cluster_create_pathways_parser(
208
208
  cluster_create_pathways_optional_arguments
209
209
  )
210
210
 
211
+ autoprovisioning_arguments = (
212
+ cluster_create_pathways_parser.add_argument_group(
213
+ 'Autoprovisioning Arguments',
214
+ 'Optional arguments for enabling autoprovisioning.',
215
+ )
216
+ )
217
+ add_autoprovisioning_arguments(autoprovisioning_arguments)
218
+
211
219
  ### Capacity arguments specific to "cluster create-pathways"
212
220
  cluster_create_pathways_capacity_arguments = (
213
221
  cluster_create_pathways_parser.add_argument_group(
@@ -529,15 +537,15 @@ def set_cluster_adapt_parser(cluster_adapt_parser: ArgumentParser):
529
537
  cluster_adapt_parser.set_defaults(func=cluster_adapt)
530
538
 
531
539
 
532
- def add_autoprovisioning_arguments(parser: ArgumentParser):
533
- parser.add_argument(
540
+ def add_autoprovisioning_arguments(parser_or_group: ParserOrArgumentGroup):
541
+ parser_or_group.add_argument(
534
542
  '--enable-autoprovisioning',
535
543
  action='store_true',
536
544
  help=(
537
545
  'Enable GKE features for autoprovisioning node pools in GKE clusters.'
538
546
  ),
539
547
  )
540
- parser.add_argument(
548
+ parser_or_group.add_argument(
541
549
  '--autoprovisioning-min-chips',
542
550
  type=int,
543
551
  help=(
@@ -546,7 +554,7 @@ def add_autoprovisioning_arguments(parser: ArgumentParser):
546
554
  ' resources in the cluster as the minimum, and maximum.'
547
555
  ),
548
556
  )
549
- parser.add_argument(
557
+ parser_or_group.add_argument(
550
558
  '--autoprovisioning-max-chips',
551
559
  type=int,
552
560
  help=(
@@ -557,13 +565,15 @@ def add_autoprovisioning_arguments(parser: ArgumentParser):
557
565
  )
558
566
 
559
567
 
560
- def add_shared_cluster_create_required_arguments(parser: ArgumentParser):
568
+ def add_shared_cluster_create_required_arguments(
569
+ parser_or_group: ParserOrArgumentGroup,
570
+ ):
561
571
  """Add shared required arguments in cluster create and Pathways cluster create.
562
572
 
563
573
  Args:
564
- parser: cluster create argument parser or argument group
574
+ parser_or_group: cluster create argument parser or argument group
565
575
  """
566
- parser.add_argument(
576
+ parser_or_group.add_argument(
567
577
  '--cluster',
568
578
  type=name_type,
569
579
  default=None,
@@ -575,21 +585,23 @@ def add_shared_cluster_create_required_arguments(parser: ArgumentParser):
575
585
  )
576
586
 
577
587
 
578
- def add_shared_cluster_create_optional_arguments(parser: ArgumentParser):
588
+ def add_shared_cluster_create_optional_arguments(
589
+ parser_or_group: ParserOrArgumentGroup,
590
+ ):
579
591
  """Add shared optional arguments in cluster create and Pathways cluster create.
580
592
 
581
593
  Args:
582
- parser: cluster create argument parser or argument group
594
+ parser_or_group: cluster create argument parser or argument group
583
595
  """
584
- add_shared_arguments(parser)
585
- parser.add_argument(
596
+ add_shared_arguments(parser_or_group)
597
+ parser_or_group.add_argument(
586
598
  '--host-maintenance-interval',
587
599
  type=str,
588
600
  choices=['AS_NEEDED', 'PERIODIC'],
589
601
  default='AS_NEEDED',
590
602
  help='The maintenance policy of the cluster and respective clusters.',
591
603
  )
592
- parser.add_argument(
604
+ parser_or_group.add_argument(
593
605
  '--gke-version',
594
606
  type=str,
595
607
  help=(
@@ -598,20 +610,20 @@ def add_shared_cluster_create_optional_arguments(parser: ArgumentParser):
598
610
  ' recommended version.'
599
611
  ),
600
612
  )
601
- parser.add_argument(
613
+ parser_or_group.add_argument(
602
614
  '--num-slices',
603
615
  type=int,
604
616
  default=1,
605
617
  help='The number of slices to run the job on, defaults to 1.',
606
618
  required=False,
607
619
  )
608
- parser.add_argument(
620
+ parser_or_group.add_argument(
609
621
  '--pathways-gce-machine-type',
610
622
  type=str,
611
623
  default='n2-standard-64',
612
624
  help='The CPU type for Pathways CPU nodepools',
613
625
  )
614
- parser.add_argument(
626
+ parser_or_group.add_argument(
615
627
  '--default-pool-cpu-machine-type',
616
628
  type=str,
617
629
  default='e2-standard-16',
@@ -620,7 +632,7 @@ def add_shared_cluster_create_optional_arguments(parser: ArgumentParser):
620
632
  ' regional clusters, all zones must support the machine type.'
621
633
  ),
622
634
  )
623
- parser.add_argument(
635
+ parser_or_group.add_argument(
624
636
  '--cluster-cpu-machine-type',
625
637
  type=str,
626
638
  default='',
@@ -631,7 +643,7 @@ def add_shared_cluster_create_optional_arguments(parser: ArgumentParser):
631
643
  ' cpu nodepools using --device-type.'
632
644
  ),
633
645
  )
634
- parser.add_argument(
646
+ parser_or_group.add_argument(
635
647
  '--default-pool-cpu-num-nodes',
636
648
  type=int,
637
649
  default=6,
@@ -641,7 +653,7 @@ def add_shared_cluster_create_optional_arguments(parser: ArgumentParser):
641
653
  ' over time.'
642
654
  ),
643
655
  )
644
- parser.add_argument(
656
+ parser_or_group.add_argument(
645
657
  '--custom-cluster-arguments',
646
658
  type=str,
647
659
  default='',
@@ -652,7 +664,7 @@ def add_shared_cluster_create_optional_arguments(parser: ArgumentParser):
652
664
  " --custom-cluster-arguments='--network=mtu9k --subnetwork=mtu9k'"
653
665
  ),
654
666
  )
655
- parser.add_argument(
667
+ parser_or_group.add_argument(
656
668
  '--custom-nodepool-arguments',
657
669
  type=str,
658
670
  default='',
@@ -663,7 +675,7 @@ def add_shared_cluster_create_optional_arguments(parser: ArgumentParser):
663
675
  ' --custom-nodepool-arguments="--disk-size=300"'
664
676
  ),
665
677
  )
666
- parser.add_argument(
678
+ parser_or_group.add_argument(
667
679
  '--force',
668
680
  action='store_true',
669
681
  help=(
@@ -671,7 +683,7 @@ def add_shared_cluster_create_optional_arguments(parser: ArgumentParser):
671
683
  ' additional approval.'
672
684
  ),
673
685
  )
674
- parser.add_argument(
686
+ parser_or_group.add_argument(
675
687
  '--custom-tpu-nodepool-arguments',
676
688
  type=str,
677
689
  default='',
@@ -682,7 +694,7 @@ def add_shared_cluster_create_optional_arguments(parser: ArgumentParser):
682
694
  ' --custom-tpu-nodepool-arguments="--enable-ip-alias"'
683
695
  ),
684
696
  )
685
- parser.add_argument(
697
+ parser_or_group.add_argument(
686
698
  '--private',
687
699
  action='store_true',
688
700
  help=(
@@ -695,7 +707,7 @@ def add_shared_cluster_create_optional_arguments(parser: ArgumentParser):
695
707
  ' clusters.'
696
708
  ),
697
709
  )
698
- parser.add_argument(
710
+ parser_or_group.add_argument(
699
711
  '--authorized-networks',
700
712
  action='extend',
701
713
  nargs='+',
@@ -710,16 +722,16 @@ def add_shared_cluster_create_optional_arguments(parser: ArgumentParser):
710
722
  ' Example usage: --authorized-networks 1.2.3.0/24 1.2.4.5/32'
711
723
  ),
712
724
  )
713
- parser.add_argument(
725
+ parser_or_group.add_argument(
714
726
  '--enable-workload-identity',
715
727
  action='store_true',
716
728
  help='Enable Workload Identity Federation on the cluster and node-pools.',
717
729
  )
718
- add_driver_arguments(parser)
730
+ add_driver_arguments(parser_or_group)
719
731
 
720
732
 
721
- def add_driver_arguments(parser: ArgumentParser):
722
- parser.add_argument(
733
+ def add_driver_arguments(parser_or_group: ParserOrArgumentGroup):
734
+ parser_or_group.add_argument(
723
735
  '--enable-gcsfuse-csi-driver',
724
736
  action='store_true',
725
737
  help=(
@@ -728,42 +740,44 @@ def add_driver_arguments(parser: ArgumentParser):
728
740
  ' Identity is enabled by default.'
729
741
  ),
730
742
  )
731
- parser.add_argument(
743
+ parser_or_group.add_argument(
732
744
  '--enable-gcpfilestore-csi-driver',
733
745
  action='store_true',
734
746
  help='Enable GCPFilestore driver on the cluster.',
735
747
  )
736
- parser.add_argument(
748
+ parser_or_group.add_argument(
737
749
  '--enable-parallelstore-csi-driver',
738
750
  action='store_true',
739
751
  help='Enable Parallelstore CSI driver on the cluster.',
740
752
  )
741
- parser.add_argument(
753
+ parser_or_group.add_argument(
742
754
  '--enable-pd-csi-driver',
743
755
  action='store_true',
744
756
  help='Enable PersistentDisk CSI driver on the cluster.',
745
757
  )
746
- parser.add_argument(
758
+ parser_or_group.add_argument(
747
759
  '--enable-lustre-csi-driver',
748
760
  action='store_true',
749
761
  help='Enable Lustre CSI driver on the cluster.',
750
762
  )
751
763
 
752
764
 
753
- def add_shared_cluster_create_tensorboard_arguments(parser: ArgumentParser):
765
+ def add_shared_cluster_create_tensorboard_arguments(
766
+ parser_or_group: ParserOrArgumentGroup,
767
+ ):
754
768
  """Add shared tensorboard arguments in cluster create and Pathways cluster create.
755
769
  Note that this feature enables non-Pathways workloads to use tensorboard arguments
756
770
  on a Pathways cluster.
757
771
 
758
772
  Args:
759
- parser: cluster create argument parser or argument group
773
+ parser_or_group: cluster create argument parser or argument group
760
774
  """
761
- parser.add_argument(
775
+ parser_or_group.add_argument(
762
776
  '--create-vertex-tensorboard',
763
777
  action='store_true',
764
778
  help='Set this flag to create a Tensorboard instance in Vertex AI.',
765
779
  )
766
- parser.add_argument(
780
+ parser_or_group.add_argument(
767
781
  '--tensorboard-region',
768
782
  type=str,
769
783
  default='us-central1',
@@ -774,7 +788,7 @@ def add_shared_cluster_create_tensorboard_arguments(parser: ArgumentParser):
774
788
  ' instance will be created in us-central1.'
775
789
  ),
776
790
  )
777
- parser.add_argument(
791
+ parser_or_group.add_argument(
778
792
  '--tensorboard-name',
779
793
  type=str,
780
794
  required=False,
@@ -787,13 +801,15 @@ def add_shared_cluster_create_tensorboard_arguments(parser: ArgumentParser):
787
801
  )
788
802
 
789
803
 
790
- def add_shared_cluster_create_capacity_arguments(parser: ArgumentParser):
804
+ def add_shared_cluster_create_capacity_arguments(
805
+ parser_or_group: ParserOrArgumentGroup,
806
+ ):
791
807
  """Add shared capacity arguments in cluster create and Pathways cluster create.
792
808
 
793
809
  Args:
794
- parser: cluster create argument parser or argument group
810
+ parser_or_group: cluster create argument parser or argument group
795
811
  """
796
- parser.add_argument(
812
+ parser_or_group.add_argument(
797
813
  '--on-demand',
798
814
  action='store_true',
799
815
  help=(
@@ -802,7 +818,7 @@ def add_shared_cluster_create_capacity_arguments(parser: ArgumentParser):
802
818
  ' types.'
803
819
  ),
804
820
  )
805
- parser.add_argument(
821
+ parser_or_group.add_argument(
806
822
  '--reservation',
807
823
  type=str,
808
824
  help=(
@@ -811,7 +827,7 @@ def add_shared_cluster_create_capacity_arguments(parser: ArgumentParser):
811
827
  ' `--flex` or `--on-demand` for other capacity types.'
812
828
  ),
813
829
  )
814
- parser.add_argument(
830
+ parser_or_group.add_argument(
815
831
  '--spot',
816
832
  action='store_true',
817
833
  help=(
@@ -820,7 +836,7 @@ def add_shared_cluster_create_capacity_arguments(parser: ArgumentParser):
820
836
  ' capacity types.'
821
837
  ),
822
838
  )
823
- parser.add_argument(
839
+ parser_or_group.add_argument(
824
840
  '--flex',
825
841
  action='store_true',
826
842
  help=(
@@ -831,18 +847,20 @@ def add_shared_cluster_create_capacity_arguments(parser: ArgumentParser):
831
847
  )
832
848
 
833
849
 
834
- def add_shared_cluster_create_mtc_arguments(parser: ArgumentParser):
850
+ def add_shared_cluster_create_mtc_arguments(
851
+ parser_or_group: ParserOrArgumentGroup,
852
+ ):
835
853
  """Add shared Multi-tier Checkpointing arguments in cluster create and Pathways cluster create.
836
854
 
837
855
  Args:
838
- List of cluster create MTC arguments parsers
856
+ List of cluster create MTC arguments parsers or group
839
857
  """
840
- parser.add_argument(
858
+ parser_or_group.add_argument(
841
859
  '--enable-mtc',
842
860
  action='store_true',
843
861
  help='Enable MTC on the cluster.',
844
862
  )
845
- parser.add_argument(
863
+ parser_or_group.add_argument(
846
864
  '--mtc-ramdisk-size',
847
865
  type=str,
848
866
  default=None,
@@ -851,7 +869,7 @@ def add_shared_cluster_create_mtc_arguments(parser: ArgumentParser):
851
869
  ' used for multi-tier checkpointing. e.g. "64Mi" '
852
870
  ),
853
871
  )
854
- parser.add_argument(
872
+ parser_or_group.add_argument(
855
873
  '--mtc-gcs-bucket',
856
874
  type=str,
857
875
  default=None,
@@ -860,7 +878,7 @@ def add_shared_cluster_create_mtc_arguments(parser: ArgumentParser):
860
878
  ' multi-tier checkpointing.'
861
879
  ),
862
880
  )
863
- parser.add_argument(
881
+ parser_or_group.add_argument(
864
882
  '--mtc-toleration-key',
865
883
  type=str,
866
884
  default=None,
xpk/parser/common.py CHANGED
@@ -15,24 +15,31 @@ limitations under the License.
15
15
  """
16
16
 
17
17
  import argparse
18
+ from typing import Protocol, Any
19
+
20
+
21
+ class ParserOrArgumentGroup(Protocol):
22
+
23
+ def add_argument(self, *args, **kwargs) -> Any:
24
+ ...
18
25
 
19
26
 
20
27
  def add_shared_arguments(
21
- custom_parser: argparse.ArgumentParser, required=False
28
+ custom_parser_or_group: ParserOrArgumentGroup, required=False
22
29
  ) -> None:
23
- """Add shared arguments to the parser.
30
+ """Add shared arguments to the parser or argument group.
24
31
 
25
32
  Args:
26
- custom_parser: parser to add shared arguments to.
33
+ custom_parser_or_group: parser or argument group to add shared arguments to.
27
34
  """
28
- custom_parser.add_argument(
35
+ custom_parser_or_group.add_argument(
29
36
  '--project',
30
37
  type=str,
31
38
  default=None,
32
39
  help='GCE project name, defaults to "gcloud config project."',
33
40
  required=required,
34
41
  )
35
- custom_parser.add_argument(
42
+ custom_parser_or_group.add_argument(
36
43
  '--zone',
37
44
  type=str,
38
45
  default=None,
@@ -43,7 +50,7 @@ def add_shared_arguments(
43
50
  ),
44
51
  required=required,
45
52
  )
46
- custom_parser.add_argument(
53
+ custom_parser_or_group.add_argument(
47
54
  '--dry-run',
48
55
  type=bool,
49
56
  action=argparse.BooleanOptionalAction,
@@ -58,14 +65,14 @@ def add_shared_arguments(
58
65
 
59
66
 
60
67
  def add_cluster_arguments(
61
- custom_parser: argparse.ArgumentParser, required=False
68
+ custom_parser_or_group: ParserOrArgumentGroup, required=False
62
69
  ) -> None:
63
- """Add cluster argument to the parser.
70
+ """Add cluster argument to the parser or argument group.
64
71
 
65
72
  Args:
66
- custom_parser: parser to add shared arguments to.
73
+ custom_parser_or_group: parser or argument group to add shared arguments to.
67
74
  """
68
- custom_parser.add_argument(
75
+ custom_parser_or_group.add_argument(
69
76
  '--cluster',
70
77
  type=str,
71
78
  default=None,
@@ -74,13 +81,15 @@ def add_cluster_arguments(
74
81
  )
75
82
 
76
83
 
77
- def add_kind_cluster_arguments(custom_parser: argparse.ArgumentParser) -> None:
78
- """Add kind cluster arguments to the parser.
84
+ def add_kind_cluster_arguments(
85
+ custom_parser_or_group: ParserOrArgumentGroup,
86
+ ) -> None:
87
+ """Add kind cluster arguments to the parser or argument group.
79
88
 
80
89
  Args:
81
- custom_parser: parser to add shared arguments to.
90
+ custom_parser_or_group: parser or argument group to add shared arguments to.
82
91
  """
83
- custom_parser.add_argument(
92
+ custom_parser_or_group.add_argument(
84
93
  '--kind-cluster',
85
94
  type=bool,
86
95
  action=argparse.BooleanOptionalAction,
@@ -89,13 +98,13 @@ def add_kind_cluster_arguments(custom_parser: argparse.ArgumentParser) -> None:
89
98
  )
90
99
 
91
100
 
92
- def add_global_arguments(custom_parser: argparse.ArgumentParser):
101
+ def add_global_arguments(custom_parser_or_group: ParserOrArgumentGroup):
93
102
  """Add global - no cloud dependent - arguments to the parser.
94
103
 
95
104
  Args:
96
- custom_parser: parser to add global arguments to.
105
+ custom_parser_or_group: parser or argument group to add global arguments to.
97
106
  """
98
- custom_parser.add_argument(
107
+ custom_parser_or_group.add_argument(
99
108
  '--dry-run',
100
109
  type=bool,
101
110
  action=argparse.BooleanOptionalAction,
@@ -108,20 +117,20 @@ def add_global_arguments(custom_parser: argparse.ArgumentParser):
108
117
  )
109
118
 
110
119
 
111
- def add_slurm_arguments(custom_parser: argparse.ArgumentParser):
120
+ def add_slurm_arguments(custom_parser_or_group: ParserOrArgumentGroup):
112
121
  """Add Slurm job arguments to the parser.
113
122
 
114
123
  Args:
115
- custom_parser: parser to add global arguments to.
124
+ custom_parser_or_group: parser or argument group to add global arguments to.
116
125
  """
117
- custom_parser.add_argument(
126
+ custom_parser_or_group.add_argument(
118
127
  '--ignore-unknown-flags',
119
128
  type=bool,
120
129
  action=argparse.BooleanOptionalAction,
121
130
  default=False,
122
131
  help='Ignore all the unsupported flags in the bash script.',
123
132
  )
124
- custom_parser.add_argument(
133
+ custom_parser_or_group.add_argument(
125
134
  '-a',
126
135
  '--array',
127
136
  type=str,
@@ -137,32 +146,32 @@ def add_slurm_arguments(custom_parser: argparse.ArgumentParser):
137
146
  ' 0. The maximum index value is 2147483647.'
138
147
  ),
139
148
  )
140
- custom_parser.add_argument(
149
+ custom_parser_or_group.add_argument(
141
150
  '-c',
142
151
  '--cpus-per-task',
143
152
  type=str,
144
153
  default=None,
145
154
  help='How much cpus a container inside a pod requires.',
146
155
  )
147
- custom_parser.add_argument(
156
+ custom_parser_or_group.add_argument(
148
157
  '--gpus-per-task',
149
158
  type=str,
150
159
  default=None,
151
160
  help='How much gpus a container inside a pod requires.',
152
161
  )
153
- custom_parser.add_argument(
162
+ custom_parser_or_group.add_argument(
154
163
  '--mem',
155
164
  type=str,
156
165
  default=None,
157
166
  help='How much memory a pod requires.',
158
167
  )
159
- custom_parser.add_argument(
168
+ custom_parser_or_group.add_argument(
160
169
  '--mem-per-task',
161
170
  type=str,
162
171
  default=None,
163
172
  help='How much memory a container requires.',
164
173
  )
165
- custom_parser.add_argument(
174
+ custom_parser_or_group.add_argument(
166
175
  '--mem-per-cpu',
167
176
  type=str,
168
177
  default=None,
@@ -171,7 +180,7 @@ def add_slurm_arguments(custom_parser: argparse.ArgumentParser):
171
180
  'of requested cpus per task by mem-per-cpu.'
172
181
  ),
173
182
  )
174
- custom_parser.add_argument(
183
+ custom_parser_or_group.add_argument(
175
184
  '--mem-per-gpu',
176
185
  type=str,
177
186
  default=None,
@@ -180,21 +189,21 @@ def add_slurm_arguments(custom_parser: argparse.ArgumentParser):
180
189
  'of requested gpus per task by mem-per-gpu.'
181
190
  ),
182
191
  )
183
- custom_parser.add_argument(
192
+ custom_parser_or_group.add_argument(
184
193
  '-N',
185
194
  '--nodes',
186
195
  type=int,
187
196
  default=None,
188
197
  help='Number of pods to be used at a time.',
189
198
  )
190
- custom_parser.add_argument(
199
+ custom_parser_or_group.add_argument(
191
200
  '-n',
192
201
  '--ntasks',
193
202
  type=int,
194
203
  default=None,
195
204
  help='Number of identical containers inside of a pod, usually 1.',
196
205
  )
197
- custom_parser.add_argument(
206
+ custom_parser_or_group.add_argument(
198
207
  '-o',
199
208
  '--output',
200
209
  type=str,
@@ -204,7 +213,7 @@ def add_slurm_arguments(custom_parser: argparse.ArgumentParser):
204
213
  ' passed it proceeds to stdout, and is available via kubectl logs.'
205
214
  ),
206
215
  )
207
- custom_parser.add_argument(
216
+ custom_parser_or_group.add_argument(
208
217
  '-e',
209
218
  '--error',
210
219
  type=str,
@@ -214,27 +223,27 @@ def add_slurm_arguments(custom_parser: argparse.ArgumentParser):
214
223
  ' proceeds to stdout, and is available via kubectl logs.'
215
224
  ),
216
225
  )
217
- custom_parser.add_argument(
226
+ custom_parser_or_group.add_argument(
218
227
  '--input',
219
228
  type=str,
220
229
  default=None,
221
230
  help='What to pipe into the script.',
222
231
  )
223
- custom_parser.add_argument(
232
+ custom_parser_or_group.add_argument(
224
233
  '-J',
225
234
  '--job-name',
226
235
  type=str,
227
236
  default=None,
228
237
  help='What is the job name.',
229
238
  )
230
- custom_parser.add_argument(
239
+ custom_parser_or_group.add_argument(
231
240
  '-D',
232
241
  '--chdir',
233
242
  type=str,
234
243
  default=None,
235
244
  help='Change directory before executing the script.',
236
245
  )
237
- custom_parser.add_argument(
246
+ custom_parser_or_group.add_argument(
238
247
  '-t',
239
248
  '--time',
240
249
  type=str,
@@ -247,7 +256,7 @@ def add_slurm_arguments(custom_parser: argparse.ArgumentParser):
247
256
  'and "days-hours:minutes:seconds".'
248
257
  ),
249
258
  )
250
- custom_parser.add_argument(
259
+ custom_parser_or_group.add_argument(
251
260
  '--priority',
252
261
  type=str,
253
262
  default='medium',
xpk/parser/storage.py CHANGED
@@ -28,6 +28,13 @@ from .common import (
28
28
  add_kind_cluster_arguments,
29
29
  add_shared_arguments,
30
30
  )
31
+ from typing import Protocol, Any
32
+
33
+
34
+ class Subcommands(Protocol):
35
+
36
+ def add_parser(self, *args, **kwargs) -> Any:
37
+ ...
31
38
 
32
39
 
33
40
  def set_storage_parser(storage_parser: argparse.ArgumentParser) -> None:
@@ -47,7 +54,7 @@ def set_storage_parser(storage_parser: argparse.ArgumentParser) -> None:
47
54
 
48
55
 
49
56
  def add_storage_attach_parser(
50
- storage_subcommands_parser: argparse.ArgumentParser,
57
+ storage_subcommands_parser: Subcommands,
51
58
  ) -> None:
52
59
 
53
60
  storage_attach_parser: argparse.ArgumentParser = (
@@ -171,9 +178,7 @@ def add_storage_attach_parser(
171
178
  add_kind_cluster_arguments(opt_args)
172
179
 
173
180
 
174
- def add_storage_create_parser(
175
- storage_subcommands_parser: argparse.ArgumentParser,
176
- ) -> None:
181
+ def add_storage_create_parser(storage_subcommands_parser: Subcommands) -> None:
177
182
  storage_create_parser: argparse.ArgumentParser = (
178
183
  storage_subcommands_parser.add_parser(
179
184
  'create', help='create XPK Storage.'
@@ -272,9 +277,7 @@ def add_storage_create_parser(
272
277
  add_kind_cluster_arguments(opt_args)
273
278
 
274
279
 
275
- def add_storage_list_parser(
276
- storage_subcommands_parser: argparse.ArgumentParser,
277
- ):
280
+ def add_storage_list_parser(storage_subcommands_parser: Subcommands) -> None:
278
281
  storage_list_parser: argparse.ArgumentParser = (
279
282
  storage_subcommands_parser.add_parser('list', help='List XPK Storages.')
280
283
  )
@@ -290,9 +293,7 @@ def add_storage_list_parser(
290
293
  )
291
294
 
292
295
 
293
- def add_storage_detach_parser(
294
- storage_subcommands_parser: argparse.ArgumentParser,
295
- ):
296
+ def add_storage_detach_parser(storage_subcommands_parser: Subcommands) -> None:
296
297
  storage_detach_parser: argparse.ArgumentParser = (
297
298
  storage_subcommands_parser.add_parser(
298
299
  'detach', help='Detach XPK Storage.'
@@ -315,9 +316,7 @@ def add_storage_detach_parser(
315
316
  add_kind_cluster_arguments(opt_args)
316
317
 
317
318
 
318
- def add_storage_delete_parser(
319
- storage_subcommands_parser: argparse.ArgumentParser,
320
- ):
319
+ def add_storage_delete_parser(storage_subcommands_parser: Subcommands) -> None:
321
320
  storage_delete_parser: argparse.ArgumentParser = (
322
321
  storage_subcommands_parser.add_parser(
323
322
  'delete', help='Delete XPK Storage.'