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 |