Can't open /onedev-build/job-commands.sh (OD-329)
Khose opened 5 years ago

hi

I found an error when I run my project build and it like below :

11:33:17Running step "Build"...
11:33:18sh: 0: Can't open /onedev-build/job-commands.sh
11:33:18Skipping step "Publish Artifacts"...

and my buildspec is like below :

version: 6
jobs:
- name: Release
  steps:
  - !CheckoutStep
    name: Checkout code
    cloneCredential: !DefaultCredential {}
    condition: ALL_PREVIOUS_STEPS_WERE_SUCCESSFUL
  - !SetBuildVersionStep
    name: Set Version
    buildVersion: 1.0.0
    condition: ALL_PREVIOUS_STEPS_WERE_SUCCESSFUL
  - !CommandStep
    name: Build
    image: ubuntu:20.04
    commands:
    - tar -zcmf oneconf.tar.gz .onedev-buildspec.yml 
    condition: ALL_PREVIOUS_STEPS_WERE_SUCCESSFUL
  - !PublishArtifactStep
    name: Publish Artifacts
    artifacts: '*.tar.gz'
    condition: ALL_PREVIOUS_STEPS_WERE_SUCCESSFUL
  retryCondition: never
  maxRetries: 3
  retryDelay: 30
  cpuRequirement: 250m
  memoryRequirement: 128m
  timeout: 3600
  • Robin Shen commented 5 years ago

    It works at my side. I'd like to know:

    1. Your OS
    2. How you are running OneDev (docker mode, bare metal, k8s etc)
    3. What job executor is being used
    4. Is there any errors in server log?
  • Khose commented 5 years ago

    hi

    1. Your OS

    Ubuntu 20.04

    1. How you are running OneDev (docker mode, bare metal, k8s etc)

    I have made an custom docker image and my dockerfile is like below

    
    FROM ubuntu:20.04
    
    ENV BUILD_VERSION=1563
    ENV ONEDEV_VERSION=4.5.0
    
    ENV DATABASE_INSTANCE=internal
    ENV DATABASE_HOST=database
    ENV DATABASE_USER=postgres
    ENV DATABASE_PASSWORD=postgres
    
    RUN apt-get update && apt-get install -y --fix-missing \
        bash \
        curl \
        docker.io \
        git \
        openjdk-8-jre-headless \
        s6 \
        wget;
    
    WORKDIR /opt
    
    RUN wget https://code.onedev.io/downloads/projects/onedev-server/builds/${BUILD_VERSION}/artifacts/onedev-${ONEDEV_VERSION}.zip && \
        unzip onedev-${ONEDEV_VERSION}.zip && \
        mv onedev-${ONEDEV_VERSION} onedev && \
        mv onedev/site/avatars onedev/site/avatars-defaults && \
        rm -rf onedev-${ONEDEV_VERSION}.zip;
    
    WORKDIR /opt/onedev
    
    COPY docker docker
    
    RUN chmod +x docker/s6/onedev/run;
    RUN mv site/avatars site/avatars-defaults;
    
    CMD ["/bin/s6-svscan", "/opt/onedev/docker/s6/"]
    

    the s6 run file is like below:

    #!/bin/bash
    
    ONEDEV_PATH=/opt/onedev
    ONEDEV_HIBERNATE=${ONEDEV_PATH}/conf/hibernate.properties
    
    ONEDEV_DATABASE_INSTANCE=${DATABASE_INSTANCE}
    ONEDEV_DATABASE_HOST=${DATABASE_HOST}
    ONEDEV_DATABASE_USER=${DATABASE_USER}
    ONEDEV_DATABASE_PASSWORD=${DATABASE_PASSWORD}
    
    if test -f ${ONEDEV_PATH}/.inited; then
        cd ${ONEDEV_PATH}/bin;
        ./server.sh console;
        exit 0;
    fi
    
    #
    # Setup hibernate database configuration.
    #
    if [[ "${ONEDEV_DATABASE_INSTANCE}" != "internal" ]]; then
        while read line
        do
            if [[ ${line:0:1} == '#' ]]; then
                continue;
            fi
    
            line_key=${line%=*};
    
            if [[ "${line_key}" == hibernate.dialect ]]; then
                sed -i "s/${line}/#${line}/g" ${ONEDEV_HIBERNATE};
            elif [[ "${line_key}" == hibernate.connection.driver_class ]]; then
                sed -i "s/${line}/#${line}/g" ${ONEDEV_HIBERNATE};
            elif [[ "${line_key}" == hibernate.connection.url ]]; then
                sed -i "s/${line}/#${line}/g" ${ONEDEV_HIBERNATE};
            elif [[ "${line_key}" == hibernate.connection.username ]]; then
                sed -i "s/${line}/#${line}/g" ${ONEDEV_HIBERNATE};
            elif [[ "${line_key}" == hibernate.connection.password ]]; then
                sed -i "s/${line}/#${line}/g" ${ONEDEV_HIBERNATE};
            fi
        done < ${ONEDEV_HIBERNATE};
    fi
    
    if [[ "${ONEDEV_DATABASE_INSTANCE}" == "postgresql" ]]; then
        wget https://jdbc.postgresql.org/download/postgresql-42.2.21.jar;
        mv postgresql-42.2.21.jar ${ONEDEV_PATH}/site/lib/;
    
        echo "hibernate.dialect=io.onedev.server.persistence.PostgreSQLDialect" >> ${ONEDEV_HIBERNATE};
        echo "hibernate.connection.driver_class=org.postgresql.Driver" >> ${ONEDEV_HIBERNATE};
        echo "hibernate.connection.url=jdbc:postgresql://${ONEDEV_DATABASE_HOST}:5432/onedev" >> ${ONEDEV_HIBERNATE};
        echo "hibernate.connection.username=${ONEDEV_DATABASE_USER}" >> ${ONEDEV_HIBERNATE};
        echo "hibernate.connection.password=${ONEDEV_DATABASE_PASSWORD}" >> ${ONEDEV_HIBERNATE};
    elif  [[ "${ONEDEV_DATABASE_INSTANCE}" == "mysql" ]]; then
        wget https://cdn.mysql.com//Downloads/Connector-J/mysql-connector-java_8.0.25-1ubuntu20.04_all.deb;
        mv mysql-connector-java_8.0.25-1ubuntu20.04_all.deb ${ONEDEV_PATH}/site/lib/mysql-connector-java_8.0.25-1ubuntu20.04_all.deb;
        dpkg -i ${ONEDEV_PATH}/site/lib/mysql-connector-java_8.0.25-1ubuntu20.04_all.deb;
    
        echo "hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect" >> ${ONEDEV_HIBERNATE};
        echo "hibernate.connection.driver_class=com.mysql.cj.jdbc.Driver" >> ${ONEDEV_HIBERNATE};
        echo "hibernate.connection.url=jdbc:mysql://${ONEDEV_DATABASE_HOST}:3306/onedev?serverTimezone=UTC&allowPublicKeyRetrieval=true&useSSL=false&disableMariaDbDriver=true" >> ${ONEDEV_HIBERNATE};
        echo "hibernate.connection.username=${ONEDEV_DATABASE_USER}" >> ${ONEDEV_HIBERNATE};
        echo "hibernate.connection.password=${ONEDEV_DATABASE_PASSWORD}" >> ${ONEDEV_HIBERNATE};
    fi
    
    #
    # Move default avatars to mapping path.
    #
    mkdir -p ${ONEDEV_PATH}/site/avatars;
    
    cp -f ${ONEDEV_PATH}/site/avatars-defaults/onedev.png ${ONEDEV_PATH}/site/avatars/onedev.png;
    cp -f ${ONEDEV_PATH}/site/avatars-defaults/project.png ${ONEDEV_PATH}/site/avatars/project.png;
    cp -f ${ONEDEV_PATH}/site/avatars-defaults/user.png ${ONEDEV_PATH}/site/avatars/user.png;
    
    #
    # Create inited flag file.
    #
    touch ${ONEDEV_PATH}/.inited;
    
    #
    # Run onedev.
    #
    cd ${ONEDEV_PATH}/bin;
    ./server.sh console;
    
    

    cmd:

    docker run -p 6610:6610 -e DATABASE_INSTANCE=postgresql -e DATABASE_HOST=database -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres --link database -v /var/run/docker.sock:/var/run/docker.sock --name onedev onedev:4.5.0
    
    1. What job executor is being used

    auto executor.

    1. Is there any errors in server log?

    server log is like below:

    root@608dbae4536a:/opt/onedev/logs# cat server.log 
    2021-06-14 03:24:53,090 INFO  [WrapperSimpleAppMain] i.o.c.launcher.bootstrap.Bootstrap Launching application from '/opt/onedev'...
    2021-06-14 03:24:53,208 INFO  [WrapperSimpleAppMain] i.o.c.launcher.loader.AppLoader Initializing dependency injection container...
    2021-06-14 03:24:54,157 INFO  [WrapperSimpleAppMain] i.o.c.launcher.loader.AppLoader Starting plugin manager...
    2021-06-14 03:24:58,094 INFO  [WrapperSimpleAppMain] i.o.s.e.impl.DefaultBuildManager Caching build info...
    2021-06-14 03:24:58,109 INFO  [WrapperSimpleAppMain] i.o.s.e.i.DefaultBuildParamManager Caching build param info...
    2021-06-14 03:24:58,132 INFO  [WrapperSimpleAppMain] i.o.s.e.impl.DefaultIssueManager Caching issue info...
    2021-06-14 03:24:58,188 INFO  [WrapperSimpleAppMain] i.o.s.e.impl.DefaultProjectManager Checking projects...
    2021-06-14 03:24:58,190 INFO  [WrapperSimpleAppMain] i.o.s.e.impl.DefaultProjectManager Initializing git repository in '/opt/onedev/site/projects/1/git'...
    2021-06-14 03:24:58,329 INFO  [WrapperSimpleAppMain] i.o.s.e.impl.DefaultProjectManager Initializing git repository in '/opt/onedev/site/projects/2/git'...
    2021-06-14 03:24:58,334 INFO  [WrapperSimpleAppMain] i.o.s.e.impl.DefaultProjectManager Initializing git repository in '/opt/onedev/site/projects/3/git'...
    2021-06-14 03:24:58,478 INFO  [WrapperSimpleAppMain] i.o.s.e.i.DefaultBuildMetricManager Caching build metric info...
    2021-06-14 03:24:58,498 INFO  [WrapperSimpleAppMain] io.onedev.server.OneDev Server is ready at http://192.168.18.129:6610.
    2021-06-14 03:33:18,582 INFO  [pool-6-thread-4] i.o.s.plugin.docker.DockerExecutor Unable to find image 'busybox:latest' locally
    2021-06-14 03:33:21,611 INFO  [pool-6-thread-4] i.o.s.plugin.docker.DockerExecutor latest: Pulling from library/busybox
    2021-06-14 03:33:22,724 INFO  [pool-6-thread-4] i.o.s.plugin.docker.DockerExecutor b71f96345d44: Pulling fs layer
    2021-06-14 03:33:25,080 INFO  [pool-6-thread-4] i.o.s.plugin.docker.DockerExecutor b71f96345d44: Download complete
    2021-06-14 03:33:25,146 INFO  [pool-6-thread-4] i.o.s.plugin.docker.DockerExecutor b71f96345d44: Pull complete
    2021-06-14 03:33:25,150 INFO  [pool-6-thread-4] i.o.s.plugin.docker.DockerExecutor Digest: sha256:930490f97e5b921535c153e0e7110d251134cc4b72bbb8133c6a5065cc68580d
    2021-06-14 03:33:25,152 INFO  [pool-6-thread-4] i.o.s.plugin.docker.DockerExecutor Status: Downloaded newer image for busybox:latest
    
  • Khose commented 5 years ago

    HI

    I have test in an ubuntu environment ( not docker) and it work fine, so could you tell me how the /onedev-build/job-commands.sh work?

  • Robin Shen commented 5 years ago

    Please test if it works by running the default docker script:

    docker run -it --rm -v /var/run/docker.sock:/var/run/docker.sock -v $(pwd)/onedev:/opt/onedev -p 6610:6610 -p 6611:6611 1dev/server:4.5.0
    

    The job-commands.sh wraps the commands to be called within docker. For details, please check:

    https://code.onedev.io/projects/onedev-server/blob/main/server-plugin/server-plugin-executor-docker/src/main/java/io/onedev/server/plugin/docker/DockerExecutor.java?position=source-89.14-89.28-1

    Due to limited time, I can only support official docker images.

  • Khose commented 5 years ago

    Hi

    Thank you for your reply.

    I think it seems the mapping issue for docker, could you tell me how the onedev container share the job-commands.sh to the job contanier ?

    I see below in code

    File scriptFile = new File(hostBuildHome, "job-commands.sh");
    

    and the hostBuildHome is here:

    File hostBuildHome = FileUtils.createTempDir("onedev-build");
    

    and the path will be mapping in

    docker.addArgs("-v", getOuterPath(hostBuildHome.getAbsolutePath()) + ":" + containerBuildHome);
    

    So could you tell me the real path string and the -v argument real string ? Or which directory in ondev should to be mapping to the host(using -v) for onedev-build?

  • Robin Shen commented 5 years ago

    To avoid conflicting, each build should have its own hostBuildHome, this is the reason why hostBuildHome is generated via createTempDir.

  • Khose commented 5 years ago

    Hi

    Thank you, I found below code:

    	private String getOuterPath(String hostPath) {
    		String hostInstallPath = Bootstrap.installDir.getAbsolutePath();
    		Preconditions.checkState(hostPath.startsWith(hostInstallPath + "/")
    				|| hostPath.startsWith(hostInstallPath + "\\"));
    		if (outerInstallPath == null) {
    			if (Bootstrap.isInDocker()) {
    				AtomicReference<String> installDirRef = new AtomicReference<>(null);
    				Commandline docker = newDocker();
    				String inspectFormat = String.format(
    						"{{range .Mounts}} {{if eq .Destination \"%s\"}} {{.Source}} {{end}} {{end}}", 
    						hostInstallPath);
    				docker.addArgs("inspect", "-f", inspectFormat, System.getenv("HOSTNAME"));						
    				docker.execute(new LineConsumer() {
    		
    					@Override
    					public void consume(String line) {
    						installDirRef.set(line.trim());
    					}
    					
    				}, new LineConsumer() {
    		
    					@Override
    					public void consume(String line) {
    						logger.error(line);
    					}
    					
    				}).checkReturnCode();
    				
    				outerInstallPath = Preconditions.checkNotNull(installDirRef.get());
    			} else {
    				outerInstallPath = hostInstallPath;
    			}
    		}
    		return outerInstallPath + hostPath.substring(hostInstallPath.length());
    	}
    

    It seems that the onedev install path should be mapped in docker command, right?

  • Robin Shen commented 5 years ago

    This maps the host path seen by OneDev process to the actual path in your OS. Since docker sock is mounted into OneDev from OS and it can only recognize OS paths when mount paths to launch build container.

  • Robin Shen changed state to 'Closed' 5 years ago
    Previous Value Current Value
    Open
    Closed
  • Khose commented 5 years ago

    Hi

    One more question, could you tell me where and how the Bootstrap.installDir get its value?

issue 1/1
Type
Bug
Priority
Normal
Assignee
Affected Versions
Not Found
Issue Votes (0)
Watchers (3)
Reference
OD-329
Please wait...
Connection lost or session expired, reload to recover
Page is in error, reload to recover