Ejemplo n.º 1
0
    def save(self, requester, new_image_name, name_confirmed):
        username = requester.get_username()
        if not username:
            return 'GIVE_UP'    # client already disconnected, give up
        # 1st step: validate new name
        existing_image = self.images.get_user_image_from_name(
                                        requester,
                                        new_image_name,
                                        expected=None)
        if self.image.name == new_image_name:
            if name_confirmed:
                pass
            else:
                # same name for the modified image.
                # this would overwrite the existing one.
                # we will let the user confirm this.
                self.images.warn_overwrite_image(requester, self.image.name)
                return 'NAME_NEEDS_CONFIRM'
        else:   # save as a different name
            if existing_image:
                requester.stderr.write('Bad name: Image already exists.\n')
                return 'NAME_NOT_OK'
        # verify name syntax
        if not validate_image_name(requester, new_image_name):
            return 'NAME_NOT_OK'
        # ok, all is fine

        # 2nd step: save the image
        image_fullname = format_image_fullname(username, new_image_name)
        # with the walt image cp command, the client sends a request to start a
        # container for receiving, then immediately starts to send a tar archive,
        # and then tries to commit the container through rpc commands.
        # we have to ensure here that the container was run and completed its job.
        while True:
            event = next(self.docker_events)
            if 'Status' not in event or 'Name' not in event:
                continue
            if event['Status'] in ('cleanup', 'died') and event['Name'] == self.container_name:
                break
        # if we modified an image in use, umount/mount it in order to make changes
        # available to nodes
        need_remount = (self.image.fullname == image_fullname) and self.image.in_use
        if need_remount:
            self.images.umount_used_image(self.image)
        print('committing %s...' % self.container_name)
        self.docker.local.commit(self.container_name, image_fullname)
        if need_remount:
            self.images.update_image_mounts()
        if self.image.fullname == image_fullname:
            # same name, we are modifying the image
            requester.stdout.write('Image %s updated.\n' % new_image_name)
            self.image.task_label = None
            return 'OK_BUT_REBOOT_NODES'
        else:
            # we are saving changes to a new image, leaving the initial one
            # unchanged
            self.images.register_image(image_fullname, True)
            requester.stdout.write('New image %s saved.\n' % new_image_name)
            self.image.task_label = None
            return 'OK_SAVED'
Ejemplo n.º 2
0
 def get_user_image_from_name(self,
                              requester,
                              image_name,
                              expected=True,
                              ready_only=True):
     username = requester.get_username()
     if not username:
         return None  # client already disconnected, give up
     found = None
     fullname = format_image_fullname(username, image_name)
     for image in self.images.values():
         if image.fullname == fullname:
             found = image
     if expected == True and found is None:
         requester.stderr.write(
             "Error: No such image '%s'. (tip: walt image show)\n" %
             image_name)
     if expected == False and found is not None:
         requester.stderr.write("Error: Image '%s' already exists.\n" %
                                image_name)
     if expected == True and found is not None:
         if ready_only and found.ready == False:
             requester.stderr.write("Error: Image '%s' is not ready.\n" %
                                    image_name)
             found = None
     return found
Ejemplo n.º 3
0
def do_rename(images, docker, image, new_name):
    new_fullname = format_image_fullname(image.user, new_name)
    # rename the docker image
    docker.local.tag(image.fullname, new_fullname)
    docker.local.rmi(image.fullname)
    # update the store
    images.rename(image.fullname, new_fullname)
Ejemplo n.º 4
0
def do_rename(images, docker, image, new_name):
    new_fullname = format_image_fullname(image.user, new_name)
    # rename the docker image
    docker.local.tag(image.fullname, new_fullname)
    docker.local.rmi(image.fullname)
    # update the store
    images.rename(image.fullname, new_fullname)
Ejemplo n.º 5
0
 def image_shell_session_save(self, requester, session, new_name, name_confirmed):
     status = session.save(requester, new_name, name_confirmed)
     if status == 'OK_BUT_REBOOT_NODES':
         image_fullname = format_image_fullname(requester.get_username(), new_name)
         self.nodes.reboot_nodes_for_image(requester, image_fullname)
         status = 'OK_SAVED'
     return status
Ejemplo n.º 6
0
 def warn_overwrite_image(self, requester, image_name):
     image_fullname = format_image_fullname(requester.get_username(), image_name)
     num_nodes = self.num_nodes_using_image(image_fullname)
     if num_nodes == 0:
         reboot_message = ''
     else:
         reboot_message = MSG_WOULD_OVERWRITE_IMAGE_REBOOTED_NODES % num_nodes
     requester.stderr.write(MSG_WOULD_OVERWRITE_IMAGE % reboot_message)
Ejemplo n.º 7
0
 def warn_overwrite_image(self, requester, image_name):
     image_fullname = format_image_fullname(requester.get_username(),
                                            image_name)
     num_nodes = self.num_nodes_using_image(image_fullname)
     if num_nodes == 0:
         reboot_message = ''
     else:
         reboot_message = MSG_WOULD_OVERWRITE_IMAGE_REBOOTED_NODES % num_nodes
     requester.stderr.write(MSG_WOULD_OVERWRITE_IMAGE % reboot_message)
Ejemplo n.º 8
0
 def image_shell_session_save(self, requester, session, new_name,
                              name_confirmed):
     status = session.save(requester, new_name, name_confirmed)
     if status == 'OK_BUT_REBOOT_NODES':
         image_fullname = format_image_fullname(requester.get_username(),
                                                new_name)
         self.nodes.reboot_nodes_for_image(requester, image_fullname)
         status = 'OK_SAVED'
     return status
Ejemplo n.º 9
0
 def task_callback(status):
     if status == 'OK_BUT_REBOOT_NODES':
         image_fullname = format_image_fullname(
             requester.get_username(), image_name)
         task_callback_2 = lambda res: task.return_result('OK')
         self.reboot_nodes_after_image_change(requester,
                                              task_callback_2,
                                              image_fullname)
     else:
         task.return_result(status)
Ejemplo n.º 10
0
 def image_shell_session_save(self, requester, cb_return, session, new_name,
                              name_confirmed):
     image_fullname = format_image_fullname(requester.get_username(),
                                            new_name)
     status = session.save(requester, new_name, name_confirmed)
     if status == 'OK_BUT_REBOOT_NODES':
         cb_reboot = lambda res: cb_return('OK_SAVED')
         self.reboot_nodes_after_image_change(requester, cb_reboot,
                                              image_fullname)
     else:
         cb_return(status)
Ejemplo n.º 11
0
 def warn_if_would_reboot_nodes(self, requester, image_name):
     if '/' in image_name:
         image_fullname = image_name
     else:
         image_fullname = format_image_fullname(requester.get_username(),
                                                image_name)
     num_nodes = self.num_nodes_using_image(image_fullname)
     if num_nodes == 0:
         return False  # no node would reboot
     requester.stderr.write(MSG_WOULD_REBOOT_NODES % num_nodes)
     return True  # yes it would reboot some nodes
Ejemplo n.º 12
0
 def get_user_image_from_name(self, requester, image_name, expected = True, ready_only = True):
     username = requester.get_username()
     if not username:
         return None    # client already disconnected, give up
     found = None
     fullname = format_image_fullname(username, image_name)
     for image in self.images.values():
         if image.fullname == fullname:
             found = image
     if expected == True and found is None:
         requester.stderr.write(
             "Error: No such image '%s'. (tip: walt image show)\n" % image_name)
     if expected == False and found is not None:
         requester.stderr.write(
             "Error: Image '%s' already exists.\n" % image_name)
     if expected == True and found is not None:
         if ready_only and found.ready == False:
             requester.stderr.write(
                 "Error: Image '%s' is not ready.\n" % image_name)
             found = None
     return found
Ejemplo n.º 13
0
def do_duplicate(images, docker, image, new_name):
    new_fullname = format_image_fullname(image.user, new_name)
    # add a tag to the docker image
    docker.local.tag(image.fullname, new_fullname)
    # update the store
    images.register_image(new_fullname, True)
Ejemplo n.º 14
0
    def save(self, requester, new_image_name, name_confirmed):
        username = requester.get_username()
        if not username:
            return 'GIVE_UP'    # client already disconnected, give up
        # 1st step: validate new name
        existing_image = self.images.get_user_image_from_name(
                                        requester,
                                        new_image_name,
                                        expected=None)
        if self.image.name == new_image_name:
            if name_confirmed:
                pass
            else:
                # same name for the modified image.
                # this would overwrite the existing one.
                # we will let the user confirm this.
                self.images.warn_overwrite_image(requester, self.image.name)
                return 'NAME_NEEDS_CONFIRM'
        else:   # save as a different name
            if existing_image:
                requester.stderr.write('Bad name: Image already exists.\n')
                return 'NAME_NOT_OK'
        # verify name syntax
        if not validate_image_name(requester, new_image_name):
            return 'NAME_NOT_OK'
        # ok, all is fine

        # 2nd step: save the image
        image_fullname = format_image_fullname(username, new_image_name)
        # with the walt image cp command, the client sends a request to start a
        # container for receiving, then immediately starts to send a tar archive,
        # and then tries to commit the container through rpc commands.
        # we have to ensure here that the container was run and completed its job.
        while True:
            event = self.docker_events.next()
            if 'status' not in event:
                continue
            if event['status'] == 'die' and \
                    self.docker.local.get_container_name(event['id']) == self.container_name:
                break
        print 'committing %s...' % self.container_name
        self.docker.local.commit(self.container_name, image_fullname,
                'Image modified using walt image [cp|shell]')
        if self.image.fullname == image_fullname:
            # same name, we are modifying the image
            # if image is mounted, umount/mount it in order to make changes
            # available to nodes
            if self.image.mounted:
                # umount
                self.images.umount_used_image(self.image)
                # re-mount
                self.images.update_image_mounts()
            # done.
            requester.stdout.write('Image %s updated.\n' % new_image_name)
            self.image.task_label = None
            return 'OK_BUT_REBOOT_NODES'
        else:
            # we are saving changes to a new image, leaving the initial one
            # unchanged
            self.images.register_image(image_fullname, True)
            requester.stdout.write('New image %s saved.\n' % new_image_name)
            self.image.task_label = None
            return 'OK_SAVED'
Ejemplo n.º 15
0
def do_duplicate(images, docker, image, new_name):
    new_fullname = format_image_fullname(image.user, new_name)
    # add a tag to the docker image
    docker.local.tag(image.fullname, new_fullname)
    # update the store
    images.register_image(new_fullname, True)