github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/apiserver/params/internal.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package params 5 6 import ( 7 "time" 8 9 "github.com/juju/version" 10 11 "github.com/juju/juju/constraints" 12 "github.com/juju/juju/instance" 13 "github.com/juju/juju/state/multiwatcher" 14 "github.com/juju/juju/status" 15 "github.com/juju/juju/tools" 16 ) 17 18 // MachineContainersParams holds the arguments for making a SetSupportedContainers 19 // API call. 20 type MachineContainersParams struct { 21 Params []MachineContainers `json:"params"` 22 } 23 24 // MachineContainers holds the arguments for making an SetSupportedContainers call 25 // on a given machine. 26 type MachineContainers struct { 27 MachineTag string `json:"machine-tag"` 28 ContainerTypes []instance.ContainerType `json:"container-types"` 29 } 30 31 // WatchContainer identifies a single container type within a machine. 32 type WatchContainer struct { 33 MachineTag string `json:"machine-tag"` 34 ContainerType string `json:"container-type"` 35 } 36 37 // WatchContainers holds the arguments for making a WatchContainers 38 // API call. 39 type WatchContainers struct { 40 Params []WatchContainer `json:"params"` 41 } 42 43 // CharmURL identifies a single charm URL. 44 type CharmURL struct { 45 URL string `json:"url"` 46 } 47 48 // CharmURLs identifies multiple charm URLs. 49 type CharmURLs struct { 50 URLs []CharmURL `json:"urls"` 51 } 52 53 // StringsResult holds the result of an API call that returns a slice 54 // of strings or an error. 55 type StringsResult struct { 56 Error *Error `json:"error,omitempty"` 57 Result []string `json:"result,omitempty"` 58 } 59 60 // StringsResults holds the bulk operation result of an API call 61 // that returns a slice of strings or an error. 62 type StringsResults struct { 63 Results []StringsResult `json:"results"` 64 } 65 66 // StringResult holds a string or an error. 67 type StringResult struct { 68 Error *Error `json:"error,omitempty"` 69 Result string `json:"result"` 70 } 71 72 // StringResults holds the bulk operation result of an API call 73 // that returns a string or an error. 74 type StringResults struct { 75 Results []StringResult `json:"results"` 76 } 77 78 // MapResult holds a generic map or an error. 79 type MapResult struct { 80 Result map[string]interface{} `json:"result"` 81 Error *Error `json:"error,omitempty"` 82 } 83 84 // MapResults holds the bulk operation result of an API call 85 // that returns a map or an error. 86 type MapResults struct { 87 Results []MapResult `json:"results"` 88 } 89 90 // ModelResult holds the result of an API call returning a name and UUID 91 // for a model. 92 type ModelResult struct { 93 Error *Error `json:"error,omitempty"` 94 Name string `json:"name"` 95 UUID string `json:"uuid"` 96 } 97 98 // ModelCreateArgs holds the arguments that are necessary to create 99 // a model. 100 type ModelCreateArgs struct { 101 // Name is the name for the new model. 102 Name string `json:"name"` 103 104 // OwnerTag represents the user that will own the new model. 105 // The OwnerTag must be a valid user tag. If the user tag represents 106 // a local user, that user must exist. 107 OwnerTag string `json:"owner-tag"` 108 109 // Config defines the model config, which includes the name of the 110 // model. A model UUID is allocated by the API server during the 111 // creation of the model. 112 Config map[string]interface{} `json:"config,omitempty"` 113 114 // CloudTag is the tag of the cloud to create the model in. 115 // If this is empty, the model will be created in the same 116 // cloud as the controller model. 117 CloudTag string `json:"cloud-tag,omitempty"` 118 119 // CloudRegion is the name of the cloud region to create the 120 // model in. If the cloud does not support regions, this must 121 // be empty. If this is empty, and CloudTag is empty, the model 122 // will be created in the same region as the controller model. 123 CloudRegion string `json:"region,omitempty"` 124 125 // CloudCredentialTag is the tag of the cloud credential to use 126 // for managing the model's resources. If the cloud does not 127 // require credentials, this may be empty. If this is empty, 128 // and the owner is the controller owner, the same credential 129 // used for the controller model will be used. 130 CloudCredentialTag string `json:"credential,omitempty"` 131 } 132 133 // Model holds the result of an API call returning a name and UUID 134 // for a model and the tag of the server in which it is running. 135 type Model struct { 136 Name string `json:"name"` 137 UUID string `json:"uuid"` 138 OwnerTag string `json:"owner-tag"` 139 } 140 141 // UserModel holds information about a model and the last 142 // time the model was accessed for a particular user. 143 type UserModel struct { 144 Model `json:"model"` 145 LastConnection *time.Time `json:"last-connection"` 146 } 147 148 // UserModelList holds information about a list of models 149 // for a particular user. 150 type UserModelList struct { 151 UserModels []UserModel `json:"user-models"` 152 } 153 154 // ResolvedModeResult holds a resolved mode or an error. 155 type ResolvedModeResult struct { 156 Error *Error `json:"error,omitempty"` 157 Mode ResolvedMode `json:"mode"` 158 } 159 160 // ResolvedModeResults holds the bulk operation result of an API call 161 // that returns a resolved mode or an error. 162 type ResolvedModeResults struct { 163 Results []ResolvedModeResult `json:"results"` 164 } 165 166 // StringBoolResult holds the result of an API call that returns a 167 // string and a boolean. 168 type StringBoolResult struct { 169 Error *Error `json:"error,omitempty"` 170 Result string `json:"result"` 171 Ok bool `json:"ok"` 172 } 173 174 // StringBoolResults holds multiple results with a string and a bool 175 // each. 176 type StringBoolResults struct { 177 Results []StringBoolResult `json:"results"` 178 } 179 180 // BoolResult holds the result of an API call that returns a 181 // a boolean or an error. 182 type BoolResult struct { 183 Error *Error `json:"error,omitempty"` 184 Result bool `json:"result"` 185 } 186 187 // BoolResults holds multiple results with BoolResult each. 188 type BoolResults struct { 189 Results []BoolResult `json:"results"` 190 } 191 192 // IntResults holds multiple results with an int in each. 193 type IntResults struct { 194 // Results holds a list of results for calls that return an int or error. 195 Results []IntResult `json:"results"` 196 } 197 198 // IntResult holds the result of an API call that returns a 199 // int or an error. 200 type IntResult struct { 201 // Error holds the error (if any) of this call. 202 Error *Error `json:"error,omitempty"` 203 // Result holds the integer result of the call (if Error is nil). 204 Result int `json:"result"` 205 } 206 207 // Settings holds relation settings names and values. 208 type Settings map[string]string 209 210 // SettingsResult holds a relation settings map or an error. 211 type SettingsResult struct { 212 Error *Error `json:"error,omitempty"` 213 Settings Settings `json:"settings"` 214 } 215 216 // SettingsResults holds the result of an API calls that 217 // returns settings for multiple relations. 218 type SettingsResults struct { 219 Results []SettingsResult `json:"results"` 220 } 221 222 // ConfigSettings holds unit, application or cham configuration settings 223 // with string keys and arbitrary values. 224 type ConfigSettings map[string]interface{} 225 226 // ConfigSettingsResult holds a configuration map or an error. 227 type ConfigSettingsResult struct { 228 Error *Error `json:"error,omitempty"` 229 Settings ConfigSettings `json:"settings"` 230 } 231 232 // ConfigSettingsResults holds multiple configuration maps or errors. 233 type ConfigSettingsResults struct { 234 Results []ConfigSettingsResult `json:"results"` 235 } 236 237 // ModelConfig holds a model configuration. 238 type ModelConfig map[string]interface{} 239 240 // ControllerConfig holds a controller configuration. 241 type ControllerConfig map[string]interface{} 242 243 // ModelConfigResult holds model configuration. 244 type ModelConfigResult struct { 245 Config ModelConfig `json:"config"` 246 } 247 248 // ControllerConfigResult holds controller configuration. 249 type ControllerConfigResult struct { 250 Config ControllerConfig `json:"config"` 251 } 252 253 // RelationUnit holds a relation and a unit tag. 254 type RelationUnit struct { 255 Relation string `json:"relation"` 256 Unit string `json:"unit"` 257 } 258 259 // RelationUnits holds the parameters for API calls expecting a pair 260 // of relation and unit tags. 261 type RelationUnits struct { 262 RelationUnits []RelationUnit `json:"relation-units"` 263 } 264 265 // RelationIds holds multiple relation ids. 266 type RelationIds struct { 267 RelationIds []int `json:"relation-ids"` 268 } 269 270 // RelationUnitPair holds a relation tag, a local and remote unit tags. 271 type RelationUnitPair struct { 272 Relation string `json:"relation"` 273 LocalUnit string `json:"local-unit"` 274 RemoteUnit string `json:"remote-unit"` 275 } 276 277 // RelationUnitPairs holds the parameters for API calls expecting 278 // multiple sets of a relation tag, a local and remote unit tags. 279 type RelationUnitPairs struct { 280 RelationUnitPairs []RelationUnitPair `json:"relation-unit-pairs"` 281 } 282 283 // RelationUnitSettings holds a relation tag, a unit tag and local 284 // unit settings. 285 type RelationUnitSettings struct { 286 Relation string `json:"relation"` 287 Unit string `json:"unit"` 288 Settings Settings `json:"settings"` 289 } 290 291 // RelationUnitsSettings holds the arguments for making a EnterScope 292 // or WriteSettings API calls. 293 type RelationUnitsSettings struct { 294 RelationUnits []RelationUnitSettings `json:"relation-units"` 295 } 296 297 // RelationResult returns information about a single relation, 298 // or an error. 299 type RelationResult struct { 300 Error *Error `json:"error,omitempty"` 301 Life Life `json:"life"` 302 Id int `json:"id"` 303 Key string `json:"key"` 304 Endpoint multiwatcher.Endpoint `json:"endpoint"` 305 } 306 307 // RelationResults holds the result of an API call that returns 308 // information about multiple relations. 309 type RelationResults struct { 310 Results []RelationResult `json:"results"` 311 } 312 313 // EntityCharmURL holds an entity's tag and a charm URL. 314 type EntityCharmURL struct { 315 Tag string `json:"tag"` 316 CharmURL string `json:"charm-url"` 317 } 318 319 // EntitiesCharmURL holds the parameters for making a SetCharmURL API 320 // call. 321 type EntitiesCharmURL struct { 322 Entities []EntityCharmURL `json:"entities"` 323 } 324 325 // EntityWorkloadVersion holds the workload version for an entity. 326 type EntityWorkloadVersion struct { 327 Tag string `json:"tag"` 328 WorkloadVersion string `json:"workload-version"` 329 } 330 331 // EntityWorkloadVersions holds the parameters for setting the 332 // workload version for a set of entities. 333 type EntityWorkloadVersions struct { 334 Entities []EntityWorkloadVersion `json:"entities"` 335 } 336 337 // BytesResult holds the result of an API call that returns a slice 338 // of bytes. 339 type BytesResult struct { 340 Result []byte `json:"result"` 341 } 342 343 // LifeResult holds the life status of a single entity, or an error 344 // indicating why it is not available. 345 type LifeResult struct { 346 Life Life `json:"life"` 347 Error *Error `json:"error,omitempty"` 348 } 349 350 // LifeResults holds the life or error status of multiple entities. 351 type LifeResults struct { 352 Results []LifeResult `json:"results"` 353 } 354 355 // InstanceInfo holds a machine tag, provider-specific instance id, a nonce, and 356 // network config. 357 type InstanceInfo struct { 358 Tag string `json:"tag"` 359 InstanceId instance.Id `json:"instance-id"` 360 Nonce string `json:"nonce"` 361 Characteristics *instance.HardwareCharacteristics `json:"characteristics"` 362 Volumes []Volume `json:"volumes"` 363 // VolumeAttachments is a mapping from volume tag to 364 // volume attachment info. 365 VolumeAttachments map[string]VolumeAttachmentInfo `json:"volume-attachments"` 366 367 NetworkConfig []NetworkConfig `json:"network-config"` 368 } 369 370 // InstancesInfo holds the parameters for making a SetInstanceInfo 371 // call for multiple machines. 372 type InstancesInfo struct { 373 Machines []InstanceInfo `json:"machines"` 374 } 375 376 // EntityStatus holds the status of an entity. 377 type EntityStatus struct { 378 Status status.Status `json:"status"` 379 Info string `json:"info"` 380 Data map[string]interface{} `json:"data,omitempty"` 381 Since *time.Time `json:"since"` 382 } 383 384 // EntityStatusArgs holds parameters for setting the status of a single entity. 385 type EntityStatusArgs struct { 386 Tag string `json:"tag"` 387 Status string `json:"status"` 388 Info string `json:"info"` 389 Data map[string]interface{} `json:"data"` 390 } 391 392 // SetStatus holds the parameters for making a SetStatus/UpdateStatus call. 393 type SetStatus struct { 394 Entities []EntityStatusArgs `json:"entities"` 395 } 396 397 // ConstraintsResult holds machine constraints or an error. 398 type ConstraintsResult struct { 399 Error *Error `json:"error,omitempty"` 400 Constraints constraints.Value `json:"constraints"` 401 } 402 403 // ConstraintsResults holds multiple constraints results. 404 type ConstraintsResults struct { 405 Results []ConstraintsResult `json:"results"` 406 } 407 408 // AgentGetEntitiesResults holds the results of a 409 // agent.API.GetEntities call. 410 type AgentGetEntitiesResults struct { 411 Entities []AgentGetEntitiesResult `json:"entities"` 412 } 413 414 // AgentGetEntitiesResult holds the results of a 415 // machineagent.API.GetEntities call for a single entity. 416 type AgentGetEntitiesResult struct { 417 Life Life `json:"life"` 418 Jobs []multiwatcher.MachineJob `json:"jobs"` 419 ContainerType instance.ContainerType `json:"container-type"` 420 Error *Error `json:"error,omitempty"` 421 } 422 423 // VersionResult holds the version and possibly error for a given 424 // DesiredVersion() API call. 425 type VersionResult struct { 426 Version *version.Number `json:"version,omitempty"` 427 Error *Error `json:"error,omitempty"` 428 } 429 430 // VersionResults is a list of versions for the requested entities. 431 type VersionResults struct { 432 Results []VersionResult `json:"results"` 433 } 434 435 // ToolsResult holds the tools and possibly error for a given 436 // Tools() API call. 437 type ToolsResult struct { 438 ToolsList tools.List `json:"tools"` 439 DisableSSLHostnameVerification bool `json:"disable-ssl-hostname-verification"` 440 Error *Error `json:"error,omitempty"` 441 } 442 443 // ToolsResults is a list of tools for various requested agents. 444 type ToolsResults struct { 445 Results []ToolsResult `json:"results"` 446 } 447 448 // Version holds a specific binary version. 449 type Version struct { 450 Version version.Binary `json:"version"` 451 } 452 453 // EntityVersion specifies the tools version to be set for an entity 454 // with the given tag. 455 // version.Binary directly. 456 type EntityVersion struct { 457 Tag string `json:"tag"` 458 Tools *Version `json:"tools"` 459 } 460 461 // EntitiesVersion specifies what tools are being run for 462 // multiple entities. 463 type EntitiesVersion struct { 464 AgentTools []EntityVersion `json:"agent-tools"` 465 } 466 467 // NotifyWatchResult holds a NotifyWatcher id and an error (if any). 468 type NotifyWatchResult struct { 469 NotifyWatcherId string 470 Error *Error `json:"error,omitempty"` 471 } 472 473 // NotifyWatchResults holds the results for any API call which ends up 474 // returning a list of NotifyWatchers 475 type NotifyWatchResults struct { 476 Results []NotifyWatchResult `json:"results"` 477 } 478 479 // StringsWatchResult holds a StringsWatcher id, changes and an error 480 // (if any). 481 type StringsWatchResult struct { 482 StringsWatcherId string `json:"watcher-id"` 483 Changes []string `json:"changes,omitempty"` 484 Error *Error `json:"error,omitempty"` 485 } 486 487 // StringsWatchResults holds the results for any API call which ends up 488 // returning a list of StringsWatchers. 489 type StringsWatchResults struct { 490 Results []StringsWatchResult `json:"results"` 491 } 492 493 // EntitiesWatchResult holds a EntitiesWatcher id, changes and an error 494 // (if any). 495 type EntitiesWatchResult struct { 496 // Note legacy serialization tag. 497 EntitiesWatcherId string `json:"watcher-id"` 498 Changes []string `json:"changes,omitempty"` 499 Error *Error `json:"error,omitempty"` 500 } 501 502 // EntitiesWatchResults holds the results for any API call which ends up 503 // returning a list of EntitiesWatchers. 504 type EntitiesWatchResults struct { 505 Results []EntitiesWatchResult `json:"results"` 506 } 507 508 // UnitSettings specifies the version of some unit's settings in some relation. 509 type UnitSettings struct { 510 Version int64 `json:"version"` 511 } 512 513 // RelationUnitsChange describes the membership and settings of; or changes to; 514 // some relation scope. 515 type RelationUnitsChange struct { 516 517 // Changed holds a set of units that are known to be in scope, and the 518 // latest known settings version for each. 519 Changed map[string]UnitSettings `json:"changed"` 520 521 // Departed holds a set of units that have previously been reported to 522 // be in scope, but which no longer are. 523 Departed []string `json:"departed,omitempty"` 524 } 525 526 // RelationUnitsWatchResult holds a RelationUnitsWatcher id, baseline state 527 // (in the Changes field), and an error (if any). 528 type RelationUnitsWatchResult struct { 529 RelationUnitsWatcherId string `json:"watcher-id"` 530 Changes RelationUnitsChange `json:"changes"` 531 Error *Error `json:"error,omitempty"` 532 } 533 534 // RelationUnitsWatchResults holds the results for any API call which ends up 535 // returning a list of RelationUnitsWatchers. 536 type RelationUnitsWatchResults struct { 537 Results []RelationUnitsWatchResult `json:"results"` 538 } 539 540 // MachineStorageIdsWatchResult holds a MachineStorageIdsWatcher id, 541 // changes and an error (if any). 542 type MachineStorageIdsWatchResult struct { 543 MachineStorageIdsWatcherId string `json:"watcher-id"` 544 Changes []MachineStorageId `json:"changes"` 545 Error *Error `json:"error,omitempty"` 546 } 547 548 // MachineStorageIdsWatchResults holds the results for any API call which ends 549 // up returning a list of MachineStorageIdsWatchers. 550 type MachineStorageIdsWatchResults struct { 551 Results []MachineStorageIdsWatchResult `json:"results"` 552 } 553 554 // CharmsResponse is the server response to charm upload or GET requests. 555 type CharmsResponse struct { 556 Error string `json:"error,omitempty"` 557 558 // ErrorCode holds the code associated with the error. 559 // Ideally, Error would hold an Error object and the 560 // code would be in that, but for backward compatibility, 561 // we cannot do that. 562 ErrorCode string `json:"error-code,omitempty"` 563 564 // ErrorInfo holds extra information associated with the error. 565 // Like ErrorCode, this should really be in an Error object. 566 ErrorInfo *ErrorInfo `json:"error-info,omitempty"` 567 568 CharmURL string `json:"charm-url,omitempty"` 569 Files []string `json:"files,omitempty"` 570 } 571 572 // RunParams is used to provide the parameters to the Run method. 573 // Commands and Timeout are expected to have values, and one or more 574 // values should be in the Machines, Applications, or Units slices. 575 type RunParams struct { 576 Commands string `json:"commands"` 577 Timeout time.Duration `json:"timeout"` 578 Machines []string `json:"machines,omitempty"` 579 Applications []string `json:"applications,omitempty"` 580 Units []string `json:"units,omitempty"` 581 } 582 583 // RunResult contains the result from an individual run call on a machine. 584 // UnitId is populated if the command was run inside the unit context. 585 type RunResult struct { 586 Code int `json:"code-id"` 587 Stdout []byte `json:"stdout,omitempty"` 588 Stderr []byte `json:"stderr,omitempty"` 589 // FIXME: should be tags not id strings 590 MachineId string `json:"machine-id"` 591 UnitId string `json:"unit-id"` 592 Error string `json:"error"` 593 } 594 595 // RunResults is used to return the slice of results. API server side calls 596 // need to return single structure values. 597 type RunResults struct { 598 Results []RunResult `json:"results"` 599 } 600 601 // AgentVersionResult is used to return the current version number of the 602 // agent running the API server. 603 type AgentVersionResult struct { 604 Version version.Number `json:"version"` 605 } 606 607 // ProvisioningInfo holds machine provisioning info. 608 type ProvisioningInfo struct { 609 Constraints constraints.Value `json:"constraints"` 610 Series string `json:"series"` 611 Placement string `json:"placement"` 612 Jobs []multiwatcher.MachineJob `json:"jobs"` 613 Volumes []VolumeParams `json:"volumes,omitempty"` 614 Tags map[string]string `json:"tags,omitempty"` 615 SubnetsToZones map[string][]string `json:"subnets-to-zones,omitempty"` 616 ImageMetadata []CloudImageMetadata `json:"image-metadata,omitempty"` 617 EndpointBindings map[string]string `json:"endpoint-bindings,omitempty"` 618 ControllerConfig map[string]interface{} `json:"controller-config,omitempty"` 619 } 620 621 // ProvisioningInfoResult holds machine provisioning info or an error. 622 type ProvisioningInfoResult struct { 623 Error *Error `json:"error,omitempty"` 624 Result *ProvisioningInfo `json:"result"` 625 } 626 627 // ProvisioningInfoResults holds multiple machine provisioning info results. 628 type ProvisioningInfoResults struct { 629 Results []ProvisioningInfoResult `json:"results"` 630 } 631 632 // Metric holds a single metric. 633 type Metric struct { 634 Key string `json:"key"` 635 Value string `json:"value"` 636 Time time.Time `json:"time"` 637 } 638 639 // MetricsParam contains the metrics for a single unit. 640 type MetricsParam struct { 641 Tag string `json:"tag"` 642 Metrics []Metric `json:"metrics"` 643 } 644 645 // MetricsParams contains the metrics for multiple units. 646 type MetricsParams struct { 647 Metrics []MetricsParam `json:"metrics"` 648 } 649 650 // MetricBatch is a list of metrics with metadata. 651 type MetricBatch struct { 652 UUID string `json:"uuid"` 653 CharmURL string `json:"charm-url"` 654 Created time.Time `json:"created"` 655 Metrics []Metric `json:"metrics"` 656 } 657 658 // MetricBatchParam contains a single metric batch. 659 type MetricBatchParam struct { 660 Tag string `json:"tag"` 661 Batch MetricBatch `json:"batch"` 662 } 663 664 // MetricBatchParams contains multiple metric batches. 665 type MetricBatchParams struct { 666 Batches []MetricBatchParam `json:"batches"` 667 } 668 669 // MeterStatusResult holds unit meter status or error. 670 type MeterStatusResult struct { 671 Code string `json:"code"` 672 Info string `json:"info"` 673 Error *Error `json:"error,omitempty"` 674 } 675 676 // MeterStatusResults holds meter status results for multiple units. 677 type MeterStatusResults struct { 678 Results []MeterStatusResult `json:"results"` 679 } 680 681 // SingularClaim represents a request for exclusive model administration access 682 // on the part of some controller. 683 type SingularClaim struct { 684 ModelTag string `json:"model-tag"` 685 ControllerTag string `json:"controller-tag"` 686 Duration time.Duration `json:"duration"` 687 } 688 689 // SingularClaims holds any number of SingularClaim~s. 690 type SingularClaims struct { 691 Claims []SingularClaim `json:"claims"` 692 } 693 694 // GUIArchiveVersion holds information on a specific GUI archive version. 695 type GUIArchiveVersion struct { 696 // Version holds the Juju GUI version number. 697 Version version.Number `json:"version"` 698 // SHA256 holds the SHA256 hash of the GUI tar.bz2 archive. 699 SHA256 string `json:"sha256"` 700 // Current holds whether this specific version is the current one served 701 // by the controller. 702 Current bool `json:"current"` 703 } 704 705 // GUIArchiveResponse holds the response to /gui-archive GET requests. 706 type GUIArchiveResponse struct { 707 Versions []GUIArchiveVersion `json:"versions"` 708 } 709 710 // GUIVersionRequest holds the body for /gui-version PUT requests. 711 type GUIVersionRequest struct { 712 // Version holds the Juju GUI version number. 713 Version version.Number `json:"version"` 714 } 715 716 // LogMessage is a structured logging entry. 717 type LogMessage struct { 718 Entity string `json:"tag"` 719 Timestamp time.Time `json:"ts"` 720 Severity string `json:"sev"` 721 Module string `json:"mod"` 722 Location string `json:"loc"` 723 Message string `json:"msg"` 724 }