pulumi / pulumi-command

Apache License 2.0
61 stars 24 forks source link

CopyToRemote fails on update when FileArchive is a directory #494

Closed Ghoughpteighbteau closed 1 month ago

Ghoughpteighbteau commented 1 month ago

What happened?

I'm trying to upload some configuration files to my ec2 instance. However whenever I make a change pulumi fails to deploy because CopyToRemote can't update. It attempts to make a target directory when the target directory already exists and bails out

Example

    const copyConfigs = new remote.CopyToRemote(`${stack}-tp-${proxyId}-configs`, {
        connection,
        source: new pulumi.asset.FileArchive("configs"),
        remotePath: "/home/pulumi",
    }, { dependsOn: waitForCloudInit, parent: proxy });

results in:

Updating (test):
     Type                               Name                              Status                  Info
     pulumi:pulumi:Stack                tile-proxy-test                   **failed**              1 error
     └─ aws:ec2:Instance                test-tp-0
 ~      └─ command:remote:CopyToRemote  test-tp-0-configs                 **updating failed**     [diff: ~source]; 1 error

Diagnostics:
  pulumi:pulumi:Stack (tile-proxy-test):
    error: update failed

  command:remote:CopyToRemote (test-tp-0-configs):
    error: failed to create remote directory /home/pulumi/configs: sftp: "Failure" (SSH_FX_FAILURE)

config is just some sshd_configs, a docker-compose.yml file and some nginx configs.

Output of pulumi about

CLI
Version      3.124.0
Go Version   go1.22.5
Go Compiler  gc

Plugins
KIND      NAME       VERSION
resource  aws        6.41.0
resource  cloudinit  1.4.4
resource  command    1.0.0
language  nodejs     unknown
resource  tls        5.0.4

Host
OS       arch
Version  "rolling"
Arch     x86_64

This project is written in nodejs: executable='/usr/bin/node' version='v20.15.1'

Current Stack: organization/tile-proxy/test

TYPE                                                URN
pulumi:pulumi:Stack                                 urn:pulumi:test::tile-proxy::pulumi:pulumi:Stack::tile-proxy-test
ops:tile-proxy:InstanceConfig                       urn:pulumi:test::tile-proxy::ops:tile-proxy:InstanceConfig::test-tp-instance-config
ops:tile-proxy:LoadBalancer                         urn:pulumi:test::tile-proxy::ops:tile-proxy:LoadBalancer::test-tp-lb-group
pulumi:providers:aws                                urn:pulumi:test::tile-proxy::pulumi:providers:aws::default_6_41_0
pulumi:providers:tls                                urn:pulumi:test::tile-proxy::pulumi:providers:tls::default_5_0_4
aws:iam/role:Role                                   urn:pulumi:test::tile-proxy::ops:tile-proxy:InstanceConfig$aws:iam/role:Role::test-tp-role
tls:index/privateKey:PrivateKey                     urn:pulumi:test::tile-proxy::ops:tile-proxy:InstanceConfig$tls:index/privateKey:PrivateKey::test-ssh-key
aws:ec2/securityGroup:SecurityGroup                 urn:pulumi:test::tile-proxy::ops:tile-proxy:LoadBalancer$aws:ec2/securityGroup:SecurityGroup::test-tp-lb-sg
aws:lb/targetGroup:TargetGroup                      urn:pulumi:test::tile-proxy::ops:tile-proxy:LoadBalancer$aws:lb/targetGroup:TargetGroup::test-tp-lb-targets
aws:iam/instanceProfile:InstanceProfile             urn:pulumi:test::tile-proxy::ops:tile-proxy:InstanceConfig$aws:iam/instanceProfile:InstanceProfile::test-tp-instance-profile
aws:alb/loadBalancer:LoadBalancer                   urn:pulumi:test::tile-proxy::ops:tile-proxy:LoadBalancer$aws:alb/loadBalancer:LoadBalancer::test-tp-lb
aws:ec2/securityGroup:SecurityGroup                 urn:pulumi:test::tile-proxy::ops:tile-proxy:InstanceConfig$aws:ec2/securityGroup:SecurityGroup::test-tp-sg
aws:ec2/instance:Instance                           urn:pulumi:test::tile-proxy::aws:ec2/instance:Instance::test-tp-0
aws:lb/targetGroupAttachment:TargetGroupAttachment  urn:pulumi:test::tile-proxy::aws:ec2/instance:Instance$aws:lb/targetGroupAttachment:TargetGroupAttachment::test-tp-0-attachment
aws:alb/listener:Listener                           urn:pulumi:test::tile-proxy::ops:tile-proxy:LoadBalancer$aws:alb/listener:Listener::test-tp-lb-listener-ssl-redirect
aws:alb/listener:Listener                           urn:pulumi:test::tile-proxy::ops:tile-proxy:LoadBalancer$aws:alb/listener:Listener::test-tp-lb-listener
pulumi:providers:command                            urn:pulumi:test::tile-proxy::pulumi:providers:command::default_1_0_0
command:remote:Command                              urn:pulumi:test::tile-proxy::aws:ec2/instance:Instance$command:remote:Command::test-tp-0-wait-for-cloud-init
command:remote:CopyToRemote                         urn:pulumi:test::tile-proxy::aws:ec2/instance:Instance$command:remote:CopyToRemote::test-tp-0-configs

Found no pending operations associated with test

Backend
Name           obelisk
URL            s3://opsready-pulumi-infrastructure-backend
User           oehpr
Organizations
Token type     personal

Dependencies:
NAME             VERSION
@pulumi/aws      6.41.0
@pulumi/command  1.0.0
@pulumi/pulumi   3.121.0
@pulumi/tls      5.0.4
@types/node      18.19.39
typescript       5.5.2

Pulumi locates its logs in /tmp by default

Additional context

I can sorta work around this issue by making sure to move the directory first thing when I remote into the ec2 instance, but it's brittle and if something goes wrong the pulumi script can not recover.

CopyToRemote should not die when it is performing an update. It should update.

Contributing

Vote on this issue by adding a 👍 reaction. To contribute a fix for this issue, leave a comment (and link to your pull request, if you've opened one already).

mjeffryes commented 1 month ago

Thanks for reporting this @Ghoughpteighbteau; I agree it should be updating in place. We'll take a look.

thomas11 commented 1 month ago

Hi @Ghoughpteighbteau, sorry you're running into this. Can you confirm that both the local configs and the remote pulumi are directories, not files?

If yes, could you try specifying the remote path as /home/pulumi/, with a trailing slash?

Ghoughpteighbteau commented 1 month ago

yep yep!

this is my file tree

/home/oehpr/dev/lightship/devops/infrastructure/tile-proxy
├──configs
│  ├──docker-compose.yml
│  ├──nginx
│  │  ├──conf.d
│  │  │  ├──cantopotiles.conf
│  │  │  ├──healthCheck.conf
│  │  │  ├──proxy_params
│  │  │  └──usgstopotiles.conf
│  │  ├──mime.types
│  │  └──nginx.conf
│  └──opsready-sshd.conf
├──index.ts
├──package-lock.json
├──package.json
├──Pulumi.prod.yaml
├──Pulumi.test.yaml
├──Pulumi.yaml
├──tile-caching-system.drawio
└──tsconfig.json

i've updated the target to include a trailing slash

    // now for configuration files, including nginx and sshd settings
    const copyConfigs = new remote.CopyToRemote(`${stack}-tp-${proxyId}-configs`, {
        connection,
        source: new pulumi.asset.FileArchive("configs"),
        remotePath: "/home/pulumi/",
    }, { dependsOn: waitForCloudInit, parent: proxy });

and I reran pulumi up

obelisk in infrastructure/tile-proxy on  tile-caching [!] via  v20.15.1 via  test took 28s
at 09:32:21 ❯ pl up
Previewing update (test):
     Type                               Name                     Plan        Info
     pulumi:pulumi:Stack                tile-proxy-test
     └─ aws:ec2:Instance                test-tp-0
 +-     ├─ command:remote:Command       test-tp-0-apply-configs  replace     [diff: ]
 ~      └─ command:remote:CopyToRemote  test-tp-0-configs        update      [diff: ~source]

Resources:
    ~ 1 to update
    +-1 to replace
    2 changes. 15 unchanged

Do you want to perform this update? yes
Updating (test):
     Type                               Name               Status                  Info
     pulumi:pulumi:Stack                tile-proxy-test    **failed**              1 error
     └─ aws:ec2:Instance                test-tp-0
 ~      └─ command:remote:CopyToRemote  test-tp-0-configs  **updating failed**     [diff: ~source]; 1 error

Diagnostics:
  command:remote:CopyToRemote (test-tp-0-configs):
    error: failed to create remote directory /home/pulumi/configs: sftp: "Failure" (SSH_FX_FAILURE)

  pulumi:pulumi:Stack (tile-proxy-test):
    error: update failed

:shrug:

Ghoughpteighbteau commented 1 month ago

Oh, sorry you asked about the remote as well, here's that tree as it currently stands.

pulumi
└── configs
    ├── docker-compose.yml
    ├── nginx
    │   ├── conf.d
    │   │   ├── cantopotiles.conf
    │   │   ├── healthCheck.conf
    │   │   ├── proxy_params
    │   │   └── usgstopotiles.conf
    │   ├── mime.types
    │   └── nginx.conf
    └── opsready-sshd.conf