Welcome to the Inedo Forums! Check out the Forums Guide for help getting started.

If you are experiencing any issues with the forum software, please visit the Contact Form on our website and let us know!

The ConnectionString property has not been initialized



  • I waited for 25.11 to get the permission check logic in place. Now that's resolved, there appears to be a new issue, but based on the error alone, I can't be 100% sure on what it is, although I'm betting it's tied to permissions.

    The instance shows healthy, but it fails to run due to a connection string issue. See error:

    Updating certificates in /etc/ssl/certs...
    142 added, 0 removed; done.
    Running hooks in /etc/ca-certificates/update.d...
    done.
    info: Microsoft.Hosting.Lifetime[0]
          Application started. Press Ctrl+C to shut down.
    info: Microsoft.Hosting.Lifetime[0]
          Hosting environment: Production
    info: Microsoft.Hosting.Lifetime[0]
          Content root path: /usr/local/proget
    Initializing embedded database...
    fail: Microsoft.Extensions.Hosting.Internal.Host[11]
          Hosting failed to start
          System.InvalidOperationException: The ConnectionString property has not been initialized.
             at Npgsql.ThrowHelper.ThrowInvalidOperationException(String message)
             at Npgsql.NpgsqlConnection.Open(Boolean async, CancellationToken cancellationToken)
             at Npgsql.NpgsqlConnection.Open()
             at Inedo.ProGet.Data.PostgresDatabaseContext.CreateConnection() in C:\Users\builds\AppData\Local\Temp\InedoAgent\BuildMaster\192.168.44.60\Temp\_E597550\Src\src\ProGet\Data\PostgresDatabaseContext.cs:line 58
             at Inedo.ProGet.Data.VirtualDatabaseContext.PostgresContext.CreateConnection() in C:\Users\builds\AppData\Local\Temp\InedoAgent\BuildMaster\192.168.44.60\Temp\_E597550\Src\src\ProGet\Data\VirtualDatabaseContext.cs:line 49
             at Inedo.ProGet.Data.VirtualDatabaseContext.CreateConnection() in C:\Users\builds\AppData\Local\Temp\InedoAgent\BuildMaster\192.168.44.60\Temp\_E597550\Src\src\ProGet\Data\VirtualDatabaseContext.cs:line 24
             at Inedo.Data.DatabaseContext.ExecuteInternal(String storedProcName, GenericDbParameter[] parameters, DatabaseCommandReturnType returnType)
             at Inedo.Data.DatabaseContext.ExecuteNonQuery(String storedProcName, GenericDbParameter[] parameters)
             at Inedo.Data.DatabaseContext.ExecuteScalar[TResult](String storedProcName, GenericDbParameter[] parameters, Int32 outParameterIndex)
             at Inedo.ProGet.Data.DB.Context.CheckSqlServerDbo(Nullable`1 IsOwner_Indicator) in C:\Users\builds\AppData\Local\Temp\InedoAgent\BuildMaster\192.168.44.60\Temp\_E597550\Src\src\ProGet\obj\Release\net8.0\linux-x64\InedoLib.Analyzers\InedoLib.Analyzers.DatabaseContextGenerator\DB.g.cs:line 2191
             at Inedo.ProGet.Data.DB.CheckSqlServerDbo(Nullable`1 IsOwner_Indicator) in C:\Users\builds\AppData\Local\Temp\InedoAgent\BuildMaster\192.168.44.60\Temp\_E597550\Src\src\ProGet\obj\Release\net8.0\linux-x64\InedoLib.Analyzers\InedoLib.Analyzers.DatabaseContextGenerator\DB.g.cs:line 183
             at Inedo.ProGet.Data.DatabaseMan.CheckConnection(Boolean asyncWithRetryMode, CancellationToken cancellationToken) in C:\Users\builds\AppData\Local\Temp\InedoAgent\BuildMaster\192.168.44.60\Temp\_E597550\Src\src\ProGet\Data\DatabaseMan.cs:line 62
             at Inedo.ProGet.Service.ProGetService.OnStartAsync(CancellationToken cancellationToken) in C:\Users\builds\AppData\Local\Temp\InedoAgent\BuildMaster\192.168.44.60\Temp\_E597550\Src\src\ProGet\Service\ProGetService.cs:line 40
             at Inedo.ProGet.Service.ProGetService.ExecuteAsync(CancellationToken stoppingToken) in C:\Users\builds\AppData\Local\Temp\InedoAgent\BuildMaster\192.168.44.60\Temp\_E597550\Src\src\ProGet\Service\ProGetService.cs:line 26
             at Microsoft.Extensions.Hosting.Internal.Host.<StartAsync>b__15_1(IHostedService service, CancellationToken token)
             at Microsoft.Extensions.Hosting.Internal.Host.ForeachService[T](IEnumerable`1 services, CancellationToken token, Boolean concurrent, Boolean abortOnFirstException, List`1 exceptions, Func`3 operation)
    

    And config (note, I added the SSL Certificate directory as a mounted volume to avoid a different permission problem when running the certificate updates).

    spec:
      replicas: 1
      selector:
        matchLabels:
          app: proget
      template:
        metadata:
          labels:
            app: proget
        spec:
          securityContext:
            runAsUser: 1024
            runAsGroup: 100
            runAsNonRoot: false
          containers:
            - name: proget
              image: proget.inedo.com/productimages/inedo/proget:latest
              ports:
                - containerPort: 8624
                  name: http
              volumeMounts:
                - name: proget-data
                  mountPath: /var/proget/database
                - name: proget-package
                  mountPath: /var/proget/packages
                - name: proget-backup
                  mountPath: /var/proget/backups
                - name: proget-certs
                  mountPath: /etc/ssl/certs
          volumes:
            - name: proget-data
              persistentVolumeClaim:
                claimName: proget-data
            - name: proget-package
              persistentVolumeClaim:
                claimName: proget-package
            - name: proget-backup
              persistentVolumeClaim:
                claimName: proget-backup
            - name: proget-certs
              persistentVolumeClaim:
                claimName: proget-certs
    

  • inedo-engineer

    Hi @tyler_5201

    The underlying error is that there is no connection string, as you noticed.

    The connection string is stored in a file (/var/proget/database/.pgsqlconn) that should be accessible to the container. I haven't tested it, but I guess if file is missing or deleted, then I suppose you might run into these issues.

    It should be created on startup of a new container, however. So it's kind of weird. I think you'll want to "play" with it a bit, since there's clearly something going on with your permissions I'm thinking.

    Note that the connection string can also be specified as an environment variable, but I don't think that applies here since you're trying to configure the embedded datbase:
    https://docs.inedo.com/docs/installation/linux/docker-guide#supported-environment-variables

    Thanks,
    Alana



  • It's been a minute since I was able to get to this.

    So, I was able to get the database directory to work with the configuration below. The data mount is a new volume that doesn't have squashing enabled. In reviewing the container configuration, it wants the /var/proget/database to be setup with 101:0 permissions. I wasn't able to replicate this with squashing, so I created a new volume to set these permissions explicitly. The package, logs, backup, and certs mounts are all set up with squashing enabled (though I don't think I actually need the certs, but I'll have to double check if the free version supports SSL). The package directory works, I'll be able to see tomorrow if the backup works, and I think the logs work, but there's nothing logged in the UI, so I guess I'll have to wait.

    While this does work, could we not implement a UID or GID env var, or follow the securityContext, so that the pod definition controls permissions, rather than the container strictly forcing 101:0 on the database directory?

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: proget
      namespace: proget
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: proget
      template:
        metadata:
          labels:
            app: proget
        spec:
          # securityContext:
          #   runAsUser: 1024
          #   runAsGroup: 100
          #   runAsNonRoot: false
          securityContext:
            runAsUser: 0
            runAsGroup: 0
            runAsNonRoot: false
          containers:
            - name: proget
              image: proget.inedo.com/productimages/inedo/proget:latest
              ports:
                - containerPort: 8624
                  name: http
              volumeMounts:
                - name: proget-data
                  mountPath: /var/proget/database
                - name: proget-package
                  mountPath: /var/proget/packages
                - name: proget-logs
                  mountPath: /var/proget/logs
                - name: proget-backup
                  mountPath: /var/proget/backups
                - name: proget-certs
                  mountPath: /etc/ssl/certs
          volumes:
            - name: proget-data
              persistentVolumeClaim:
                claimName: proget-data
            - name: proget-package
              persistentVolumeClaim:
                claimName: proget-package
            - name: proget-logs
              persistentVolumeClaim:
                claimName: proget-logs
            - name: proget-backup
              persistentVolumeClaim:
                claimName: proget-backup
            - name: proget-certs
              persistentVolumeClaim:
                claimName: proget-certs
    
    

  • inedo-engineer

    Hi @tyler_5201 ,

    Sorry I really don't know what "squashing" or "101:0" permissions mean, so I don't really know what the issue is.... but I did read "this does work" and then saw you asked a question which I didn't quite understand 😅

    What I can say is that ProGet needs to have "full control" over the database, package, backup directories. That's not something we could reasonably change... and I don't know if you're even asking that.

    Otherwise, we also have a pretty basic Docker image configuration (Dockerfile), and obviously making changes comes with risks. Before considering those changes, we would need to really understand what kind of value/benefit comes out of this and what kind of changes are involved here.

    Thanks,
    Alana



  • Hey Alana,

    No worries. I have a similar issue with an Ansible deployment in Kubernetes with permissions. So I have a special file share now for images that don't support changing the user/group that processes run as.

    Basically, the file share exposed and consumed by the image is configured (when using squashing) to have certain permissions. And we can make docker containers or Kubernetes deployments compatible by specifying the securityContext to tell it when user & group to run the pod as, or some containers allow specifying a user ID and group ID as environment variables. This is just to control the linux permissions for folder/file access.

    Somewhere in the image setup, there's configuration forcing it to access /var/proget/database as the user "postgres" and with the group "root", and it tries changing permissions on that folder at some point. If the image supported the securityContext or the user/group ID environment variables, it would run as those specified permissions instead - but - your image would need to be able to run as those permissions, and it would probably take some work to get the image reconfigured to allow that, and to do testing.

    For now, it works. It would take some evaluation to see if your image would support changing the user/group away from the current postgres/root.


Log in to reply
 

Inedo Website HomeSupport HomeCode of ConductForums GuideDocumentation