constructor()

in packages/aws-cdk-lib/aws-ecr-assets/lib/image-asset.ts [452:566]


  constructor(scope: Construct, id: string, props: DockerImageAssetProps) {
    super(scope, id);

    // none of the properties use tokens
    validateProps(props);

    // resolve full path
    const dir = path.resolve(props.directory);
    if (!fs.existsSync(dir)) {
      throw new ValidationError(`Cannot find image directory at ${dir}`, this);
    }

    // validate the docker file exists
    this.dockerfilePath = props.file || 'Dockerfile';
    const file = path.join(dir, this.dockerfilePath);
    if (!fs.existsSync(file)) {
      throw new ValidationError(`Cannot find file at ${file}`, this);
    }

    const defaultIgnoreMode = FeatureFlags.of(this).isEnabled(cxapi.DOCKER_IGNORE_SUPPORT)
      ? IgnoreMode.DOCKER : IgnoreMode.GLOB;
    let ignoreMode = props.ignoreMode ?? defaultIgnoreMode;

    let exclude: string[] = props.exclude || [];

    const ignore = path.join(dir, '.dockerignore');

    if (fs.existsSync(ignore)) {
      const dockerIgnorePatterns = fs.readFileSync(ignore).toString().split('\n').filter(e => !!e);

      exclude = [
        ...dockerIgnorePatterns,
        ...exclude,

        // Ensure .dockerignore is included no matter what.
        '!.dockerignore',
      ];
    }

    // Ensure the Dockerfile is included no matter what.
    exclude.push('!' + path.basename(file));
    // Ensure the cdk.out folder is not included to avoid infinite loops.
    const cdkout = Stage.of(this)?.outdir ?? 'cdk.out';
    exclude.push(cdkout);

    if (props.repositoryName) {
      Annotations.of(this).addWarningV2('@aws-cdk/aws-ecr-assets:repositoryNameDeprecated', 'DockerImageAsset.repositoryName is deprecated. Override "core.Stack.addDockerImageAsset" to control asset locations');
    }

    // include build context in "extra" so it will impact the hash
    const extraHash: { [field: string]: any } = {};
    if (props.invalidation?.extraHash !== false && props.extraHash) { extraHash.user = props.extraHash; }
    if (props.invalidation?.buildArgs !== false && props.buildArgs) { extraHash.buildArgs = props.buildArgs; }
    if (props.invalidation?.buildSecrets !== false && props.buildSecrets) { extraHash.buildSecrets = props.buildSecrets; }
    if (props.invalidation?.buildSsh !== false && props.buildSsh) {extraHash.buildSsh = props.buildSsh; }
    if (props.invalidation?.target !== false && props.target) { extraHash.target = props.target; }
    if (props.invalidation?.file !== false && props.file) { extraHash.file = props.file; }
    if (props.invalidation?.repositoryName !== false && props.repositoryName) { extraHash.repositoryName = props.repositoryName; }
    if (props.invalidation?.networkMode !== false && props.networkMode) { extraHash.networkMode = props.networkMode; }
    if (props.invalidation?.platform !== false && props.platform) { extraHash.platform = props.platform; }
    if (props.invalidation?.outputs !== false && props.outputs) { extraHash.outputs = props.outputs; }

    // add "salt" to the hash in order to invalidate the image in the upgrade to
    // 1.21.0 which removes the AdoptedRepository resource (and will cause the
    // deletion of the ECR repository the app used).
    extraHash.version = '1.21.0';

    const staging = new AssetStaging(this, 'Staging', {
      ...props,
      follow: props.followSymlinks ?? toSymlinkFollow(props.follow),
      exclude,
      ignoreMode,
      sourcePath: dir,
      extraHash: Object.keys(extraHash).length === 0
        ? undefined
        : JSON.stringify(extraHash),
    });

    this.assetHash = staging.assetHash;
    this.sourceHash = this.assetHash;

    const stack = Stack.of(this);
    this.assetPath = staging.relativeStagedPath(stack);
    this.assetName = props.assetName;
    this.dockerBuildArgs = props.buildArgs;
    this.dockerBuildSecrets = props.buildSecrets;
    this.dockerBuildSsh = props.buildSsh;
    this.dockerBuildTarget = props.target;
    this.dockerOutputs = props.outputs;
    this.dockerCacheFrom = props.cacheFrom;
    this.dockerCacheTo = props.cacheTo;
    this.dockerCacheDisabled = props.cacheDisabled;

    const location = stack.synthesizer.addDockerImageAsset({
      directoryName: this.assetPath,
      assetName: this.assetName,
      dockerBuildArgs: this.dockerBuildArgs,
      dockerBuildSecrets: this.dockerBuildSecrets,
      dockerBuildSsh: this.dockerBuildSsh,
      dockerBuildTarget: this.dockerBuildTarget,
      dockerFile: props.file,
      sourceHash: staging.assetHash,
      networkMode: props.networkMode?.mode,
      platform: props.platform?.platform,
      dockerOutputs: this.dockerOutputs,
      dockerCacheFrom: this.dockerCacheFrom,
      dockerCacheTo: this.dockerCacheTo,
      dockerCacheDisabled: this.dockerCacheDisabled,
      displayName: props.displayName ?? props.assetName ?? Names.stackRelativeConstructPath(this),
    });

    this.repository = ecr.Repository.fromRepositoryName(this, 'Repository', location.repositoryName);
    this.imageUri = location.imageUri;
    this.imageTag = location.imageTag ?? this.assetHash;
  }