Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /* | 5 /* |
| 6 Package cipd implements client side of Chrome Infra Package Deployer. | 6 Package cipd implements client side of Chrome Infra Package Deployer. |
| 7 | 7 |
| 8 TODO: write more. | 8 TODO: write more. |
| 9 | 9 |
| 10 Binary package file format (in free form representation): | 10 Binary package file format (in free form representation): |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 269 return ErrFinalizationTimeout | 269 return ErrFinalizationTimeout |
| 270 } | 270 } |
| 271 client.Log.Infof("cipd: uploading - verifying") | 271 client.Log.Infof("cipd: uploading - verifying") |
| 272 client.clock.sleep(delay) | 272 client.clock.sleep(delay) |
| 273 if delay < 4*time.Second { | 273 if delay < 4*time.Second { |
| 274 delay += 500 * time.Millisecond | 274 delay += 500 * time.Millisecond |
| 275 } | 275 } |
| 276 } | 276 } |
| 277 } | 277 } |
| 278 | 278 |
| 279 // ResolveVersion converts an instance ID, a tag or a ref into a concrete Pin | |
| 280 // by contacting the backend. | |
| 281 func (client *Client) ResolveVersion(packageName, version string) (common.Pin, e rror) { | |
| 282 if err := common.ValidatePackageName(packageName); err != nil { | |
| 283 return common.Pin{}, err | |
| 284 } | |
| 285 // Is it instance ID already? Don't bother calling the backend. | |
| 286 if err := common.ValidateInstanceID(version); err == nil { | |
|
nodir
2015/05/21 17:07:48
if common.ValidateInstanceID(version) == nil {
Vadim Sh.
2015/05/21 18:00:37
Done.
| |
| 287 return common.Pin{PackageName: packageName, InstanceID: version} , nil | |
| 288 } | |
| 289 if err := common.ValidateInstanceVersion(version); err != nil { | |
| 290 return common.Pin{}, err | |
| 291 } | |
| 292 client.Log.Infof("cipd: resolving version '%s' of '%s'...", version, pac kageName) | |
|
nodir
2015/05/21 17:07:48
%q instead of '%s' ?
Vadim Sh.
2015/05/21 18:00:37
Done.
| |
| 293 return client.remote.resolveVersion(packageName, version) | |
| 294 } | |
| 295 | |
| 279 // RegisterInstance makes the package instance available for clients by | 296 // RegisterInstance makes the package instance available for clients by |
| 280 // uploading it to the storage and registering it in the package repository. | 297 // uploading it to the storage and registering it in the package repository. |
| 281 // 'instance' is a package instance to register. | 298 // 'instance' is a package instance to register. |
| 282 func (client *Client) RegisterInstance(instance local.PackageInstance) error { | 299 func (client *Client) RegisterInstance(instance local.PackageInstance) error { |
| 283 // Attempt to register. | 300 // Attempt to register. |
| 284 client.Log.Infof("cipd: registering %s", instance.Pin()) | 301 client.Log.Infof("cipd: registering %s", instance.Pin()) |
| 285 result, err := client.remote.registerInstance(instance.Pin()) | 302 result, err := client.remote.registerInstance(instance.Pin()) |
| 286 if err != nil { | 303 if err != nil { |
| 287 return err | 304 return err |
| 288 } | 305 } |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 407 | 424 |
| 408 // Deploy it. 'defer' will take care of removing the temp file if needed . | 425 // Deploy it. 'defer' will take care of removing the temp file if needed . |
| 409 _, err = local.DeployInstance(root, instance) | 426 _, err = local.DeployInstance(root, instance) |
| 410 return err | 427 return err |
| 411 } | 428 } |
| 412 | 429 |
| 413 // ProcessEnsureFile parses text file that describes what should be installed | 430 // ProcessEnsureFile parses text file that describes what should be installed |
| 414 // by EnsurePackages function. It is a text file where each line has a form: | 431 // by EnsurePackages function. It is a text file where each line has a form: |
| 415 // <package name> <desired version>. Whitespaces are ignored. Lines that start | 432 // <package name> <desired version>. Whitespaces are ignored. Lines that start |
| 416 // with '#' are ignored. Version can be specified as instance ID, tag or ref. | 433 // with '#' are ignored. Version can be specified as instance ID, tag or ref. |
| 417 // Will resolve tags and refs to concrete instance IDs. | 434 // Will resolve tags and refs to concrete instance IDs by calling the backend. |
| 418 func (client *Client) ProcessEnsureFile(r io.Reader) ([]common.Pin, error) { | 435 func (client *Client) ProcessEnsureFile(r io.Reader) ([]common.Pin, error) { |
| 419 // TODO(vadimsh): Resolve tags to instance IDs. | |
| 420 | |
| 421 lineNo := 0 | 436 lineNo := 0 |
| 422 makeError := func(msg string) error { | 437 makeError := func(msg string) error { |
| 423 return fmt.Errorf("Failed to parse desired state (line %d): %s", lineNo, msg) | 438 return fmt.Errorf("Failed to parse desired state (line %d): %s", lineNo, msg) |
| 424 } | 439 } |
| 425 | 440 |
| 426 out := []common.Pin{} | 441 out := []common.Pin{} |
| 427 scanner := bufio.NewScanner(r) | 442 scanner := bufio.NewScanner(r) |
| 428 for scanner.Scan() { | 443 for scanner.Scan() { |
| 429 lineNo++ | 444 lineNo++ |
| 430 | 445 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 443 } | 458 } |
| 444 | 459 |
| 445 // Each line has a format "<package name> <version>". | 460 // Each line has a format "<package name> <version>". |
| 446 if len(tokens) != 2 { | 461 if len(tokens) != 2 { |
| 447 return nil, makeError("expecting '<package name> <versio n>' line") | 462 return nil, makeError("expecting '<package name> <versio n>' line") |
| 448 } | 463 } |
| 449 err := common.ValidatePackageName(tokens[0]) | 464 err := common.ValidatePackageName(tokens[0]) |
| 450 if err != nil { | 465 if err != nil { |
| 451 return nil, makeError(err.Error()) | 466 return nil, makeError(err.Error()) |
| 452 } | 467 } |
| 453 » » err = common.ValidateInstanceID(tokens[1]) | 468 » » err = common.ValidateInstanceVersion(tokens[1]) |
| 454 if err != nil { | 469 if err != nil { |
| 455 return nil, makeError(err.Error()) | 470 return nil, makeError(err.Error()) |
| 456 } | 471 } |
| 457 | 472 |
| 458 // Good enough. | 473 // Good enough. |
| 459 » » out = append(out, common.Pin{PackageName: tokens[0], InstanceID: tokens[1]}) | 474 » » pin, err := client.ResolveVersion(tokens[0], tokens[1]) |
|
nodir
2015/05/21 17:07:48
You may want to have batch resolve
Vadim Sh.
2015/05/21 18:00:37
Yeah, I know. In practice CIPD is installing 1-2 p
| |
| 475 » » if err != nil { | |
| 476 » » » return nil, err | |
| 477 » » } | |
| 478 » » out = append(out, pin) | |
| 460 } | 479 } |
| 461 | 480 |
| 462 return out, nil | 481 return out, nil |
| 463 } | 482 } |
| 464 | 483 |
| 465 // EnsurePackages is high-level interface for installation, removal and updates | 484 // EnsurePackages is high-level interface for installation, removal and updates |
| 466 // of packages inside some installation site root. Given a description of | 485 // of packages inside some installation site root. Given a description of |
| 467 // what packages (and versions) should be installed it will do all necessary | 486 // what packages (and versions) should be installed it will do all necessary |
| 468 // actions to bring the state of the site root to the desired one. | 487 // actions to bring the state of the site root to the desired one. |
| 469 func (client *Client) EnsurePackages(root string, pins []common.Pin) error { | 488 func (client *Client) EnsurePackages(root string, pins []common.Pin) error { |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 558 | 577 |
| 559 type clock interface { | 578 type clock interface { |
| 560 now() time.Time | 579 now() time.Time |
| 561 sleep(time.Duration) | 580 sleep(time.Duration) |
| 562 } | 581 } |
| 563 | 582 |
| 564 type remote interface { | 583 type remote interface { |
| 565 fetchACL(packagePath string) ([]PackageACL, error) | 584 fetchACL(packagePath string) ([]PackageACL, error) |
| 566 modifyACL(packagePath string, changes []PackageACLChange) error | 585 modifyACL(packagePath string, changes []PackageACLChange) error |
| 567 | 586 |
| 587 resolveVersion(packageName, version string) (common.Pin, error) | |
| 588 | |
| 568 initiateUpload(sha1 string) (*UploadSession, error) | 589 initiateUpload(sha1 string) (*UploadSession, error) |
| 569 finalizeUpload(sessionID string) (bool, error) | 590 finalizeUpload(sessionID string) (bool, error) |
| 570 registerInstance(pin common.Pin) (*registerInstanceResponse, error) | 591 registerInstance(pin common.Pin) (*registerInstanceResponse, error) |
| 571 | 592 |
| 572 attachTags(pin common.Pin, tags []string) error | 593 attachTags(pin common.Pin, tags []string) error |
| 573 fetchInstance(pin common.Pin) (*fetchInstanceResponse, error) | 594 fetchInstance(pin common.Pin) (*fetchInstanceResponse, error) |
| 574 } | 595 } |
| 575 | 596 |
| 576 type storage interface { | 597 type storage interface { |
| 577 upload(url string, data io.ReadSeeker) error | 598 upload(url string, data io.ReadSeeker) error |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 620 } | 641 } |
| 621 | 642 |
| 622 // buildInstanceIDMap builds mapping {package name -> instance ID}. | 643 // buildInstanceIDMap builds mapping {package name -> instance ID}. |
| 623 func buildInstanceIDMap(pins []common.Pin) map[string]string { | 644 func buildInstanceIDMap(pins []common.Pin) map[string]string { |
| 624 out := map[string]string{} | 645 out := map[string]string{} |
| 625 for _, p := range pins { | 646 for _, p := range pins { |
| 626 out[p.PackageName] = p.InstanceID | 647 out[p.PackageName] = p.InstanceID |
| 627 } | 648 } |
| 628 return out | 649 return out |
| 629 } | 650 } |
| OLD | NEW |